WPF INotifyPropertyChanged是如何工作的?

27

这是一个典型的INotifyPropertyChanged实现,用于在WPF/C#中使用Binding。

namespace notifications.ViewModel
{
    class MainViewModel : INotifyPropertyChanged
    {
        public const string NamePropertyName = "CheckBoxState";
        private bool _checkboxstate = true;

        public bool CheckBoxState
        {
            get { return _checkboxstate; }
            set
            {
                if (_checkboxstate == value) return;
                _checkboxstate = value;
                RaisePropertyChanged(NamePropertyName);
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

我还有一段 XAML 代码,其中绑定了CheckBoxStateenter image description here

<Grid>
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <CheckBox Content="Click Me" IsChecked="{Binding Path=CheckBoxState, Mode=TwoWay}" />
        <TextBlock Text="{Binding Path=CheckBoxState, Mode=TwoWay}" />
    </StackPanel>
</Grid>

这是用于将DataContext与模型关联的MainWindow.xaml.cs文件。

public partial class MainWindow : Window
{
    notifications.ViewModel.MainViewModel model = new notifications.ViewModel.MainViewModel();

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = model;
    }
}
当用户设置复选框时,我认为会发生以下操作: IsChecked 变为 true,并使用 "{Binding Path=CheckBoxState, Mode=TwoWay}"CheckBoxState 属性变为 true,调用 RaisePropertyChanged() 和相应的 PropertyChanged()。由于此函数的参数是 CheckBoxState,因此每个 Path 为 CheckBoxState 的 Binding 都会被通知以更新自身。
  • 这个调用是如何激活 <TextBlock Text="{Binding Path=CheckBoxState, Mode=TwoWay}" /> 的?C# 是怎么做到这一点的?
  • if (PropertyChanged != null) 为什么是必要的?谁将 PropertyChanged 设置为什么值?
  • Mode=TwoWay 的含义似乎不仅可以表示更改,还可以在其他绑定元素中具有相同名称的 Binding 更改时更新内容,那 OneWay 模式呢?我们可以将 Binding 设置为仅源或仅目标吗?
1个回答

19
这段代码创建了一个Binding对象,将TextBlock的Text属性与ViewModel属性进行了链接。同时,它还添加了一个事件处理程序到ViewModel的PropertyChanged事件中,以便在ViewModel触发PropertyChanged事件(带有正确的属性)时更新文本值。
如果PropertyChanged事件为null,则触发它会导致NullReferenceException的异常抛出。
绑定模式包括: - TwoWay: 当ViewModel属性更改时,将绑定值更改,反之亦然 - OneWay: 仅当ViewModel属性更改时才更改绑定值 - OneWayToSource: 仅当绑定值更改时才更改ViewModel属性值 - OneTime: 在应用程序创建或数据上下文更改时,将绑定值设置为ViewModel属性的值。
可以在此处了解更多信息:http://msdn.microsoft.com/en-us/library/system.windows.data.bindingmode.aspx

1
我相信还有一种OneTime绑定模式,它只在控件加载时更新一次。 - Yuf
@Yuf:好发现:我会把它加到我的答案中。 - Jackson Pope
2
这行代码是如何工作的 - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - RSB
你所做的只是评论他的问题,那里没有任何真正的解释。 - AymenDaoudi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接