【发布时间】:2021-08-16 15:18:47
【问题描述】:
这几天我一直在想办法解决我的问题。
我有一个类似这样的数据结构(我使用 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));
}
}
但它仍然不起作用。谁能帮帮我?
编辑
当我更新 Valore 字段时,我可以使用 ItemsChangeObservableCollection 类进入他的方法 item_PropertyChanged。所以我希望调用
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
一个 CollectionChanged 它是生成的......但它不是。 如果我像添加 Item1 构造函数
public Item1()
{
Lista= new ItemsChangeObservableCollection<Item2>();
Lista.CollectionChanged += MyCollectionChanged;
}
MyCollectionChanged 永远不会被触发。为什么????
【问题讨论】:
-
请参阅 Fody 文档中的“依赖属性” - github.com/Fody/PropertyChanged#notes
-
“从属属性”段落中描述的行为仅对同一类的字段有效,对子对象字段无效。
-
作为一个选项,您可以在
Item2类中拥有一个属性Item1 Owner,并在Valore设置器中提升Owner.PropertyChanged。 -
mmmm 好的,这是一个想法......但是还有其他一些解决方案可以让我的数据结构保持不变吗?已经够复杂了!我会正确使用 ItemsChangeObservableCollection 类,就像我在 EDITED 帖子中写的那样
标签: c# xamarin observablecollection inotifypropertychanged inotifycollectionchanged