[英]Why I cannot bind a DependencyProperty to an ObservableCollection?
[英]WPF, cannot bind a property because it says it's not a DependencyProperty, but I registered it
我有一个带有Template
属性的UserControl
,它已设置为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); }
}
}
我试图在XAML中为Window
,SaveTemplateDialog使用此UserControl
,并且尝试将其Template
属性设置为SaveTemplateDialog
类中的Template
属性:
<local:TemplateDetail HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
MinWidth="100" Template="{Binding}"
Width="{Binding ElementName=Scroller, Path=ViewportWidth}"/>
SaveTemplateDialog
的DataContext
设置为其Template
属性,这也是一个依赖项属性。 但是,对于上述XAML,在Visual Studio中, Template="{Binding}"
用蓝色下划线标出,并指出:
不能在'TemplateDetail'类型的'Template'属性上设置'Binding'。 只能在DependencyObject的DependencyProperty上设置“绑定”。
果然,当我加载应用程序时,当我知道其中包含值时, TemplateDetail
尝试显示的Template
内容为空白。 如果我已经将TemplateDetail.Template
注册为依赖项属性,为什么它会显示此消息?
编辑:现在我很困惑。 在我的SaveTemplateDialog
窗口中,我正在执行以下操作以将模板传递给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
是获得正确的数据,因为我也有这个XAML中SaveTemplateDialog
,这说明我希望在价值MyType
财产NewTemplate
:
<TextBlock Text="{Binding Path=NewTemplate.MyType}" />
该TextBlock
显示了我的期望。 但是,显然正确的数据没有到达TemplateDetail
或者我在那里没有正确绑定,因为我无法获得相同的MyType
属性(或其他Template
属性)显示在TemplateDetail
。 在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”来命名属性。
更新第二个问题:
当您在TemplateDetail构造函数中设置DataContext = this
时,导致Path = NewTemplate绑定的源从继承的DataContext更改为TemplateDetail控件本身。 您应该在“输出”窗口中看到一个错误,指出在TemplateDetail类型的对象上找不到NewTemplate属性。 我通常不重设UserControl本身的DataContext,而通常给UserControl XAML中的根布局Panel一个x:Name,并在构造函数中设置LayoutRoot.DataContext = this
。
确保模板不是导致XAML处理器感到困惑的保留字。 请尝试其他单词。
(根据Sarah Vessel的建议作为答案发布)。
我认为某些事情没有得到应有的更新。 我发现,如果我在SaveTemplateDialog
窗口的NewTemplate
属性中执行了以下操作,则我的TemplateDetail
UserControl
将正确填充我期望的所有数据:
public Template NewTemplate
{
get
{
return (Template)GetValue(NewTemplateProperty);
}
set
{
SetValue(NewTemplateProperty, value);
// The magic line, explicitly setting TemplateData property on
// the TemplateDetails UserControl:
uct_templateDetails.TemplateData = value;
}
}
这使我相信,只是有下面SaveTemplateDialog
的XAML是不够的,新的实例发送到TemplateDetails
每当NewTemplate
被更新:
<local:TemplateDetail HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
TemplateData="{Binding Path=NewTemplate}" Grid.Row="2"
Grid.Column="1" Grid.ColumnSpan="3"
x:Name="uct_templateDetails"/>
我希望有人指出我在这里做错了什么,因为看来我不必明确地说uct_templateDetails.TemplateData = value;
每当SaveTemplateDialog.NewTemplate
更改时。 我以为那是依赖项属性的关键所在,即更新它会导致使用它获取更新值的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.