首页 文章

绑定简单的WPF TextBox文本TwoWay

提问于
浏览
2

我很抱歉这个问题非常基础 . 我刚刚学习了WPF,但我没有简单的双向绑定到textbox.text到string属性 .

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#代码

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);
    }
}

首先,文本框不显示“OK”,但它是空白的 . 然后,我在文本框中键入了不同的文本,例如:“blablabla”没有引号 . 然后我单击按钮检查我的str属性是否已更新 . 显然,str仍然包含“OK” .

我在这做错了什么?我错过了什么来进行装订工作?

2 回答

  • 3

    问题是,你不要绑定到Window的代码隐藏,而是绑定到DataContext .

    试试这个:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new DC();
        }
    
        public class DC
        {
            public string str { get; set; }
    
            public DC()
            {
                str = "OK";
            }
        }
    }
    

    通常,您将拥有两个不同的文件,但是对于测试,您可以在一个文件中执行此操作 . 之后,您的DC(DataContext)应该实现INotifyPropertyChanged接口 .

    试着找一些关于MVVM的文章像这样http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial

  • 4

    作为WPF的新手,所有这些Binding和DataContext爵士乐都会让人感到困惑 . 让我们先从你的绑定表达式开始......

    <TextBox Text="{Binding Path=str, Mode=TwoWay}"/>

    这是说你要将Text属性绑定到 TextBoxDataContext . DataContext 本质上是"thing"你的 TextBox 正在得到它's data from. Now here' s . 如果未明确设置, DataContext 将继承自可视树中的元素"above" . 在你的代码中, TextBoxGrid 元素继承它的 DataContext ,而后者又从 Window 元素继承它的 DataContext . 如果未在 Window 中设置 DataContext ,则将应用 DataContext 属性的默认值,即 null . DataContext 也未在窗口的任何子元素中设置,通过继承,将该窗口的所有子元素的 DataContext 设置为 null .

    请务必注意,您已在绑定表达式中省略了 Source 属性 .

    <TextBox Text="{Binding Source=left_out, Path=str, Mode=TwoWay}"/>

    省略此属性时,由于上述原因,绑定的源隐含为元素 DataContext ,在本例中为null . 基本上,你的表达式在这里说的是你想要将你的text属性绑定到 DataContext.str ,由WPF解析的是 null.str .

    好的 . 现在,我们如何将 TextBox.Text 绑定的 DataContext 设置为窗口的Code Behind,以便我们可以获得 str 属性?有几种方法可以做到这一点,但出于我们的目的,我们将专注于在 TextBox.Text 属性的绑定中明确设置它 . 现在,绑定有三种不同的"source"类型属性 . "Source"是我们想要控制/元素's binding to get it'的数据的地方 . 我们有 SourceRelativeSourceElementName . 我们在这里只关注 ElementName ,但其他的对研究和理解至关重要 .

    所以,让我们命名我们的 Window 元素,以便我们可以通过 ElementName 属性访问它 .

    <Window x:Class="WpfApplication1.MainWindow"
            x:Name="_window"
            ...
    

    现在我们可以在 TextBox.Text 绑定上设置 ElementName 属性来引用窗口 .

    <TextBox Text="{Binding ElementName=_window, Path=str, Mode=TwoWay}"/>

    这意味着绑定将在尝试解析时查找 _window.str 属性's binding. At this point, you still probably won' t,请参阅 TextBox 中反映的 str 值 . 这是因为它的值是在窗口构造函数中的 InitializeComponent 方法之后设置的 . 此功能是第一次解析绑定的位置 . 如果在调用 InitializeComponent 之前设置 str 的值,您将看到 TextBox 中反映的值 .

    这将我们带到依赖属性 . 现在,只需要知道依赖属性已内置更改通知,绑定需要它,因此当绑定发生更改时以及何时再次解析绑定值时,它会变为"knows" . 是的,您可以在后面的代码中使用 INotifyPropertyChanged ,但在这种情况下使用DependencyProperties有很好的参数,这只会混淆此时的问题 . 但是,这是另一个必须理解的事情 .

    以下是 str 属性的 DependencyProperty 代码 .

    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);}
    }
    

    现在,您将能够像这样设置值,并通过绑定反映到 TextBox .

    public MainWindow()
    {
        InitializeComponent();
        Str = "OK";
    }
    

    在这一点上,一切都应该是好的 . 我希望这会有所帮助 . 我花了一段时间才得到了WPF . 我的建议是尽可能多地阅读 DataContextBindingDependencyProperty ,因为这些是WPF的核心 . 祝好运!

相关问题