添加集合项目时,OnRender不会调用?
我有一个用于执行动态数据呈现的自定义控件。此控件包含一组DataPoint
对象,并且每个DataPoint
都基于其位置(控制点绘制在OnRender
方法中)呈现在控件中。添加集合项目时,OnRender不会调用?
自定义控件包含许多DependencyProperties
影响渲染的图像,因此具有FrameworkPropertyMetadata
描述了控制应呈现,如果属性的变化:
public static readonly DependencyProperty DataPointsProperty =
DependencyProperty.Register(
"DataPoints", //Property Name
typeof(List<DataPoint>), //CLR-Property Type
typeof(MyCustomControl), //Custom Control Type
new FrameworkPropertyMetadata(
new List<DataPoint>(), //Default Value.
FrameworkPropertyMetadataOptions.AffectsRender //Re-render if changed
)
);
遗憾的是,重新渲染确实NOT发生在新的DataPoint
为时,将添加到此集合中。
如何添加新的DataPoint
时,如何配置我的自定义控件以便调用OnRender
方法?
除了程序的运行时间以外,重新呈现必须发生在WPF设计器中。
首先,List<T>
不支持更改通知,而WPF的内置集合做了支持更改通知并非来自List<T>
。我建议您使用IList<T>
或IEnumerable<T>
作为您的房产类型。第二,每当新的集合被分配到DataPoints
(验证它实现INotifyCollectionChanged
后),并且使用该处理程序调用InvalidateVisual()
时,您将需要添加集合更改处理程序。最简单的方法是在注册DataPoints
依赖项属性时指定属性更改回调。
public static readonly DependencyProperty DataPointsProperty =
DependencyProperty.Register(
"DataPoints", //Property Name
typeof(IList<DataPoint>), //CLR-Property Type
typeof(MyCustomControl), //Custom Control Type
new FrameworkPropertyMetadata(
default(IList<DataPoint>), //Default Value.
FrameworkPropertyMetadataOptions.AffectsRender, //Re-render if changed,
OnDataPointsPropertyChanged
)
);
private static void OnDataPointsPropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var control = (MyCustomControl)d;
var oldValue = e.OldValue as INotifyCollectionChanged;
var newValue = e.NewValue as INotifyCollectionChanged;
if (oldValue != null)
oldValue.CollectionChanged -= control.OnDataPointsCollectionChanged;
if (newValue != null)
newValue.CollectionChanged += control.OnDataPointsCollectionChanged;
}
private void OnDataPointsCollectionChanged(
object s,
NotifyCollectionChangedEventArgs e)
{
this.InvalidateVisual();
}
最后,不要指定默认属性值的集合实例:这将导致所有实例共享相同的集合(除非分配一个新的)。相反,初始化您的构造函数中的属性:
public MyCustomControl()
{
// ...
SetCurrentValue(DataPointsProperty, new ObservableCollection<DataPoint>());
}
+1提醒我在初始化引用类型依赖项属性时使用SetCurrentValue而不是本地值。 – Clemens 2014-09-24 19:13:34
太棒了!有用。顺便说一下,如果集合具有在XAML中指定的项目,则“IList”将不起作用,因为它只允许1个子元素(并且该子元素不是列表项)。但是,将其更改为“ObservableCollection”允许我在XAML中指定项目。 – 2014-09-24 19:53:17
非泛型'IList'应该在Xaml中正常工作,但'IList
没有这个**大胆**也人们可以很好地阅读这个问题。我已经编辑了你的问题。 – 2014-09-24 18:45:47