WPF,无法绑定属性,因为它说它不是DependencyProperty,但是我注册了它 [英] WPF, cannot bind a property because it says it's not a DependencyProperty, but I registered it

查看:475
本文介绍了WPF,无法绑定属性,因为它说它不是DependencyProperty,但是我注册了它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 UserControl 和一个 Template 属性,我将该属性设置为 DependencyProperty

I have a UserControl with a Template property that I've set up as a DependencyProperty:

public partial class TemplateDetail : UserControl
{
    public static readonly DependencyProperty _templateProperty =
        DependencyProperty.Register(
            "Template",
            typeof(Template),
            typeof(TemplateDetail)
        );

    public TemplateDetail()
    {
        InitializeComponent();
        Template = new Template();
        DataContext = Template;
    }

    public Template Template
    {
        get
        {
            return (Template)GetValue(_templateProperty);
        }
        set { SetValue(_templateProperty, value); }
    }
}

我正在尝试使用此<$ c XAML中$ c> UserControl 的 Window SaveTemplateDialog,而我正在尝试设置其 Template SaveTemplateDialog 类中的 Template 属性的code>属性:

I'm trying to use this UserControl in the XAML for a Window, SaveTemplateDialog, and I'm trying to set its Template property to the Template property in my SaveTemplateDialog class:

<local:TemplateDetail HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                      MinWidth="100" Template="{Binding}"
                      Width="{Binding ElementName=Scroller, Path=ViewportWidth}"/>

DataContext > SaveTemplateDialog 设置为其 Template 属性,该属性也是依赖项属性。但是,对于上面的XAML,在Visual Studio中, Template = {Binding} 用蓝色下划线标出:

The DataContext in SaveTemplateDialog is set to its Template property, which is also a dependency property. However, for the XAML above, Template="{Binding}" is underlined in blue in Visual Studio and it says:


不能在'TemplateDetail'类型的'Template'属性上设置'Binding'。只能在DependencyObject的DependencyProperty上设置绑定。

A 'Binding' cannot be set on the 'Template' property of type 'TemplateDetail'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

当然,当我加载应用程序时,当我知道其中包含值时, TemplateDetail 尝试显示的 Template 为空白。如果我已经将 TemplateDetail.Template 注册为依赖项属性,为什么会显示此消息?

Sure enough, when I load my app, the contents of the Template that TemplateDetail tries to display is blank, when I know there are values in it. Why does it give this message if I've registered TemplateDetail.Template as a dependency property?

编辑:现在我很困惑。在我的 SaveTemplateDialog 窗口中,我正在执行以下操作以将模板传递到 TemplateDetail UserControl

now I'm quite confused. In my SaveTemplateDialog window, I'm doing the following to pass along the template to the TemplateDetail UserControl:

<local:TemplateDetail HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                      TemplateData="{Binding Path=NewTemplate, Mode=OneWay}"
                      Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3"/>

我知道 Path = NewTemplate 正在获取正确的数据,因为我在 SaveTemplateDialog 中也有此XAML,它显示了我期望的 MyType 属性中的值code> NewTemplate :

I know Path=NewTemplate is getting the right data because I also have this XAML in SaveTemplateDialog, which shows the value I would expect in the MyType property of NewTemplate:

<TextBlock Text="{Binding Path=NewTemplate.MyType}" />

TextBlock 显示了我的期望。但是,显然正确的数据没有到达 TemplateDetail ,或者我在那里没有正确绑定,因为我无法获得相同的 MyType 属性(或其他 Template 属性)显示在 TemplateDetail 中。在 TemplateDetail 中:

That TextBlock shows what I expect. However, apparently the right data is not getting to TemplateDetail or I'm not binding correctly there, because I can't get that same MyType property (or the other Template properties) to show up in TemplateDetail. In TemplateDetail:

<TextBlock Text="{Binding Path=TemplateData.MyType}" Grid.Row="2" Grid.Column="2"
           HorizontalAlignment="Stretch" Width="200"/>

这是 TemplateDetail 类现在:

public partial class TemplateDetail : MainWindowUserControl
{
    public static readonly DependencyProperty TemplateDataProperty =
        DependencyProperty.Register(
            "TemplateData",
            typeof(Template),
            typeof(TemplateDetail),
            new PropertyMetadata(
                new Template("Default Template", null)
            )
        );

    public TemplateDetail()
    {
        InitializeComponent();
        DataContext = this;
    }

    public Template TemplateData
    {
        get
        {
            return (Template)GetValue(TemplateDataProperty);
        }
        set { SetValue(TemplateDataProperty, value); }
    }
}


推荐答案

您应该将DependencyProperty的名称更改为使用诸如PropertyNameProperty之类的标准约定,而不是像字段一样命名。在XAML中设置内容时,它将调用SetValue并期望使用字符串名称(此处为 Template)和 Property来命名属性。

You should change the name of your DependencyProperty to the use the standard convention like PropertyNameProperty instead of naming like a field. When you set something in XAML it calls SetValue and expects the property to be named using the string name ("Template" here) followed by "Property".

UPDATE (第二个问题):

在您的TemplateDetail构造函数中设置 DataContext = this 时,将Path = NewTemplate绑定的源从继承的DataContext更改为TemplateDetail控件本身。您应该在输出窗口中看到一个错误,指出在TemplateDetail类型的对象上找不到NewT​​emplate属性。我通常不重设UserControl本身的DataContext,而是给UserControl XAML中的根布局面板一个x:Name并在构造函数中设置 LayoutRoot.DataContext = this

When you set DataContext = this in your TemplateDetail constructor that is causing the source for your Path=NewTemplate Binding to be changed from the inherited DataContext to the TemplateDetail control itself. You should be seeing an error in your Output window that the NewTemplate property can't be found on the object of type TemplateDetail. Instead of resetting the DataContext of the UserControl itself, I will usually give the root layout Panel in my UserControl XAML an x:Name and set LayoutRoot.DataContext = this in the constructor instead.

这篇关于WPF,无法绑定属性,因为它说它不是DependencyProperty,但是我注册了它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆