c# - être - wpf usercontrol dependencyproperty



Définir les propriétés de dépendance en XAML lorsque la classe de base est générique (1)

Je suppose que le problème réside dans le type de propriétaire de la propriété de dépendance (typeof (WindowBase <ViewModel>).) Chaque type générique fermé sera un type d'exécution complètement différent alors que le compilateur est satisfait que la propriété existe. t le trouve quand il regarde la propriété par rapport au type (différent) dans son stockage interne.

Comme vous l'avez constaté, la classe non générique fonctionne car le type de propriétaire et le type d'exécution sont les mêmes.

Vous pouvez obtenir le comportement souhaité en poussant les DP vers une base non générique mais en déduisant vos vues d'une classe générique pour obtenir les modèles fortement typés

public class WindowBase : Window
{
    public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
        "Header", typeof(string), typeof(WindowBase), new PropertyMetadata("No Header Name Assigned"));

    public string Header
    {
        get { return (string)GetValue(HeaderProperty); }
        protected set { SetValue(HeaderProperty, value); }
    }
}

public class WindowBase<ViewModel> : WindowBase
{
    protected ViewModel Model { get; set; }
}

Comme dans le titre, comment pouvez-vous définir une propriété de dépendance en XAML lorsque la classe de base est générique? Lorsque j'essaie de faire cela, j'obtiens une exception NullReferenceException, ce qui permet de définir correctement la propriété du code. Cela fonctionne aussi quand la classe de base n'est pas générique. J'utilise .NET4

Voici un exemple de code pour démontrer:

WindowBase.cs

using System.Windows;

namespace GenericDependencyPropertyTest
{
    public class WindowBase<ViewModel> : Window
    {
        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
        "Header", typeof(string), typeof(WindowBase<ViewModel>), new PropertyMetadata("No Header Name Assigned"));

        public string Header
        {
            get { return (string)GetValue(HeaderProperty); }
            protected set { SetValue(HeaderProperty, value); }
        }
        protected virtual ViewModel Model { get; set; }
    }
}

MainWindow.xaml

<local:WindowBase x:Class="GenericDependencyPropertyTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:GenericDependencyPropertyTest"
        x:TypeArguments="local:IMyViewModel"
        Title="MainWindow" Height="350" Width="525" Header="Test">
    <Grid>

    </Grid>
</local:WindowBase>

MainWindow.xaml.cs

namespace GenericDependencyPropertyTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : WindowBase<IMyViewModel>
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        protected override IMyViewModel Model
        {
            get
            {
                return base.Model;
            }
            set
            {
                base.Model = value;
            }
        }
    }
}

IMyViewModel.cs

namespace GenericDependencyPropertyTest
{
    public interface IMyViewModel
    {
    }
}