wpf:从视图模型中更改依赖项属性的值
我有一个自定义的用户控件,其中包含一个类型为字符串的自定义依赖项属性。应结合双向的文本框,这是一个周围的应用,如:wpf:从视图模型中更改依赖项属性的值
<Textbox Name="TextBoxInHostApp"/>
<ctrl:MyControl
....
MyString = "{Binding ElementName=TextBoxInHostApp, Path=Text, Mode=TwoWay}"
</ctrl:MyControl>
问题:
控制应该具备的功能,揭示了依赖属性也值了!
在MyControl中,我有一个简单的字符串属性“Name”,它应该更新MyString的dependeny属性值。
所以通常情况下,如果MyString的是没有绑定到外面的世界,你会在XAML使用控制,其中代码:
<Textbox Name="TextBoxInHostApp"/>
<ctrl:MyControl
....
MyString = "{Binding Name}"
</ctrl:MyControl>
但是,这不是可以在我的情况。
尝试1: 我使用的用户控件XAML内触发:
<UserControl.Style>
<Style>
<Style.Setters>
<Setter Property="local:MyControl.MyString" Value="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
</Style.Setters>
</Style>
现在这个触发器不起作用,因为DP的“本地值”已被设置在这里:
MyString = "{Binding ...
如果我注释掉:
<!--<MyString = "{Binding ...
...触发正常工作,因为“L ocal值“未设置。
下一个尝试: 我尝试在MyControls视图模型硬盘的方式和代码:
public string Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged("Name");
MyOwningUICtrl.SetValue(MyControl.MyStringProperty, value); // ??
}
}
我必须通过的DependencyObject调用的SetValue,这是不愉快的MVVM。这种情况必须有更好的解决方案吗?
这是由设计
每WPF的Dependency Property Precedence List,价值观当地指定的<Tag>
内将始终优先于一个Style
或Trigger
一个共同的问题规定值的设定值在<Tag>
,然后试图改变它在Style.Trigger
。解决的办法是设置默认值作为<Style>
,而不是在一个<Tag>
<Setter>
,那么这将使触发值优先于样式值
<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>
但我没有真正看到一个触发器在你的帖子中定义的任何地方,所以我不确定这是否是你的问题。
我对代码的确切结构有点不清楚,但请记住,依赖属性有点像指向另一个值的指针。您可以将其设置为指向TextBox.Text
,或指向DataContext.Name
,但不能同时指向两者。
如果你想设置两个TextBox.Text
和MyUserControl.MyString
指向DataContext.Name
,那么你就应该既属性绑定到"{Binding Name}"
像Natxo suggests。
或者,如果你想,如果在<ctrl:MyControl ...>
标签没有指定MyString
是绑定MyString
到UserControl.Name
,那么你可以尝试使用PriorityBinding(例如here),或者只是暴露Name
属性外界要让外部因素使用控制如<ctrl:MyControl Name="{Binding ...}" />
如果在Textbox和Mycontrol中都显示相同的值...为什么不把它们绑定到该属性? :
<Textbox Name="TextBoxInHostApp" Text="{Binding Name}"/>
<ctrl:MyControl
....
MyString="{Binding Name}"
</ctrl:MyControl>
这一点是应用程序无法访问“名称”属性。由文本框表示的应用程序字符串应该通过“MyString”dp修改usercontrols,“名称”设置在“MyString”内 - ChangedCallback在这里不相关。事情是“Name”允许修改“ MyString“dp等,如果控件内部的”Name“发生变化,应用程序文本框中的文本也会发生变化 – deafjeff 2013-03-25 15:02:13
1st)您的权利,我使用的是样式设置器,而不是触发器2)textbox.text应该是绑定到MyString dp的属性,设计的实际情况是,dp的值可以通过两种方式进行更改:从应用程序布局上的文本框和自定义控件中的文本框中进行更改 – deafjeff 2013-03-25 15:21:29
非智能解决方案我刚测试:MyOwningUICtrl.SetValue(MyControl.MyStringProperty,value); // ?? ...工作正常,但它不是很好的编程我认为 – deafjeff 2013-03-25 15:23:46
@deafjeff请记住,绑定就像指针 - 它们指向一个值在'DataContext'中,听起来像y ou希望你的'MyString'依赖属性指向'UserControl'之外的某个值(比如'{Binding Name}',并且你希望'TextBox.Text'指向'UserControl.MyString'。所以你的最终结果是' '和' ''' –
Rachel
2013-03-25 15:39:14