自定义控件中的依赖项属性意外共享内存/值 [英] Dependency property in custom control is sharing memory/values unexpectedly

查看:113
本文介绍了自定义控件中的依赖项属性意外共享内存/值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我进行了以下设置:


  • 自定义WPF控件(基类),源自 Canvas

  • 该基类的实现

  • 一个 ObservableCollection< T> 对该实现的依赖属性

  • Custom WPF Control (Base class), deriving from Canvas
  • Implementation of that base class
  • An ObservableCollection<T> dependency property on that implementation

我有一个测试应用,显示了我的自定义控件的三个唯一实例(例如< custom:MyControl x:Name = Test1 /> ,Test2,Test3等)。当我运行和调试应用程序时, ObservableCollection< T> 的内容对于控件的所有三个实例都是相同的。为什么?

I have a test app that displays three unique instances of my custom control (e.g. <custom:MyControl x:Name="Test1" />, Test2, Test3, and so on). When I run and debug the app, the contents of the ObservableCollection<T> are the same for all three instances of the control. Why is this?

图表:

[ContentProperty("DataGroups")]
public abstract class Chart : Canvas
{
    static Chart()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(Chart), new FrameworkPropertyMetadata(typeof(Chart)));
    }

    public ObservableCollection<ChartData> DataGroups
    {
        get { return (ObservableCollection<ChartData>)GetValue(DataGroupsProperty); }
        set { SetValue(DataGroupsProperty, value); }
    }
    public static readonly DependencyProperty DataGroupsProperty =
        DependencyProperty.Register("DataGroups", typeof(ObservableCollection<ChartData>), typeof(Chart), new FrameworkPropertyMetadata(new ObservableCollection<ChartData>(), FrameworkPropertyMetadataOptions.AffectsArrange));

    public abstract void Refresh();
}

ChartData:

ChartData:

[ContentProperty("Points")]
public class ChartData : FrameworkElement
{
    public ObservableCollection<Point> Points
    {
        get { return (ObservableCollection<Point>)GetValue(PointsProperty); }
        set { SetValue(PointsProperty, value); }
    }
    public static readonly DependencyProperty PointsProperty =
        DependencyProperty.Register("Points", typeof(ObservableCollection<Point>), typeof(ChartData), new PropertyMetadata(new ObservableCollection<Point>()));
}






我修改图表数据是(假设有多个数据组),例如:


One way I modify the chart data is (assuming multiple data groups), for example:

MyChart.DataGroups[index].Points.Add(new Point() { Y = someNumber });
MyChart.Refresh();

但是 DataGroups [] 中的每个实例都是

如果我通过XAML定义集合,也会发生同样的事情:

The same thing is happening if I define my collection(s) via XAML, like so:

<c:Chart x:Name="ChartA">
    <c:ChartData x:Name="DataGroup1" />
    <c:ChartData x:Name="DataGroup2" />
</c:Chart>

然后,在代码中,我将访问定义的集合:

Then, in code, I would access the defined collections:

ChartA.DataGroups[0].Points.Add(new Point() { Y = someNumber });
ChartA.Refresh();


推荐答案

您没有做错任何事情。这是设计使然。它应该以这种方式工作。只需在构造函数中设置您的值,就不会出现单例。

You havent done anything wrong. It is by design. It shall work that way. Just set your value in constructor instead and you will not have a singleton.

http://msdn.microsoft.com/en-us/library/aa970563.aspx

初始化超出默认值的集合值

Initializing the Collection Beyond the Default Value

创建依赖项属性时,请勿将属性默认值指定为初始字段值。相反,您可以通过依赖项属性元数据指定默认值。如果您的属性是引用类型,则在依赖项属性元数据中指定的默认值不是每个实例的默认值;相反,它是适用于该类型的所有实例的默认值。因此,必须小心不要将collection属性元数据定义的单个静态collection用作类型的新创建实例的工作默认值。相反,您必须确保在类构造函数逻辑中故意将集合值设置为唯一(实例)集合。否则,您将创建一个意外的单例类。

When you create a dependency property, you do not specify the property default value as the initial field value. Instead, you specify the default value through the dependency property metadata. If your property is a reference type, the default value specified in dependency property metadata is not a default value per instance; instead it is a default value that applies to all instances of the type. Therefore you must be careful to not use the singular static collection defined by the collection property metadata as the working default value for newly created instances of your type. Instead, you must make sure that you deliberately set the collection value to a unique (instance) collection as part of your class constructor logic. Otherwise you will have created an unintentional singleton class.

这篇关于自定义控件中的依赖项属性意外共享内存/值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆