绑定简单的 WPF TextBox 文本 TwoWay
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39063172/
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
Binding Simple WPF TextBox Text TwoWay
提问by kurakura88
I am very sorry that this question is very basic. I just learned WPF and I failed to make simple two way binding to textbox.text to string property.
我很抱歉这个问题非常基础。我刚刚学习了 WPF,但未能对 textbox.text 和 string 属性进行简单的双向绑定。
XAML Code:
XAML 代码:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="StuInfo">
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="10,26,0,0" TextWrapping="Wrap" Text="{Binding Path=str,Mode=TwoWay}" VerticalAlignment="Top" Width="120"/>
<Button x:Name="button" Content="Check" HorizontalAlignment="Left" Margin="10,67,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
</Grid>
C# Code
C# 代码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
str = "OK";
}
public string str { get; set; }
private void button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine(str);
}
}
First, the textbox does not show "OK", but it is blank. Then, I typed a different text into the textbox, for ex:"blablabla" without the quotes. Then I click the button to check if my str property has been updated. Apparently, str still contains "OK".
首先,文本框不显示“OK”,而是空白。然后,我在文本框中输入了一个不同的文本,例如:"blablabla" 不带引号。然后我单击按钮检查我的 str 属性是否已更新。显然, str 仍然包含“OK”。
What did I do wrong here? What did I miss to make the binding work?
我在这里做错了什么?我错过了什么使绑定工作?
采纳答案by Jakub ?ermoch
The problem is that, you dont bind to codebehind of Window, but to DataContext.
问题是,您没有绑定到 Window 的代码隐藏,而是绑定到 DataContext。
Try this:
尝试这个:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new DC();
}
public class DC
{
public string str { get; set; }
public DC()
{
str = "OK";
}
}
}
Normally, you would have two different files, but for test, you can do it in one file. After that, your DC (DataContext) should implement INotifyPropertyChanged interface.
通常,您会有两个不同的文件,但为了测试,您可以在一个文件中进行。之后,您的 DC (DataContext) 应该实现 INotifyPropertyChanged 接口。
Try to find some article about MVVM like this http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial
尝试找到一些关于 MVVM 的文章,如http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial
回答by John Stritenberger
As a newcomer to WPF, all this Binding and DataContext jazz can be quite confusing. Let's start with your binding expression first...
作为 WPF 的新手,所有这些 Binding 和 DataContext 爵士乐都可能令人困惑。让我们先从你的绑定表达式开始......
<TextBox Text="{Binding Path=str, Mode=TwoWay}"/>
<TextBox Text="{Binding Path=str, Mode=TwoWay}"/>
What this is saying is that you want to bind your Text property to whatever the DataContextof the TextBoxis. DataContextis essentially the "thing" your TextBoxis getting it's data from. Now here's the rub. DataContextis inherited from the element "above" it in the visual tree if not explicitly set. In your code, TextBoxinherits it's DataContextfrom the Gridelement, which in turn inherits it's DataContextfrom the Windowelement. Seeing that DataContextis not set in your Windowthe default value of the DataContextproperty will be applied, which is null. The DataContextis also not set in any of the child elements of your window, which, via inheritance, will set the DataContextof all children of that window to null.
这是什么要说的是,你想你的Text属性绑定到无论DataContext的TextBox是。DataContext本质上是您TextBox从中获取数据的“事物” 。现在问题来了。DataContext如果未明确设置,则从可视化树中它“上方”的元素继承。在你的代码,TextBox继承了它DataContext从Grid元素,这反过来又继承它DataContext从Window元素。看到DataContext未在您Window的DataContext属性中设置的默认值将被应用,即null. 在DataContext还没有在任何你的窗口的子元素,其中,通过继承,将设置的设置DataContext该窗口的所有儿童null。
It is important to note that you've left out the Sourceproperty in your binding expression.
请务必注意,您Source在绑定表达式中遗漏了该属性。
<TextBox Text="{Binding Source=left_out, Path=str, Mode=TwoWay}"/>
<TextBox Text="{Binding Source=left_out, Path=str, Mode=TwoWay}"/>
When this property is left out, the binding's source is implied to be the elements DataContext, which in this case is null, for the reasons mentioned above. Basically, what your expression is saying here is that you want to bind your text property to DataContext.strwhich resolved by WPF is null.str.
当这个属性被忽略时,绑定的源被暗示为元素DataContext,在这种情况下为空,原因如上所述。基本上,您的表达式在这里说的是您希望将DataContext.strWPF 解析的文本属性绑定到null.str.
OK, cool. Now, how do we set the DataContextof your TextBox.Textbinding to the Code Behind for the window so we can get at that strproperty? There are several ways to do this, but for our purposes we'll focus on setting it explicitly in the binding of the TextBox.Textproperty. Now, there are three different "source" type properties of bindings. "Source" being where we want our control/element's binding to get it's data from. We have Source, RelativeSource, and ElementName. We're only going to focus on ElementNamehere, but the others are essential to research and understand.
嗯不错。现在,我们如何将DataContext您的TextBox.Text绑定设置为窗口的隐藏代码,以便我们可以获取该str属性?有几种方法可以做到这一点,但出于我们的目的,我们将重点关注在TextBox.Text属性绑定中显式设置它。现在,绑定有三个不同的“源”类型属性。“源”是我们希望控件/元素的绑定从中获取数据的地方。我们有Source, RelativeSource, 和ElementName。我们只关注ElementName这里,但其他的对于研究和理解是必不可少的。
So, let's name our Windowelement so we can access it through the ElementNameproperty.
所以,让我们命名我们的Window元素,以便我们可以通过ElementName属性访问它。
<Window x:Class="WpfApplication1.MainWindow"
x:Name="_window"
...
Now we can set the ElementNameproperty on the TextBox.Textbinding to refer to the window.
现在我们可以ElementName在TextBox.Text绑定上设置属性来引用窗口。
<TextBox Text="{Binding ElementName=_window, Path=str, Mode=TwoWay}"/>
<TextBox Text="{Binding ElementName=_window, Path=str, Mode=TwoWay}"/>
This means the binding will look for the _window.strproperty when trying to resolve it's binding. At this point, you still probably won't see your strvalue reflected in the TextBox. This is because it's value is set after the InitializeComponentmethod in the window's constructor. This function is where bindings are resolved for the first time. If you were to set the value of strbefore calling InitializeComponent, you would see the value reflected in the TextBox.
这意味着绑定将_window.str在尝试解析其绑定时查找该属性。此时,您可能仍然看不到您的str价值反映在TextBox. 这是因为它的值是InitializeComponent在窗口构造函数中的方法之后设置的。这个函数是第一次解决绑定的地方。如果您str在调用之前设置 的值InitializeComponent,您将看到该值反映在TextBox.
This brings us to Dependency Properties. For now, just know that Dependency Properties have built in change notification, which your binding needs so it "knows" when the binding has changed and when to resolve the binding value again. Yes, you could use INotifyPropertyChangedin your code behind, but there are good arguments for using DependencyProperties in this case, which will only confuse the issue at this point. But, it is another one of those things that is essential to understand.
这将我们带到了依赖属性。现在,只知道依赖属性内置了更改通知,您的绑定需要它,以便它“知道”绑定何时更改以及何时再次解析绑定值。是的,您可以INotifyPropertyChanged在后面的代码中使用,但在这种情况下使用 DependencyProperties 有很好的论据,这只会在此时混淆问题。但是,这是理解必不可少的另一件事。
Here is the code for a DependencyPropertyfor your strproperty.
这是DependencyProperty您的str财产的代码。
public static readonly DependencyProperty StrProperty
= DependencyProperty.Register("Str", typeof(string), typeof(MainWindow),
new FrameworkPropertyMetadata(FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string Str
{
get{return (string)GetValue(StrProperty);}
set{SetValue(StrProperty,value);}
}
Now you'll be able to set the value like such and have it reflect through the binding to your TextBox.
现在,您将能够像这样设置值,并通过绑定反映到您的TextBox.
public MainWindow()
{
InitializeComponent();
Str = "OK";
}
At this point, all should be well. I hope this helps out. It took me a while get the hang of WPF. My suggestion would be to read as much as you can on DataContext, Binding, and DependencyPropertyas these are the core of WPF. Good luck!
在这一点上,一切都应该很好。我希望这会有所帮助。我花了一段时间才掌握 WPF。我的建议是尽可能多地阅读DataContext、Binding,DependencyProperty因为这些是 WPF 的核心。祝你好运!

