gpt4 book ai didi

c# - 当静态属性值更改时, View 未收到通知

转载 作者:太空狗 更新时间:2023-10-30 00:10:32 27 4
gpt4 key购买 nike

我有一个 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");

但主要问题在于您绑定(bind)的 XAML -

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 for static properties .


更新

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 那样工作。

我没有任何 MSDN 文档来断言这一点,但我通过稍微调整事件代码来验证它,以查看 XAML 是否 Hook 到来自 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 绑定(bind)引擎在内部 Hook 它以监听静态属性更改事件。

但是一旦您将其移至基类 ViewModelBase,断点就不会命中。因为,WPF 没有 Hook 它,所以属性的任何更改都不会明显地更新 UI。

关于c# - 当静态属性值更改时, View 未收到通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22346212/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com