静态属性值更改时,视图未收到通知 [英] View is not getting notified when value of static Property Changes

查看:30
本文介绍了静态属性值更改时,视图未收到通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ViewModelBase类,如下:

I have a ViewModelBase class as follows:

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:

Now, I have another viewModel called GroupViewModel which inherits 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页面中:

Now in Groups.xaml Page :

<Grid DataContext="{Binding CurrentGroup}">
    .....
    .....
    <TextBlock Text="{Binding GroupName, TargetNullValue=''}" />
    .....
    .....
</Grid>

我还有一个名为MainWindowViewModel的ViewModel,我尝试将CurrentGroup像下面的代码一样保存到数据库,然后设置 CurrentGroup = new Group(); ,但是在Group.xaml中,不会清除TextBox的文本:

I have another ViewModel called MainWindowViewModel, I try to save CurrentGroup to Database like below code and then I set CurrentGroup = new Group(); but in Group.xaml the text of TextBox is not cleared :

Group group = GroupViewModel.CurrentGroup;
db.Groups.Add(group);
db.SaveChanges();
GroupViewModel.CurrentGroup = new Group();

更新:

如果我在GroupsViewModel中使用以下代码,则输出是预期的.我的意思是,静态"属性更改时,视图也会更新.

If I use the below code in GroupsViewModel, the output is as expected. I mean View is updated when Static property changes.

public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged
         = delegate { };
private static void NotifyStaticPropertyChanged(string propertyName)
{
   StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}

如果我在ViewModelBase中使用相同的代码(请注意GroupsViewModel继承了ViewModelBase),则当静态属性的值更改时,View不会更新.另外,在这种情况下,我已将NotifyStaticPropertyChanged标记为公共,以避免诸如保护级别错误之类的编译时错误.

If I use that same code in ViewModelBase (Please note that GroupsViewModel inherits ViewModelBase) then View is not updated when value of static property changes. Also I have marked the NotifyStaticPropertyChanged as public in this case to avoid the compile time errors like errors about protection level.

推荐答案

对于 Static PropertyChanged ,您必须在类中创建这样的通用静态事件:

For Static PropertyChanged you have to create generic static event like this in your class:

public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged
         = delegate { };
private static void NotifyStaticPropertyChanged(string propertyName)
{
   StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}

,您必须像执行实例属性一样调用:

and you have to call like you use to do instance properties:

NotifyStaticPropertyChanged("CurrentGroup");

但是主要要注意的是绑定的XAML-

But main catch is in XAML where you are binding -

您将在名称空间,类和属性周围使用括号因为WPF绑定引擎将路径解析为ClassName.PropertyName而不是PropertyName.PropertyName.

You'll use parentheses around the namespace, class, and property because WPF binding engine parse the path as ClassName.PropertyName rather than PropertyName.PropertyName.

因此,它将是这样的:

<Grid DataContext="{Binding Path=(local:GroupViewModel.CurrentGroup)}">
  .....
  .....
  <TextBlock Text="{Binding GroupName, TargetNullValue=''}" />
  .....
  .....
</Grid>

此处来源INPC具有静态属性.

更新

如果我在ViewModelBase中使用相同的代码(请注意,GroupsViewModel继承ViewModelBase),则在以下情况下不更新View静态属性更改的值.

If I use that same code in ViewModelBase (Please note that GroupsViewModel inherits ViewModelBase) then View is not updated when value of static property changes.

StaticPropertyChangedEvent 必须与属性所在的类属于同一类.对于实例属性,它不会像传统的 INotifyPropertyChanged 一样工作.

StaticPropertyChangedEvent have to be in same class where property resides. It won't work like traditional INotifyPropertyChanged for instance properties.

我没有任何MSDN文档可以断言,但是我通过稍微调整事件代码以查看XAML是否从XAML挂接到 StaticPropertyChangedEvent 上进行了验证.

I don't have any MSDN documentation to assert that but I verified it by tweaking event code a bit to see if XAML is hooking onto StaticPropertyChangedEvent from XAML.

将事件代码替换为此,您将看到自己:

Replace event code to this and you can see yourself:

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绑定引擎在内部挂钩到它以侦听静态属性更改的事件,因此您将看到它被命中.

Put a breakpoint on add and you will see it will get hit since WPF binding engine internally hook to it to listen to static property changed events.

但是,只要将其移至基类ViewModelBase,就不会遇到断点.自此以来,WPF并未对其进行任何关联,因此对属性的任何更改都不会明显更新UI.

But as soon as you move that to base class ViewModelBase, breakpoint won't get hit. Since, WPF haven't hook to it so any changes in property won't update UI obviously.

这篇关于静态属性值更改时,视图未收到通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆