简体   繁体   中英

WPF control binding to a single variable

I can't seem to bind a control's value to an object. I want to bind a TextBox to a string object, the idea is that when textbox's text changes, it should automatically change the object as well. couldn't figure out what I'm doing wrong. Here is what I have tried:

MainWindow.xaml.cs:

public partial class MainWindow : Window
    {
        string str;
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = str;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {

    }
}

and MainWindow.xaml:

<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="150" Width="150">
    <Grid Margin="0,0,642,319">
        <TextBox HorizontalAlignment="Left" Height="23"  TextWrapping="Wrap" Text="{Binding str}" VerticalAlignment="Top" Width="120" Margin="0,0,-120,-46" />
        <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Button_Click" Height="23" Margin="0,28,-75,-51" RenderTransformOrigin="0.423,2.257" />

    </Grid>
</Window>

So, when I enter something to the textbox and click the button, I should see the text in str while debugging but it is always null

  1. Change the str to a auto property:

    public string str { get; set; }

  2. Change the DataContext to:

    DataContext = this;

The DataContext is the class which will hold your binding properties/commands/events. The properties/commands/events need to be public in order to be accessible by your view.

For the two-way binding to work, you have to notify to the UI binding that the property has been changed and for that you need to implement the INotifyPropertyChanged interface for the class which holds the properties which have been bound in the UI. You will need a private property and you cannot notify from a auto-property.

Simple Example:

public class Sample : INotifyPropertyChanged
{
    private string _str;
    public string Str
    {
        get { return _str; }
        set
        {
            _str = value;
            NotifyPropertyChanged(nameof(Str));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

First, data bindings in WPF only work with public properties. So you must explicitely declare one in your code behind (instead of string str; )

public string str { get; set; }

Second, the DataContext property of a view defines the object / class in which the property will be searched for the bindings. The line this.DataContext = str; in your example means that you want your bindings in the view to be looked for inside the str object (which is a string ). You should replace this line by

this.DataContext = this;

so that the bindings will be searched inside the code behind of this view itself.

Remark You could also stay with the line this.DataContext = str; if str is a public property and bind using an expression such as

<TextBox Text="{Binding .}" />

which will bind to the value of the DataContext property.

也许您可以使用MVVM light进行绑定。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM