gpt4 book ai didi

c# - 静态 ObservableCollection 事件未触发

转载 作者:太空宇宙 更新时间:2023-11-03 23:01:17 25 4
gpt4 key购买 nike

我有以下 static ObservableCollection 使用 linq 更新。为什么事件没有触发?

public static class myViewModel
{

private static ObservableCollection<ObjA> CollectionA = new ObservableCollection<ObjA>();
private static ObservableCollection<ObjB> CollectionB = new ObservableCollection<ObjB>();

static myViewModel()
{
CollectionA.CollectionChanged += new NotifyCollectionChangedEventHandler(myHandler);
CollectionA = new ObservableCollection(CollectionB.Select(abc=> new ObjA(abc, True));
}

private static void myHandler(object sender, NotifyCollectionChangedEventArgs e)
{
//To do
throw new NotImplementedException();
}

private static void updateCollection()
{

foreach (var x in CollectionA)
{
CollectionA.field=5;
}
}
}

最佳答案

第一步:给 CollectionA 一个事件处理程序。

CollectionA.CollectionChanged += new NotifyCollectionChangedEventHandler(myHandler);

第二步:丢弃 CollectionA 并将其替换为没有处理程序的不同集合。

CollectionA = new ObservableCollection(CollectionB.Select(abc=> new ObjA(abc, true));

看看你在那里做了什么?

CollectionA 返回对集合对象的引用。您没有向该集合对象添加项目。您正在用不同的集合对象替换该集合对象。

改为将项目添加到现有集合中:

CollectionA.CollectionChanged += new NotifyCollectionChangedEventHandler(myHandler);

foreach (var x in CollectionB.Select(abc=> new ObjA(abc, true)))
{
CollectionA.Add(x);
}

如果你真的想一次替换所有集合,你需要将处理程序添加到集合:

CollectionA = new ObservableCollection(CollectionB.Select(abc=> new ObjA(abc, true));

CollectionA.CollectionChanged += myHandler;

如果 myHandler 具有正确的参数和返回类型,则您不需要 new NotifyCollectionChangedEventHandler

处理此类事情的通常方法是使 CollectionA 成为一个添加处理程序本身的属性:

private static ObservableCollection<ObjA> _collectionA;
public static ObservableCollection<ObjA> CollectionA {
get { return _collectionA; }
set {
if (_collectionA != value)
{
// Remove handler from old collection, if any
if (_collectionA != null)
{
_collectionA.CollectionChanged -= myHandler;
}

_collectionA = value;

if (_collectionA != null)
{
_collectionA.CollectionChanged += myHandler;

// Whatever myHandler does on new items, you probably want to do
// that here for each item in the new collection.
}
}
}
}

static myViewModel()
{
// Now, whenever you replace CollectionA, the setter will add the changed
// handler automatically and you don't have to think about it.
CollectionA = new ObservableCollection(CollectionB.Select(abc=> new(abc, True));
}

更新

现在,我们用这些元素做什么?也许我们想知道它们的属性何时发生变化。 ObservableCollection 不会为我们做这些,但我们可以自己连接它。

思考以更方便、可重用的方式重构此代码的方法很有趣。

private static ObservableCollection<ObjA> _collectionA;
public static ObservableCollection<ObjA> CollectionA
{
get { return _collectionA; }
set
{
if (_collectionA != value)
{
// Remove handler from old collection, if any
if (_collectionA != null)
{
_collectionA.CollectionChanged -= myHandler;
}

// 1. Remove property changed handlers from old collection items (if old collection not null)
// 2. Add property changed to new collection items (if new collection not null)
AddAndRemovePropertyChangedHandlers(_collectionA, value, ObjA_PropertyChanged);

_collectionA = value;

if (_collectionA != null)
{
_collectionA.CollectionChanged += myHandler;
}
}
}
}

// NotifyCollectionChangedEventArgs gives us non-generic IList rather than IEnumerable
// but all we're doing is foreach, so make it as general as possible.
protected static void AddAndRemovePropertyChangedHandlers(
System.Collections.IEnumerable oldItems,
System.Collections.IEnumerable newItems,
PropertyChangedEventHandler handler)
{
if (oldItems != null)
{
// Some items may not implement INotifyPropertyChanged.
foreach (INotifyPropertyChanged oldItem in oldItems.Cast<Object>()
.Where(item => item is INotifyPropertyChanged))
{
oldItem.PropertyChanged -= handler;
}
}

if (newItems != null)
{
foreach (INotifyPropertyChanged newItem in newItems.Cast<Object>()
.Where(item => item is INotifyPropertyChanged))
{
newItem.PropertyChanged += handler;
}
}
}

private static void ObjA_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
}

private static void myHandler(object sender,
System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// If e.Action is Reset, you don't get the items that were removed. Oh well.
AddAndRemovePropertyChangedHandlers(e.OldItems, e.NewItems, ObjA_PropertyChanged);
}

关于c# - 静态 ObservableCollection 事件未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42977471/

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