微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ObervableCollection、CollectionChanged 和 PropertyChanged

如何解决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));

a CollectionChanged 它生成了...但它不是。 如果我添加 Item1 构造函数,如

public Item1()
{
    Lista= new ItemsChangeObservableCollection<Item2>();
    Lista.CollectionChanged += MyCollectionChanged;     
}

MyCollectionChanged 永远不会被触发。为什么????

解决方法

我意识到出了什么问题。 我尝试在 Item1 构造函数中添加的 CollectionChanged hadler 在我在视图模型中实例化列表时被覆盖。

在我的视图模型中初始化后添加 CollectionChanged 解决了问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。