简体   繁体   中英

C# XAML Databinding has no effect when property is changed

Okay I've been wracking my brain a lot about this one, I'm missing something, I just can't figure out what. Ultimately I'm trying to set databinding so I can update values to be shown on the fly, but for the life of me, it's not working.

The XAML is:

<TextBox x:Name="textBox" HorizontalAlignment="Left" 
    Height="37" Margin="85,38,0,0" TextWrapping="Wrap" 
    Text="{Binding Path=TBBind}" VerticalAlignment="Top" 
    Width="121" />

Note that I have the {Binding Path=TBBind} set.

The code behind is:

using System.ComponentModel;
using System.Windows;

namespace Databinding_Practice_2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            TBBind = "test";
        }

        private string _tBBind;

        public string TBBind
        {
            get { return _tBBind; }
            set
            {
                if (value != _tBBind)
                {
                    _tBBind = value;
                    OnPropertyChanged("TBBind");
                }
            }

        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string property)
        {
            MessageBox.Show("OnPropertyChanged triggered");
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }
}

Help me obi-w.... oh wait, help me anyone!

Assuming that you are trying to use the MVVM pattern (which stands for Model-View-ViewModel):

Your MainWindow is the View.

You should create another class to be the View Model, like this:

public class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        TBBind = "test";
    }

    private string _tBBind;

    public string TBBind
    {
        get { return _tBBind; }
        set
        {
            if (value != _tBBind)
            {
                _tBBind = value;
                OnPropertyChanged("TBBind");
            }
        }

    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string property)
    {
        MessageBox.Show("OnPropertyChanged triggered");
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

Your MainWindow code behind will become like this after removing all ViewModel related stuff to the MainWindowViewModel class:

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
    }

}

Now, you should link the View with the ViewModel, there are many ways to do this. Here is one of them:

In the XAML of MainWindow, have the following inside the Window element:

<Window.DataContext>
    <wpfApplication5:MainWindowViewModel />
</Window.DataContext>

<Grid>
    <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="37" Margin="85,38,0,0" TextWrapping="Wrap" Text="{Binding TBBind}" VerticalAlignment="Top" Width="121" />
</Grid>

Please note that WpfApplication5 is the name of the namespace in my WPF project. This will probably be different in your case.

Try:

public MainWindow()
{
    InitializeComponent();
    DataContext = this;
    TBBind = "test";
}

The difference here sets the critical DataContext property. This is the cornerstone of the MVVM pattern, which you are implementing here. You should consider separating the View Model responsibility into another class, and then setting the View's DataContext to an instance of that class, but the approach you have taken here works for simple cases.

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