Ich verwende eine benutzerdefinierte Voll -DervableCollection -Klasse, die die Beobachtungspanne erweitert, wobei t inotifyPropertyChanged implementiert wird. Die Idee besteht Die darin enthaltenen Objekte, aber das Ereignis von ItemPropertyChanged wird nicht ausgelöst, wenn sich eine verschachtelte Eigenschaft ändert, z. B. wenn eine Eigenschaft in einer untergeordneten Klasse aktualisiert wird. /> 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. nicht ausgelöst. < /p>
foreach (var item in ClassAList)
{
item.ClassB.ItemPropertyChanged += Costs_ItemPropertyChanged;
}
< /code>
cost_itempropertyChanged wird nicht ausgelöst, wenn die Kosten geändert werden. Wenn sich das IT in IT ändert (selbst mit InotifyPropertychanged), versuchen Sie, es mit verschachtelten Eigenschaften zu verbessernpublic 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