【问题标题】:MVC through C# / WPF: how to notify view?MVC 通过 C#/WPF:如何通知视图?
【发布时间】:2011-05-14 20:27:11
【问题描述】:

我正在 C# 中使用 WPF 接口对 MVC 模式进行非常简单的实现。

我有一个保持状态的模型。我希望能够在状态发生任何变化时通知模型视图,以便视图可以相应地更新自身。

在 WPF 中执行此操作的最简单的最佳实践是什么?我知道有诸如 PropertyChanged 事件之类的东西,这是我正在寻找的东西还是对我的情况来说太具体了?

谢谢!

【问题讨论】:

  • 您可以考虑在这里阅读我的文章:reedcopsey.com/series/windows-forms-to-mvvm 他们从 WPF 的角度介绍了如何考虑这一点,包括如何以及为什么要实现 INotifyPropertyChanged。 MVVM 只是一种 WPF 友好的架构模式,您可以将其用作 MVC 的替代方案。

标签: c# wpf model-view-controller


【解决方案1】:

是的。实现接口 INotifyPropertyChanged。

一个例子:

MainWindow.xaml

<Window x:Class="INotifyChangedDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Label Content="{Binding HitCount}"></Label>
    <Button Grid.Row="1" Click="Button_Click">
        Hit
    </Button>
</Grid>


MainWindow.xaml.cs

namespace INotifyChangedDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private MainViewModel _viewModel = new MainViewModel();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = _viewModel;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _viewModel.HitCount = _viewModel.HitCount + 1;
        }
    }
}

MainViewModel.cs

namespace INotifyChangedDemo
{
    public class MainViewModel : INotifyPropertyChanged
    {
        private int _hitCount;
        public int HitCount
        {
            get
            {
                return _hitCount;
            }
            set
            {
                if (_hitCount == value)
                    return;

                _hitCount = value;
                // Notify the listeners that Time property has been changed
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("HitCount"));
                }

            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

为了更好地实现 INotifyChangedProperty,请参考这个帖子:Automatically INotifyPropertyChanged

如果您想了解更多有关 MVVM 模式的信息,请参阅此处:http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

【讨论】:

  • 感谢您提供的好例子!如果您使用将 UI 元素绑定到某个属性的 WPF 绑定,这似乎很有效。如果您不使用绑定并且不特别关心单个属性的变化,而是关心模型状态的任何变化,会发生什么。此外,当发生更改时,我更感兴趣的是能够在 UI 上执行特定操作(例如弹出消息框),而不是更新屏幕上元素的值。这有可能吗?
  • @glitch:主窗口可以监听视图模型的PropertyChanged事件,这样当PropertyChanged被触发时,主窗口可以打开一个对话框。这是最简单的解决方案,您需要连接每个视图中的事件。
  • 我解决消息框问题的方法是让用户控件像消息框一样呈现,其中它们的可见性绑定到视图模型中的属性。无论如何,必须解决控件的覆盖问题。
【解决方案2】:

如果您的视图绑定到模型中声明的属性,并且您的属性在更改时引发 PropertyChanged 事件,那么您的视图将自动更新为新值。例如,您的视图可能会声明以下内容:

<TextBlock Text="{Binding Name}" />

在您的模型中,您将拥有:

string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
        RaisePropertyChanged("Name");
    }
}

这假设您正在使用一些提供 RaisePropertyChanged 方法的框架/助手。我从 Galasoft MVVM 框架中举了这个例子,但我假设在 MVC 中应用完全相同的原理。

希望这会有所帮助。

【讨论】:

  • 感谢您提供的好例子!如果您使用将 UI 元素绑定到某个属性的 WPF 绑定,这似乎很有效。如果您不使用绑定并且不特别关心单个属性的变化,而是关心模型状态的任何变化,会发生什么。此外,当发生更改时,我更感兴趣的是能够在 UI 上执行特定操作(例如弹出消息框),而不仅仅是更新屏幕上元素的值。这有可能吗?
猜你喜欢
  • 2012-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 2013-09-21
相关资源
最近更新 更多