我有一个自定义usercontrol,其自定义依赖项属性为string类型。它应该被绑定到文本框中,文本框位于周围的应用程序中,如下所示:
<Textbox Name="TextBoxInHostApp"/>
<ctrl:MyControl
....
MyString = "{Binding ElementName=TextBoxInHostApp, Path=Text, Mode=TwoWay}"
</ctrl:MyControl>
问题:
Control应具有显示依赖属性值的功能!
在MyControl中,我有一个简单的字符串属性“Name”,它应该更新MyString dependeny属性值。
通常情况下,如果MyString没有绑定到外部世界,您将在使用控件的xaml中进行编码:
<Textbox Name="TextBoxInHostApp"/>
<ctrl:MyControl
....
MyString = "{Binding Name}"
</ctrl:MyControl>
但是我的情况并不适用。
尝试1: 我在usercontrol xaml中使用了一个触发器:
<UserControl.Style>
<Style>
<Style.Setters>
<Setter Property="local:MyControl.MyString" Value="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
</Style.Setters>
</Style>
现在这个触发器不起作用,因为dp的“本地值”已在此处设置:
MyString = "{Binding ...
如果我发表评论:
<!--<MyString = "{Binding ...
...触发器工作正常,因为未设置“本地值”。
下次尝试: 我在MyControls viewmodel中尝试了很难的方法和代码:
public string Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged("Name");
MyOwningUICtrl.SetValue(MyControl.MyStringProperty, value); // ??
}
}
我必须传递DependencyObject来调用SetValue,这对MVVM来说是不愉快的。这种情况必须有更好的解决方案吗?
答案 0 :(得分:3)
这是设计
根据WPF的Dependency Property Precedence List,<Tag>
内本地指定的值始终优先于Style
或Trigger
常见问题是在<Tag>
中设置值,然后尝试在Style.Trigger
中更改它。解决方案是在<Setter>
而不是<Style>
中将默认值设置为<Tag>
,然后允许触发值优先于样式值
<Style>
<!-- Default Value
<Setter Property="local:MyControl.MyString"
Value="{Binding ElementName=TextBoxInHostApp, Path=Text, Mode=TwoWay}"/>
<Style.Triggers>
<Trigger ...>
<!-- Triggered Value -->
<Setter Property="local:MyControl.MyString"
Value="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
</Trigger>
</Style.Setters>
</Style>
但我实际上并没有在你的帖子中看到任何定义的Trigger,所以我不确定这是不是你的问题。
我对代码的确切结构有点不清楚,但请记住,依赖属性有点像指向另一个值的指针。您可以将其设置为指向TextBox.Text
,或指向DataContext.Name
,但不能指向两者。
如果您要将TextBox.Text
和MyUserControl.MyString
设置为指向DataContext.Name
,则应将这两个属性绑定到"{Binding Name}"
,如Natxo suggests。
如果您在MyString
标记中未指定UserControl.Name
时尝试将MyString
绑定到<ctrl:MyControl ...>
,则可以尝试使用PriorityBinding (示例here),或者只是将Name
属性公开给外界,让外部元素使用控件,如<ctrl:MyControl Name="{Binding ...}" />
答案 1 :(得分:1)
如果你在Textbox和Mycontrol中同时显示相同的值...为什么不将它们绑定到该属性? :
<Textbox Name="TextBoxInHostApp" Text="{Binding Name}"/>
<ctrl:MyControl
....
MyString="{Binding Name}"
</ctrl:MyControl>