gpt4 book ai didi

c# - RaisePropertyChanged 不适用于集合

转载 作者:太空宇宙 更新时间:2023-11-03 21:53:36 26 4
gpt4 key购买 nike

我正在使用 mvvm-light,我注意到有关 RaisePropertyChanged 的​​这种奇怪行为。

xaml:

<ListBox ItemsSource="{Binding Collection}"/>
<TextBlock Text="{Binding Text}"/>

可观察类:

public class A : ObservableObject
{
private string _b;
public string B
{
get { return this._b; }
set
{
this._b = value;
this.RaisePropertyChanged("B");
}
}
}

虚拟机:

public MainViewModel(IDataService dataService) { this.Collection = new List<A>(...); }

public RelayCommand Command1
{
get
{
return this._command1 ?? (this._command1= new RelayCommand(() =>
{
this.Collection.Add(new A());
this.Collection[2].B = "updated";
this.RaisePropertyChanged("Collection");
this.RaisePropertyChanged("Text");
}));
}
}

public RelayCommand Command2
{
get { return this._command2?? (this._command2 = new RelayCommand(() => { this.Text++; })); }
}

public List<A> Collection { get; set; }
public int Text { get; set; }

因此,RaisePropertyChanged("Collection") 不会更新绑定(bind),而 RaisePropertyChanged("Text") 会更新。我可以通过多次执行 Command2 和之后的 Command1 来看到它。如果 Collection 是一个 ObservableCollection,那么新元素会显示在 View 中,但更新的项目不会,这意味着 ObservableCollection 的内部机制起作用,但 RaisePropertyChanged 不起作用。

最佳答案

首先说明问题:

在 Windows Phone 上,当为依赖属性设置值时,框架会在内部检查新值是否与旧值不同(可能出于优化目的)。当您引发 PropertyChanged 事件或直接将您的集合重新分配给 ItemsSource 属性时(它只是 ItemsControl.ItemsSourceProperty 依赖项的包装器属性),框架检测到该值实际上没有改变并且不更新属性。因此,ListBox 永远不会收到您的更改通知,也不会更新。

ObservableCollection 之所以有效,是因为它使用了一种完全不同的机制:ListBox 直接订阅您集合的 CollectionChanged 事件,因此是'受依赖属性限制的阻碍。


现在,如何绕过这个限制?我能想到的唯一解决方法是:

  1. 使用 ObservableCollection 而不是 List
  2. null 分配给 ListBoxItemsSource 属性,然后重新分配您的集合
  3. ListBox 绑定(bind)到每次调用时都会返回不同集合的属性:

    public List<A> CollectionCopy
    {
    get
    {
    return this.Collection.ToList();
    }
    }

关于c# - RaisePropertyChanged 不适用于集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13332075/

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