I have an abstract generic class that defines a generic dependency property the type of which is to be defined by subclassing classes. This property is somehow not recognized as a dependency property so that I get an error message during runtime when binding to this property. Additionally during compilation time the constructor cannot call InitializeComponent
. Why is that?
The generic abstract class MyClass
:
abstract public class MyClass<T,U> : UserControl {
protected MyClass() {
InitializeComponent(); // Here is one error: Cannot be found
}
abstract protected U ListSource;
private static void DPChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var myClassObj = (MyClass) d;
myClassObj.DataContext = myClassObj.ListSource;
}
// Causes a binding error at runtime => DP (of the concrete subclass)
// is not recognized as a dependency property
public static readonly DependencyProperty DPProperty =
DependencyProperty.Register(
"DP",
typeof(T),
typeof(MyClass),
new PropertyMetadata(null, DPChanged));
public T DP {
get { return (T) GetValue(DPProperty); }
set { SetValue(DPProperty, value); }
}
}
The corresponding XAML:
<UserControl x:Class="Path.of.Namespace.MyClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ListView>
<!-- Some stuff for the list view - used for all subclasses -->
</ListView>
</UserControl>
A concrete subclass MySubClass
:
public partial class MySubClass : MyClass<ClassWithAList, List<int>> {
public MySubClass() {
InitializeComponent(); // Another error: Cannot be found
}
protected List<int> ListSource {
get { return new List<int>(); } // Just a dummy value
}
}
The corresponding XAML:
<local:MySubClass xmlns:local="Path.of.Namespace.MySubClass" />
P.S. I am also not quite sure if the partial
stuff is done correctly - R# suggests to remove these keywords.
I think there are several things wrong with your code, but first, let me explain partial
in this context:
partial
is used to declare one class in separate files. As visual studio is creating a MySubClass.g.cs
with a partial class MySubClass
(btw. this is where the method InitializeComponent
is declared) from your MySubClass.xaml
you'd have this class declaration twice and thus to get this to compile you will need the partial
keyword.
Now to the rest: XAML and generics don't do well together, meaning: not at all. your 'corresponding XAML' is declaring a MyClass
. But a MyClass
without generic parameters doesn't exist. You could at this point change x:Class="Path.of.Namespace.MyClass"
to x:Class="Path.of.Namespace.MySubClass"
, that should work.
but now the next thing is: how do you want to access that dependecy property in xaml? it is a static member in a generic type, so you have to specify it like this in code: MyClass<ClassWithAList, List<int>>.DPProperty
. The problem is again: you can't do that in xaml
to solve your problem it might be a good idea to tell us what you want to accomplish