4

我有以下设置:

  • 自定义 WPF 控件(基类),源自Canvas
  • 该基类的实现
  • 该实现的ObservableCollection<T>依赖属性

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


图表:

[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();
}

图表数据:

[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>()));
}

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

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

但是里面的每个实例DataGroups[]都是相同的。


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

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

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

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

2 回答 2

10

你没有做错任何事。这是设计使然。它应该这样工作。只需在构造函数中设置您的值,您将不会有一个单例。

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

初始化超出默认值的集合

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

于 2013-10-07T07:38:18.623 回答
1

PointsProperty是您使用默认值初始化的静态值new ObservableCollection<Point>()。此静态初始化程序创建一个单一的ObservableCollection并将其用作您创建Points的任何类型对象的默认值。ChartData它不是ObservableCollection为每个需要默认值的实例创建 new 的工厂;它只是ObservableCollection对每个使用相同的。

我猜你从来没有明确地为 赋值Points,因此总是依赖于默认值,它在所有实例中共享。这就是为什么每个实例都有相同的点集合。

于 2013-10-07T06:01:15.717 回答