Goa*_*ker 23 wpf dependency-properties observablecollection
我在控件上有一个ObservableCollection类型的附加属性.如果我在集合中添加或删除项目,则ui不会更新.但是,如果我用新的替换集合,则ui会更新ViewModel.
有人能给我一个我在Dependency对象中需要做什么的例子,以便它可以处理集合中的变化吗?
下面列出了依赖项对象的一部分:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我需要注册该集合已经更改,但我不确定如何在依赖项属性中执行此操作
Tho*_*que 39
集合中的更改不会触发OnSpecialDaysChanged回调,因为依赖项属性的值未更改.如果您需要做出反应以检测集合的更改,则需要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
}
Run Code Online (Sandbox Code Playgroud)
小智 6
如果您有集合类型依赖属性,请记住以下几点:
如果您的属性是引用类型,则依赖属性元数据中指定的默认值不是每个实例的默认值;相反,它是适用于该类型的所有实例的默认值。[...]
要纠正此问题,您必须将集合依赖项属性值重置为唯一实例,作为类构造函数调用的一部分。
(请参阅 MSDN集合类型依赖属性)
回答 Sam 的问题(我刚刚遇到了同样的问题):
使您的 CollectionChanged 处理程序成为非静态的,并在实例级别取消订阅/重新订阅。
private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var calendar = (RadCalendar)d;
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
}
Run Code Online (Sandbox Code Playgroud)
这只是为了增加托马斯的答案.在我的代码中,我通过创建一个类似于下面的处理程序对象来与DependencyObject的属性进行交互:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
希望这对某人有帮助.
| 归档时间: |
|
| 查看次数: |
14469 次 |
| 最近记录: |