C# 自定义控件中的依赖项属性意外共享内存/值
我有以下设置:C# 自定义控件中的依赖项属性意外共享内存/值,c#,wpf,custom-controls,dependency-properties,C#,Wpf,Custom Controls,Dependency Properties,我有以下设置: 自定义WPF控件(基类),派生自Canvas 该基类的实现 该实现上的observateCollection依赖属性 我有一个测试应用程序,它显示我的自定义控件的三个唯一实例(例如,、Test2、Test3等等)。当我运行并调试应用程序时,控件的所有三个实例的ObservableCollection的内容都是相同的。为什么会这样 图表: [ContentProperty("DataGroups")] public abstract class Chart : Canvas
- 自定义WPF控件(基类),派生自
Canvas
- 该基类的实现
- 该实现上的
依赖属性observateCollection
、Test2、Test3等等)。当我运行并调试应用程序时,控件的所有三个实例的ObservableCollection
的内容都是相同的。为什么会这样
图表:
[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();
}
但是数据组[]
中的每个实例都是相同的
如果我通过XAML定义集合,也会发生同样的情况,如下所示:
<c:Chart x:Name="ChartA">
<c:ChartData x:Name="DataGroup1" />
<c:ChartData x:Name="DataGroup2" />
</c:Chart>
PointsProperty
是一个静态值,您可以使用默认值newobserveCollection()
初始化该值。此静态初始值设定项创建单个可观察集合
,并将其用作您创建的任何ChartData
类型的对象上的点
的默认值。它不是一个为每个需要默认值的实例创建新的ObservableCollection
s的工厂;它只是对每一个使用相同的observeableCollection
我猜您从未显式地将值分配给
点
,因此始终依赖默认值,该值在所有实例中共享。这就是为什么每个实例都有相同的点集合。您没有做错任何事情。这是故意的。这样就行了。只需在构造函数中设置值,就不会有单例
初始化集合时超出默认值
创建依赖项属性时,不会将属性默认值指定为初始字段值。而是通过依赖项属性元数据指定默认值。如果属性是引用类型,则依赖项属性元数据中指定的默认值不是每个实例的默认值;相反,它是应用于该类型的所有实例的默认值。因此,必须小心不要将集合属性元数据定义的单一静态集合用作新创建的类型实例的工作默认值。相反,您必须确保故意将集合值设置为唯一(实例)集合,作为类构造函数逻辑的一部分。否则,您将创建一个无意的单例类。您必须向我们展示一些代码。依赖项属性声明是什么样子的?您是如何绑定它的?添加了代码,尽管它非常不完整(我尽可能地提取相关的位,但我不能将它们全部粘贴到这里,因为实现非常庞大,而且很多都是不相关的)。点来自哪里?它是如何分配的?问题的底部解释了它的定义位置和分配方式,尽管它通过XAML分配的可能性与通过代码分配的可能性一样(因为
[ContentProperty]
属性)。而Point
只是System.Windows.Point
。因此,如果您有Test1.Points=newobservedcollection();Test2.Points=新的ObservableCollection();Test1.Points.Add(newpoint())
然后Test2。点
将具有与添加到Test1
中相同的点。完美,解决了它。我不知道依赖属性默认值是如何工作的。谢谢你们两个都是对的,但我以200分而不是44000分支持了弱者。希望您能理解。:)谢谢你的帮助!
MyChart.DataGroups[index].Points.Add(new Point() { Y = someNumber });
MyChart.Refresh();
<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();