c#ObservableCollection:如何实现CollectionChanged事件

c#ObservableCollection:如何实现CollectionChanged事件,c#,mvvm,xamarin,observablecollection,C#,Mvvm,Xamarin,Observablecollection,我想知道如何使用ObservableCollection和CollectionChanged事件。我有一个画布类,可以在上面画笔画。我是将CollectionChanged事件处理程序放置在Canvas类中并侦听集合更改,还是将其放置在承载笔划集合的模型中 public partial class CollectionBindingPage : ContentPage { private ObservableCollection<Object> c; public

我想知道如何使用ObservableCollection和CollectionChanged事件。我有一个画布类,可以在上面画笔画。我是将CollectionChanged事件处理程序放置在Canvas类中并侦听集合更改,还是将其放置在承载笔划集合的模型中

public partial class CollectionBindingPage : ContentPage
{
    private ObservableCollection<Object> c;

    public CollectionBindingPage()
    {
        InitializeComponent();

        c.CollectionChanged += (sender, e) => { 
            //Update the display when strokes was added or removed.
        };
    }


    public class Object
    {
        public string A { get; set; }
        public string B { get; set; }
    }

    public class ViewModel
    {
        public ObservableCollection<Object> collection { get; set; }
    }
}
公共部分类集合BindingPage:ContentPage
{
私人可观测集合c;
公共集合绑定页()
{
初始化组件();
c、 CollectionChanged+=(发送方,e)=>{
//添加或删除笔划时更新显示。
};
}
公共类对象
{
公共字符串A{get;set;}
公共字符串B{get;set;}
}
公共类视图模型
{
公共ObservableCollection集合{get;set;}
}
}

对不起,我是第一次使用这个

e
属于
NotifyCollectionChangedEventArgs
类型,它包含
新项目
旧项目
操作

c.CollectionChanged += (sender, e) => { 
    Console.WriteLine($"{e.Action}");
    // check e.Action and draw your stuff       
};

注释中提到的解决方案草图

class MyObject : INotifyPropertyChanged
{
    private string _a;
    public event PropertyChangedEventHandler PropertyChanged;

    public string A
    {
        get { return _a; }
        set
        {
            _a = value;
            OnPropertyChanged();
        }
    }

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

class Pagey : ContentPage
{
    private ObservableCollection<MyObject> c = new ObservableCollection<MyObject>();

    // somwhere in your code 
    c.CollectionChanged += OnCollectionChanged;

    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
    {
        if (args.NewItems != null)
        {
            foreach (var item in args.NewItems.Cast<MyObject>())
            {
                item.PropertyChanged += OnChanged;
            }
        }

        if(args.OldItems != null)
        {
            foreach (var item in args.OldItems.Cast<MyObject>())
            {
                item.PropertyChanged -= OnChanged;
            }
        }

        Redraw();
    }

    private void OnChanged(object sender, PropertyChangedEventArgs e)
    {
        Redraw();
    }

    private void Redraw()
    {

    }
}
类MyObject:INotifyPropertyChanged
{
私有字符串_a;
公共事件属性更改事件处理程序属性更改;
公共字符串A
{
获取{return\u a;}
设置
{
_a=数值;
OnPropertyChanged();
}
}
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
类Pagey:ContentPage
{
私有ObservableCollection c=新ObservableCollection();
//那么你的代码在哪里
c、 CollectionChanged+=OnCollectionChanged;
CollectionChanged的私有void(对象发送方,NotifyCollectionChangedEventArgs)
{
如果(args.NewItems!=null)
{
foreach(args.NewItems.Cast()中的变量项)
{
item.PropertyChanged+=一次更改;
}
}
如果(args.OldItems!=null)
{
foreach(args.OldItems.Cast()中的变量项)
{
item.PropertyChanged-=一次更改;
}
}
重画();
}
私有void OnChanged(对象发送方,PropertyChangedEventArgs e)
{
重画();
}
私有void重绘()
{
}
}

我有点不知道该把活动放在哪里。。在模型类或视图类mabe中,您应该将处理程序移动到函数
public OnChange(对象发送方,CollectionChangeEventArgs e){}
,而不是使用lambda,因为如果卸载视图,您应该取消订阅(使用
c.CollectionChanged-=OnChange;
)事件。它必须在视图中,因为您希望在视图中执行某些操作。如果您希望视图响应更改,则该视图应该是侦听事件的视图谢谢。。修改列表中的项目如何?关于e元素的答案,我找不到那个属性。只有newItems和oldItems,并且列表中的IListitems都应实现InotifyPropertyChangedYou将集合属性绑定到画布的ItemsSource属性。这就是你要做的。