I'm trying to create a DependencyObject
which is created from Xaml.
It has a DependencyProperty
of type List<object>
defined like so:
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>
I keep receiving Cannot add instance of type 'UwpApp.Xaml.TextPair' to a collection of type 'System.Collections.Generic.List<Object>
.
What can cause this error? Thank you.
You defined the type of your DependencyProperty
with typeof(List<object>)
. This means the property requires exactly this type. Since List<object>
is not
a TextPair
we need to be more generic. Instead of using a special generic list type just use IList
as type and add new List<object>()
as default value. This should solve your problem.
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>()));
EDIT:
Looks like UWP behaves a bit different than WPF. To run this code in UWP you need to use the generic IList<object>
instead of IList
as property type.
Using the method shown by Fruchtzwerg you will get an unintentional singleton: one instance of List shared between all instances of MyCoverter.
See Collection-Type DependencyProperties in the Microsoft Docs.
To avoid this, you need to set the value separately, like this
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>());
}
}
However, this will cause another problem due to DependencyProperty Value Precedence: you will no longer be able to bind to MapProperty as you have used SetValue which has a higher precedence.
So the best & correct solution is to use a CreateDefaultValueCallback. You can do this as follows:
public static readonly DependencyProperty MapProperty =
DependencyProperty.Register("Map", typeof(IList),
typeof(MyConverter), PropertyMetadata.Create(
new CreateDefaultValueCallback(() =>
{
return new List<object>();
}
}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With