So aktualisieren Sie eine Eigenschaft in einer übergeordneten Klasse, wenn sich eine verschachtelte Immobilie in a änderC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 So aktualisieren Sie eine Eigenschaft in einer übergeordneten Klasse, wenn sich eine verschachtelte Immobilie in a änder

Post by Anonymous »

Ich verwende eine benutzerdefinierte Voll -DervableCollection -Klasse, die die Beobachtungspanne erweitert, wobei t inotifyPropertyChanged implementiert wird. Die Idee ist, eine Sammlung von Objekten zu haben, die nicht nur Änderungen ihrer eigenen Eigenschaften benachrichtigen, sondern auch Änderungen in ihren verschachtelten Objekten benachrichtigen. /> Ich habe eine Struktur wie diese: < /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>
Wenn classc.cost ändert, möchte ich, dass der SummOfBCost in Classa automatisch aktualisiert wird. foreach (var item in ClassAList)
{
item.ClassB.ItemPropertyChanged += Costs_ItemPropertyChanged;
}
< /code>
cost_itempropertyChanged wird nicht ausgelöst, wenn die Kosten geändert werden.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>
Was fehlt mir? Ist es etwas nicht möglich?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post