当基类是通用的时,在XAML中设置依赖项属性

Chr*_*Way 5 c# generics wpf xaml .net-4.0

实际上,根据标题,当基类是通用的时,如何在XAML中设置依赖属性?当我尝试这样做时,我得到一个NullReferenceException,从后面的代码设置属性工作正常.它也适用于基类不通用的情况.我正在使用.NET4

以下是一些示例代码:

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

IMyViewModel.cs

namespace GenericDependencyPropertyTest
{
    public interface IMyViewModel
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

JRo*_*han 8

我的猜测是问题在于依赖属性的所有者类型(typeof(WindowBase <ViewModel>).每个封闭的泛型类型将是一个完全不同的运行时类型,因此当编译器很高兴该属性存在时,WPF运行时可以'当它看起来属性与其内部存储中的(不同)类型相反时找到它.

如您所见,非泛型类的工作原理是因为所有者类型和运行时类型相同.

您可以通过将DP推送到非通用基础来获得所需的行为,但仍然从泛型类派生您的视图以获得强类型模型

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; }
}
Run Code Online (Sandbox Code Playgroud)