wpf WPF中的双向绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/320028/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Two-way binding in WPF
提问by evizaer
I cannot get a two-way bind in WPF to work.
我无法在 WPF 中进行双向绑定工作。
I have a string property in my app's main window that is bound to a TextBox (I set the mode to "TwoWay").
我的应用程序主窗口中有一个字符串属性,它绑定到一个 TextBox(我将模式设置为“TwoWay”)。
The only time that the value of the TextBox will update is when the window initializes.
只有在窗口初始化时才会更新 TextBox 的值。
When I type into the TextBox, the underlying string properties value does not change.
当我在 TextBox 中键入时,底层字符串属性值不会改变。
When the string property's value is changed by an external source (an event on Click, for example, that just resets the TextBox's value), the change doesn't propagate up to the TextBox.
当字符串属性的值被外部源更改时(例如,Click 上的事件,它只是重置了 TextBox 的值),更改不会传播到 TextBox。
What are the steps that I must implement to get two-way binding to work properly in even this almost trivial example?
即使在这个几乎微不足道的例子中,我必须执行哪些步骤才能使双向绑定正常工作?
回答by Gishu
Most probably you're trying to bind to a .net CLR property instead of a WPF dependencyProperty (which provides Change Notification in addition to some other things).
For normal CLR property, you'd need to implement INotifyPropertyChanged and force update on the textbox in the event handler for PropertyChanged.
很可能您正在尝试绑定到 .net CLR 属性而不是 WPF dependencyProperty(除了其他一些东西之外,它还提供更改通知)。
对于普通的 CLR 属性,您需要实现 INotifyPropertyChanged 并强制更新 PropertyChanged 事件处理程序中的文本框。
- So make your object with the property implement this interface, raise the event in the property setter. (So now we have property change notification)
- Make sure the object is set as the DataContext property of the UI element/control
- 所以让你的带有属性的对象实现这个接口,在属性设置器中引发事件。(所以现在我们有属性更改通知)
- 确保对象设置为 UI 元素/控件的 DataContext 属性
This threw me off too when I started learning about WPF data binding.
当我开始学习 WPF 数据绑定时,这也让我失望。
Update:Well OP, it would have been a waste of time if i was barking up the wrong tree.. anyways now since you had to dig a bit.. you'll remember it for a long time.Here's the code snippet to round off this answer. Also found that updating the textbox happens automatically as soon as I tab-out.. You only need to manually subscribe to the event and update the UI if your datacontext object is not the one implementing INotifyPropertyChanged.
更新:好吧,如果我在错误的树上吠叫,那将是浪费时间..反正现在因为你不得不挖一点..你会记得很长时间。这是完善这个答案的代码片段。还发现更新文本框会在我退出时自动发生。如果您的 datacontext 对象不是实现 INotifyPropertyChanged 的对象,您只需要手动订阅事件并更新 UI。
MyWindow.xaml
我的窗口.xaml
<Window x:Class="DataBinding.MyWindow" ...
Title="MyWindow" Height="300" Width="300">
<StackPanel x:Name="TopLevelContainer">
<TextBox x:Name="txtValue" Background="AliceBlue" Text="{Binding Path=MyDotNetProperty}" />
<TextBlock TextWrapping="Wrap">We're twin blue boxes bound to the same property.</TextBlock>
<TextBox x:Name="txtValue2" Background="AliceBlue" Text="{Binding Path=MyDotNetProperty}" />
</StackPanel>
</Window>
MyWindow.xaml.cs
我的窗口.xaml.cs
public partial class MyWindow : Window, INotifyPropertyChanged
{
public MyWindow()
{
InitializeComponent();
this.MyDotNetProperty = "Go ahead. Change my value.";
TopLevelContainer.DataContext = this;
}
private string m_sValue;
public string MyDotNetProperty
{
get { return m_sValue; }
set
{
m_sValue = value;
if (null != this.PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs("MyDotNetProperty"));
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
回答by flamandier
I feel the need to add some precision:
我觉得有必要增加一些精度:
"Two ways" data binding is more than "One way" data binding.
“两种方式”数据绑定不仅仅是“一种方式”数据绑定。
"One way" data binding is a binding from a source to a depency property . The source must implement INotifyProertyChanged, in order to get change propagation from source to target.
“单向”数据绑定是从源到依赖属性的绑定。源必须实现 INotifyProertyChanged,以便获得从源到目标的更改传播。
To get the " 2 way" , so to get a propagation from Target to Source, it depends on the binding mode which you set on the Binding . If you don't set any BindingMode for your binding, the default Binding mode will be used, and this default mode is a characteristics fo your target Dependency Property.
要获得“2 种方式”,从而获得从 Target 到 Source 的传播,这取决于您在 Binding 上设置的绑定模式。如果您没有为您的绑定设置任何 BindingMode,则将使用默认的 Binding 模式,并且此默认模式是您的目标依赖属性的一个特征。
Example:
例子:
A Textbox bound to a string property, called "MyTextProperty". In the code , you bind Textbox.Text DependencyProperty to "MyTextProperty" on object "MyObject"
绑定到名为“MyTextProperty”的字符串属性的文本框。在代码中,您将 Textbox.Text DependencyProperty 绑定到对象“MyObject”上的“MyTextProperty”
--> "one way" binding : the setter of "My TextProperty" must raise an event Property Changed,and "MyObject" must implement INotifyPropertyChanged.
-->“单向”绑定:“My TextProperty”的setter必须引发一个事件Property Changed,而“MyObject”必须实现INotifyPropertyChanged。
--> "2 ways data binding": in addition to what is needed for "One way", bindingMode must be set to "2 ways". In this special case, the Text DependencyProperty for Textbox does have "2 ways" as default mode, so there is nothing else to do !
--> “2 种方式数据绑定”:除了“一种方式”所需要的,bindingMode 必须设置为“2 种方式”。在这种特殊情况下,Textbox 的 Text DependencyProperty 确实有“2 种方式”作为默认模式,因此没有其他事情可做!
回答by Matt Hamilton
We might need to see the code. Does your string property raise a PropertyChanged event? Or (even better) is it implemented as a DependencyProperty? If not, the bound TextBox won't know when the value changes.
我们可能需要查看代码。您的字符串属性是否引发了 PropertyChanged 事件?或者(甚至更好)它是作为 DependencyProperty 实现的吗?如果没有,绑定的 TextBox 将不知道值何时发生变化。
As for typing into the TextBox and not seeing the property's value change, that may be because your TextBox isn't losing focus. By default, bound TextBoxes don't write their values back to the source property until focus leaves the control. Try tabbing out of it and seeing if the property value changes.
至于在 TextBox 中输入但没有看到属性值发生变化,那可能是因为您的 TextBox 没有失去焦点。默认情况下,在焦点离开控件之前,绑定的 TextBox 不会将它们的值写回源属性。尝试跳出它并查看属性值是否发生变化。