c# – 当静态属性值发生变化时,不会收到视图通知
我有一个ViewModelBase类,如下所示:
public class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this,new PropertyChangedEventArgs(propertyName)); } } public static event PropertyChangedEventHandler GlobalPropertyChanged = delegate { }; public static void OnGlobalPropertyChanged(string propertyName,Type className) { GlobalPropertyChanged(className,new PropertyChangedEventArgs(propertyName)); } } 现在,我有另一个名为GroupViewModel的viewModel,它继承了ViewModelBase: public class GroupViewModel : ViewModelBase { public GroupsViewModel() { CurrentGroup = new Group(); } private static Group _currentGroup; public static Group CurrentGroup { get { return _currentGroup; } set { _currentGroup = value; OnGlobalPropertyChanged("CurrentGroup",typeof(Group)); } } } 现在在Groups.xaml页面: <Grid DataContext="{Binding CurrentGroup}"> ..... ..... <TextBlock Text="{Binding GroupName,TargetNullValue=''}" /> ..... ..... </Grid> 我有另一个名为MainWindowViewModel的ViewModel,我尝试将CurrentGroup保存到数据库,如下面的代码,然后我设置CurrentGroup = new Group();但在Group.xaml中,TextBox的文本未被清除: Group group = GroupViewModel.CurrentGroup; db.Groups.Add(group); db.SaveChanges(); GroupViewModel.CurrentGroup = new Group(); 更新: 如果我在GroupsViewModel中使用以下代码,则输出符合预期.我的意思是静态属性更改时更新View. public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged = delegate { }; private static void NotifyStaticPropertyChanged(string propertyName) { StaticPropertyChanged(null,new PropertyChangedEventArgs(propertyName)); } 如果我在ViewModelBase中使用相同的代码(请注意,GroupsViewModel继承ViewModelBase),则静态属性的值更改时不会更新View.此外,我在这种情况下将NotifyStaticPropertyChanged标记为公共,以避免编译时错误,如有关保护级别的错误. 解决方法
对于Static PropertyChanged,您必须在类中创建如下的通用静态事件:
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged = delegate { }; private static void NotifyStaticPropertyChanged(string propertyName) { StaticPropertyChanged(null,new PropertyChangedEventArgs(propertyName)); } 你必须像你用来做实例属性一样调用: NotifyStaticPropertyChanged("CurrentGroup"); 但主要的问题是在XAML中你有约束力 –
所以,它会是这样的: <Grid DataContext="{Binding Path=(local:GroupViewModel.CurrentGroup)}"> ..... ..... <TextBlock Text="{Binding GroupName,TargetNullValue=''}" /> ..... ..... </Grid> 来源INPC for static properties. UPDATE
StaticPropertyChangedEvent必须位于属性所在的同一个类中.对于实例属性,它不会像传统的INotifyPropertyChanged那样工作. 我没有任何MSDN文档断言但我通过稍微调整事件代码来验证它是否XAML从XAML挂钩到StaticPropertyChangedEvent. 将事件代码替换为此,您可以看到自己: private static event EventHandler<PropertyChangedEventArgs> staticPC = delegate { }; public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged { add { staticPC += value; } remove { staticPC -= value; } } protected static void NotifyStaticPropertyChanged(string propertyName) { staticPC(null,new PropertyChangedEventArgs(propertyName)); } 在add上添加一个断点,你会看到它会被点击,因为WPF绑定引擎在内部挂钩它以监听静态属性更改事件. 但是只要将其移动到基类ViewModelBase,断点就不会被击中.因为,WPF没有挂钩,所以任何属性的更改都不会明显更新UI. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |