我正在尝试创建一个从Xaml创建的DependencyObject
。
它的DependencyProperty
类型List<object>
定义如下:
public List<object> Map
{
get { return (List<object>)GetValue(MapProperty); }
set { SetValue(MapProperty, value); }
}
// Using a DependencyProperty as the backing store for Map. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MapProperty =
DependencyProperty.Register("Map", typeof(List<object>), typeof(MyConverter), new PropertyMetadata(null));
的Xaml:
<MyConverter x:Key="myConverter">
<MyConverter.Map>
<TextPair First="App.Blank" Second ="App.BlankViewModel"/>
</MyConverter.Map>
</MyConverter>
我一直在接收Cannot add instance of type 'UwpApp.Xaml.TextPair' to a collection of type 'System.Collections.Generic.List<Object>
。
什么可能导致此错误?谢谢。
答案 0 :(得分:4)
您使用DependencyProperty
定义了typeof(List<object>)
的类型。这意味着该属性需要这种类型。由于List<object>
不是
一个TextPair
我们需要更通用。不要使用特殊的通用列表类型,只需使用IList
作为类型,并添加new List<object>()
作为默认值。这应该可以解决你的问题。
public IList Map
{
get { return (IList)GetValue(MapProperty); }
set { SetValue(MapProperty, value); }
}
public static readonly DependencyProperty MapProperty =
DependencyProperty.Register("Map", typeof(IList),
typeof(MyConverter), new PropertyMetadata(new List<object>()));
修改强>
看起来UWP的行为与WPF略有不同。要在UWP中运行此代码,您需要使用通用IList<object>
代替IList
作为属性类型。
答案 1 :(得分:1)
使用Fruchtzwerg显示的方法,您将获得一个意外的单例:MyCoverter的所有实例之间共享一个List实例。
请参见Collection-Type DependencyProperties in the Microsoft Docs。
为避免这种情况,您需要像这样单独设置值
public class MyConverter
{
public IList Map
{
get { return (IList)GetValue(MapProperty); }
set { SetValue(MapProperty, value); }
}
public static readonly DependencyProperty MapProperty =
DependencyProperty.Register("Map", typeof(IList),
typeof(MyConverter), new PropertyMetadata(null));
public MyConverter
{
// SetValue causes DependencyProperty precedence issue so bindings
// will not work.
// WPF supports SetCurrentValue() which solves this but UWP does not
this.SetValue(MapProperty, new List<object>());
}
}
但是,由于DependencyProperty Value Precedence,这将导致另一个问题:由于使用了具有更高优先级的SetValue,您将不再能够绑定到MapProperty。
因此,最佳和正确的解决方案是使用CreateDefaultValueCallback。您可以按照以下步骤进行操作:
public static readonly DependencyProperty MapProperty =
DependencyProperty.Register("Map", typeof(IList),
typeof(MyConverter), PropertyMetadata.Create(
new CreateDefaultValueCallback(() =>
{
return new List<object>();
}
}));