Как обновить свойство в родительском классе, когда вложенное свойство изменяется вC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как обновить свойство в родительском классе, когда вложенное свойство изменяется в

Сообщение Anonymous »

Я использую пользовательский класс 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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»