Я использую пользовательский класс FullyBservableCollection, который расширяет ObservableCollection, где T реализует INOTIFORPORTYCHANGED. Идея состоит в том, чтобы иметь набор объектов, которые не только уведомляют об изменениях в их собственных свойствах, но и уведомили об изменениях в их вложенных объектах. Объекты внутри него, но событие Itempropertychanged не запускается при изменении вложенного свойства, например, когда обновляется свойство в детском классе. < /p>
Структура класса
У меня есть такая структура: < /p>
FullyObservableCollection classAList
public class ClassA
{
public FullyObservableCollection BCollection { get; set; }
public int SumOfBCost => BCollection.Sum(b => b.C.Cost);
}
public class ClassB
{
public ClassC C { get; set; }
}
public class ClassC
{
public int Cost { get; set; }
public int Currency { get; set; }
}
< /code>
Когда Classc.cost изменяется в Classb, я хочу, чтобы SumofBcost в классе обновлялся автоматически.
Проблема заключается в том, что при изменении Classc.cost событие ItempropertyChanged для Classb является не запускается. < /p>
foreach (var item in ClassAList)
{
item.ClassB.ItemPropertyChanged += Costs_ItemPropertyChanged;
}
< /code>
ряд_itempropertychanged не запускается при изменении стоимости. Когда элемент в нем меняется (даже с INOTIFYPROPERTYCHEND) и попытайтесь улучшить его, чтобы покрыть вложенные свойстваpublic class FullyObservableCollection : ObservableCollection where T : INotifyPropertyChanged
{ public event EventHandler ItemPropertyChanged;
public FullyObservableCollection() { }
public FullyObservableCollection(List list) : base(list)
{
ObserveAll();
}
public FullyObservableCollection(IEnumerable enumerable) : base(enumerable)
{
ObserveAll();
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action is NotifyCollectionChangedAction.Remove
or NotifyCollectionChangedAction.Replace)
{
foreach (T item in e.OldItems)
UnsubscribeFromItem(item);
}
if (e.Action is NotifyCollectionChangedAction.Add
or NotifyCollectionChangedAction.Replace)
{
foreach (T item in e.NewItems)
SubscribeToItem(item);
}
base.OnCollectionChanged(e);
}
protected void OnItemPropertyChanged(ItemPropertyChangedEventArgs e)
{
ItemPropertyChanged?.Invoke(this, e);
}
protected void OnItemPropertyChanged(int index, T sender, PropertyChangedEventArgs e)
{
OnItemPropertyChanged(new ItemPropertyChangedEventArgs(index, e));
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, sender, sender, index));
}
protected override void ClearItems()
{
foreach (var item in Items)
UnsubscribeFromItem(item);
base.ClearItems();
}
private void SubscribeToItem(T item)
{
item.PropertyChanged += ChildPropertyChanged;
SubscribeToNestedProperties(item);
}
private void UnsubscribeFromItem(T item)
{
item.PropertyChanged -= ChildPropertyChanged;
UnsubscribeFromNestedProperties(item);
}
private void ObserveAll()
{
foreach (var item in Items)
SubscribeToItem(item);
}
private void ChildPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var typedSender = (T)sender;
var i = Items.IndexOf(typedSender);
if (i < 0)
throw new ArgumentException("Received property notification from item not in collection");
OnItemPropertyChanged(i, typedSender, e);
}
private void SubscribeToNestedProperties(object obj)
{
foreach (var property in obj.GetType().GetProperties())
{
if (typeof(INotifyPropertyChanged).IsAssignableFrom(property.PropertyType))
{
var nestedObject = property.GetValue(obj) as INotifyPropertyChanged;
if (nestedObject != null)
{
nestedObject.PropertyChanged += ChildPropertyChanged;
}
}
}
}
private void UnsubscribeFromNestedProperties(object obj)
{
foreach (var property in obj.GetType().GetProperties())
{
if (typeof(INotifyPropertyChanged).IsAssignableFrom(property.PropertyType))
{
var nestedObject = property.GetValue(obj) as INotifyPropertyChanged;
if (nestedObject != null)
{
nestedObject.PropertyChanged -= ChildPropertyChanged;
}
}
}
}
///
/// Finds the index of the first item that matches the given predicate.
///
///
The predicate to match items.
/// The index of the first matching item, or -1 if no item matches.
public int FindIndex(Predicate predicate)
{
for (int i = 0; i < Items.Count; i++)
{
if (predicate(Items))
{
return i;
}
}
return -1;
}
}
///
/// Provides data for the event.
///
public class ItemPropertyChangedEventArgs : PropertyChangedEventArgs
{
///
/// Gets the index in the collection for which the property change has occurred.
///
///
/// Index in parent collection.
///
public int CollectionIndex { get; }
///
/// Initializes a new instance of the class.
///
/// The index in the collection of changed item.
/// The name of the property that changed.
public ItemPropertyChangedEventArgs(int index, string name) : base(name)
{
CollectionIndex = index;
}
///
/// Initializes a new instance of the class.
///
/// The index.
/// The instance containing the event data.
public ItemPropertyChangedEventArgs(int index, PropertyChangedEventArgs args) : this(index, args.PropertyName)
{ }
}
< /code>
Что мне не хватает? Это что -то невозможно?
Подробнее здесь: https://stackoverflow.com/questions/794 ... anges-in-a
Как обновить свойство в родительском классе, когда вложенное свойство изменяется в ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как обновить свойство в родительском классе, когда вложенное свойство изменяется в
Anonymous » » в форуме C# - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как обновить свойство в родительском классе, когда вложенное свойство изменяется в
Anonymous » » в форуме C# - 0 Ответы
- 10 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как обновить свойство в родительском классе, когда вложенное свойство изменяется в
Anonymous » » в форуме C# - 0 Ответы
- 7 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как обновить свойство в родительском классе, когда вложенное свойство изменяется в
Anonymous » » в форуме C# - 0 Ответы
- 9 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как обновить свойство в родительском классе, когда вложенное свойство изменяется в
Anonymous » » в форуме C# - 0 Ответы
- 8 Просмотры
-
Последнее сообщение Anonymous
-