c# - ObervableCollection、CollectionChanged 和 PropertyChanged
问题描述
几天来,我一直在试图弄清楚如何解决我的问题。
我有一个类似的数据结构(我使用 PropertyChanged.Fody 库):
public class Item1 : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int Somma { get => this.Lista.Sum(o => o.Valore);}
public ObservableCollection<Item2> Lista {get; set;}
/*Other fields*/
}
public class Item2 : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int Valore {get; set;}
/*Other fields*/
}
在我的视图中,我有两个类似的 ListView(lista 是 Item1 的 ObservableCollection):
<mr:ListView x:Name="listView1" ItemsSource="{Binding lista}" SelectedItem="{Binding listView1Selected, Mode=TwoWay}">
<mr:ListView.ItemTemplate>
<DataTemplate>
<mr:ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Somma}" TextColor="Black" />
</StackLayout>
</mr:ViewCell>
</DataTemplate>
</mr:ListView.ItemTemplate>
</mr:ListView>
<mr:ListView x:Name="listView2" ItemsSource="{Binding listView1Selected.Lista}" SelectedItem="{Binding listView2Selected, Mode=TwoWay}">
<mr:ListView.ItemTemplate>
<DataTemplate>
<mr:ViewCell>
<StackLayout Orientation="Vertical" >
<Label Text="{Binding Valore}" TextColor="Black" />
</StackLayout>
</mr:ViewCell>
</DataTemplate>
</mr:ListView.ItemTemplate>
</mr:ListView>
当我在 ViewModel.cs 中调用更改某些 Item2 的字段 Valore 的值时,我希望重新计算 Item1 的总和并自动绑定。我尝试将 ObservableCollection 替换为如下类:
public class ItemsChangeObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged
{
public ItemsChangeObservableCollection() : base()
{
}
public ItemsChangeObservableCollection(IEnumerable<T> list) : base(list)
{
RegisterPropertyChanged(list.ToList());
}
public ItemsChangeObservableCollection(List<T> list): base(list)
{
RegisterPropertyChanged(list);
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
RegisterPropertyChanged(e.NewItems);
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
UnRegisterPropertyChanged(e.OldItems);
}
else if (e.Action == NotifyCollectionChangedAction.Replace)
{
UnRegisterPropertyChanged(e.OldItems);
RegisterPropertyChanged(e.NewItems);
}
base.OnCollectionChanged(e);
}
protected override void ClearItems()
{
UnRegisterPropertyChanged(this);
base.ClearItems();
}
private void RegisterPropertyChanged(IList items)
{
foreach (INotifyPropertyChanged item in items)
{
if (item != null)
{
item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void UnRegisterPropertyChanged(IList items)
{
foreach (INotifyPropertyChanged item in items)
{
if (item != null)
{
item.PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
但它仍然不起作用。谁能帮帮我吗?
编辑
使用 ItemsChangeObservableCollection 类,我可以在更新 Valore 字段时进入他的方法 item_PropertyChanged。所以我希望调用
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
一个 CollectionChanged 它是生成的......但它不是。如果我添加 Item1 构造函数,例如
public Item1()
{
Lista= new ItemsChangeObservableCollection<Item2>();
Lista.CollectionChanged += MyCollectionChanged;
}
MyCollectionChanged 永远不会被解雇。为什么????
解决方案
我意识到出了什么问题。当我在我的视图模型中实例化列表时,我试图在 Item1 构造函数中添加的 CollectionChanged hadler 被覆盖。
在我的视图模型中初始化后添加 CollectionChanged 可以解决问题。
推荐阅读
- javascript - 替换对按键事件不起作用的符号
- r - 如何更新/覆盖当前在 R 中导入的 csv 文件
- node.js - node-gyp 在构建时似乎失败了
- recaptcha - 如何使 Recaptcha 始终显示图像
- c# - 使用 C# (WinForms) 比较 Ram 中的图像和 Hard 中的图像
- sql - 按第三个月对元素进行分组
- captcha - 生成这些验证码的库的名称
- typescript - 基于 Expo 在 React Native 应用中集成华为移动服务
- python - 使用 POST 的“请求”模块,我想从整个 csv 单元格/值中提取整个 JSON 正文
- google-apps-script - 当 W 列包含数字时,将值附加到另一个电子表格