Właściwość zależności ObservableCollection nie została zaktualizowana podczas usuwania elementu w kolekcji


Mam dołączoną właściwość typu ObservableCollection w kontrolce. Jeśli dodam lub usunę elementy z kolekcji, interfejs użytkownika nie zostanie zaktualizowany. Jeśli jednak zastąpię kolekcję w środku nową, interfejs użytkownika ViewModel rzeczywiście się zaktualizuje.
Czy ktoś może mi podać przykład tego, co muszę zrobić w obiekcie zależności, aby mógł obsłużyć zmiany w kolekcji?
Część obiektu zależności jest wymieniona poniżej:
public class RadCalendarBehavior : DependencyObject
{
private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var calendar = d as RadCalendar;
if (e.NewValue != null)
{
calendar.DayTemplateSelector = new SpecialDaySelector((ObservableCollection<DateTime>)e.NewValue, GetSpecialDayTemplate(d));
}
}public static ObservableCollection<DateTime> GetSpecialDays(DependencyObject obj)
{
return (ObservableCollection<DateTime>)obj.GetValue(SpecialDaysProperty);
}public static void SetSpecialDays(DependencyObject obj, ObservableCollection<DateTime> value)
{
obj.SetValue(SpecialDaysProperty, value);
}public static readonly DependencyProperty SpecialDaysProperty =
DependencyProperty.RegisterAttached("SpecialDays", typeof(ObservableCollection<DateTime>), typeof(RadCalendarBehavior), new UIPropertyMetadata(null, OnSpecialDaysChanged));
}
}

Rozumiem, że muszę zarejestrować, że kolekcja uległa zmianie, ale nie jestem pewien, jak to zrobić we właściwości zależności
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zmiany w kolekcji nie wywołają wywołania zwrotnego
OnSpecialDaysChanged
, ponieważ wartość właściwości zależności nie uległa zmianie. Jeśli musisz odpowiedzieć na wykrycie zmiany w kolekcji, musisz ręcznie obsłużyć zdarzenie
CollectionChanged
:
private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var calendar = d as RadCalendar; if (e.OldValue != null)
{
var coll = (INotifyCollectionChanged)e.OldValue;
// Unsubscribe from CollectionChanged on the old collection
coll.CollectionChanged -= SpecialDays_CollectionChanged;
} if (e.NewValue != null)
{
var coll = (ObservableCollection<DateTime>)e.NewValue;
calendar.DayTemplateSelector = new SpecialDaySelector(coll, GetSpecialDayTemplate(d));
// Subscribe to CollectionChanged on the new collection
coll.CollectionChanged += SpecialDays_CollectionChanged;
}
}private static void SpecialDays_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// handle CollectionChanged
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To tylko dodanie do odpowiedzi Thomasa. W moim kodzie współdziałam z właściwościami DependencyObject, tworząc lokalnie obiekt obsługi, jak pokazano poniżej:
private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var action = new NotifyCollectionChangedEventHandler( (o, args) =>
{
var calendar = d as RadCalendar; if (calendar!= null)
{
// play with calendar's properties/methods
}
}); if (e.OldValue != null)
{
var coll = (INotifyCollectionChanged)e.OldValue;
// Unsubscribe from CollectionChanged on the old collection
coll.CollectionChanged -= action;
} if (e.NewValue != null)
{
var coll = (ObservableCollection<DateTime>)e.NewValue;
// Subscribe to CollectionChanged on the new collection
coll.CollectionChanged += action;
}
}

Mam nadzieję, że to komuś pomoże.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli masz właściwość zależności typu kolekcji, pamiętaj o następujących kwestiach:

Jeśli twoja właściwość jest typem referencyjnym, wartość domyślna określona w metadanych właściwości zależności nie jest wartością domyślną dla każdej instancji; zamiast tego jest wartością domyślną i ma zastosowanie do wszystkich wystąpień tego typu. […]

Aby rozwiązać ten problem, należy zresetować wartość właściwości zależności kolekcji do unikatowego wystąpienia w ramach wywołania konstruktora klasy.

(cm.

właściwości zależności typu kolekcji
https://msdn.microsoft.com/en-us/library/aa970563(v=vs.110).aspx
MSDN )
Aby odpowiedzieć na pytanie Sama (właśnie napotkałem ten sam problem):
Ustaw program obsługi CollectionChanged jako statyczny i anuluj subskrypcję/ponowną subskrypcję na poziomie wystąpienia.
private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var calendar = d as RadCalendar; if (e.OldValue != null)
{
var coll = (INotifyCollectionChanged)e.OldValue;
// Unsubscribe from CollectionChanged on the old collection of the DP-instance (!)
coll.CollectionChanged -= calendar.SpecialDays_CollectionChanged;
} if (e.NewValue != null)
{
var coll = (ObservableCollection<DateTime>)e.NewValue;
calendar.DayTemplateSelector = new SpecialDaySelector(coll, GetSpecialDayTemplate(d));
// Subscribe to CollectionChanged on the new collection of the DP-instance (!)
coll.CollectionChanged += calendar.SpecialDays_CollectionChanged;
}
}private void SpecialDays_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// handle CollectionChanged on instance-level
}

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się