Wpf:通用集合依赖属性
Posted
技术标签:
【中文标题】Wpf:通用集合依赖属性【英文标题】:Wpf: Generic collection dependency property 【发布时间】:2021-02-04 06:30:25 【问题描述】:我创建了具有通用集合依赖属性的自定义控件。 但是,每当此属性从 xaml 更改时,setter 中的视图模型中的值为 null。
自定义控件:
public IList A
get return (IList)GetValue(AProperty);
set SetValue(AProperty, value);
public static readonly DependencyProperty AProperty =
DependencyProperty.Register(nameof(A), typeof(IList), typeof(CustomControl), new PropertyMetadata(new List<object>()));
视图模型:
List<B> collectionB;
public List<B> CollectionB
get return collectionB;
set
if (collectionB == value) return;
collectionB = value;
如果我将 CollectionB 的类型更改为 List
【问题讨论】:
您还没有向我们展示“从 xaml 更改”的确切含义。有没有像A="Binding CollectionB, Mode=TwoWay"
这样的绑定?以及控件是如何改变集合的?
绑定是 A="Binding CollectionB, Mode=OneWayToSource"
默认值(请参阅我在答案中的备注)类型为List<object>
。这不能分配给List<B>
类型的源属性。 OneWayToSource 在这里不是一个非常适合的方法。根本不要设置默认值,而是使用双向绑定。
@AdamStawarek:当然,您可以将IList
属性设置为List<A>
。如果属性仍然是null
,那么你在设置它时做错了,或者你没有设置它。没有一些示例代码很难说。
【参考方案1】:
集合属性的最通用类型是IEnumerable
- 例如,参见ItemsControl.ItemsSource
属性。
还要注意,为集合类型依赖属性设置非空默认值是有问题的,因为默认情况下,所属类的所有实例都将在同一个集合实例上运行。将元素添加到一个控件的 A 属性会更改所有其他控件实例的集合。
你应该像这样声明属性:
public IEnumerable A
get return (IEnumerable)GetValue(AProperty);
set SetValue(AProperty, value);
public static readonly DependencyProperty AProperty =
DependencyProperty.Register(
nameof(A), typeof(IEnumerable), typeof(CustomControl));
如果您确实需要一个非空默认值,请将其添加到控件的构造函数中:
SetCurrentValue(AProperty, new List<object>());
更新:使用 OneWayToSource
绑定集合类型属性,如
<local:CustomControl A="Binding CollectionB, Mode=OneWayToSource" />
只有在 A
的默认值与 Binding 的源属性赋值兼容时才能工作,这不适用于 List<object>
和 List<B>
。
您根本不应该设置默认值,而是使用双向绑定
<local:CustomControl A="Binding CollectionB, Mode=TwoWay" />
与
private List<B> collectionB = new List<B>();
public List<B> CollectionB
get return collectionB;
set collectionB = value;
或者只是
public List<B> CollectionB get; set; = new List<B>();
【讨论】:
不幸的是,使用 IEnumerable 代替 IList 并不能解决此问题,并且 value 仍然为 null。【参考方案2】:这是因为IList<T>
没有实现IList
,所以从一种类型转换到另一种类型会失败。
如果您想要与A
绑定,那么您必须将其绑定到同样实现IList
的东西
【讨论】:
我已将 IList 更改为 List 作为第二个实现 IList 但不幸的是它也不起作用。仍然很好,所以我会更新问题。以上是关于Wpf:通用集合依赖属性的主要内容,如果未能解决你的问题,请参考以下文章