Domanda

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.

È stato utile?

Soluzione

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

Altri suggerimenti

I think the problem could be that you are writing typeof(MyClass), and should be typeof(MyClass<T,U>).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top