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?
So aktualisieren Sie eine Eigenschaft in einer übergeordneten Klasse, wenn sich eine verschachtelte Immobilie in a änder ⇐ C#
-
- Similar Topics
- Replies
- Views
- Last post
-
-
Übergeordnetes PHPDOCS -Argument einer Methode in einer übergeordneten Klasse
by Anonymous » » in Php - 0 Replies
- 0 Views
-
Last post by Anonymous
-