WPF Simple Binding to INotifyPropertyChanged Object

32,032

First of all remove DataContext="MainWindow" as this sets DataContext of a Window to a string MainWindow, then you specify ElementName for your binding which defines binding source as another control with x:Name="TheBook" which does not exist in your Window. You can make your code work by removing ElementName=TheBook from your binding and either by assigning DataContext, which is default source if none is specified, of a Window to TheBook

public SimpleBinding()
{
    ...
    this.DataContext = TheBook;
} 

or by specifying RelativeSource of your binding to the Window which exposes TheBook:

<TextBox Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=TheBook.BookName}"/>

but since you cannot bind to fields you will need to convert TheBook into property:

public partial class SimpleBinding : Window
{
    public Book TheBook { get; set; }
    ...
}
Share:
32,032
orberkov
Author by

orberkov

Updated on August 01, 2020

Comments

  • orberkov
    orberkov almost 4 years

    I've created the simplest binding. A textbox bound to an object in the code behind.

    Event though - the textbox remains empty.

    The window's DataContext is set, and the binding path is present.

    Can you say what's wrong?

    XAML

    <Window x:Class="Anecdotes.SimpleBinding"
            x:Name="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="SimpleBinding" Height="300" Width="300" DataContext="MainWindow">
        <Grid>
            <TextBox Text="{Binding Path=BookName, ElementName=TheBook}" />
        </Grid>
    </Window>
    

    Code behind

       public partial class SimpleBinding : Window
        {
            public Book TheBook;
    
            public SimpleBinding()
            {
                TheBook = new Book() { BookName = "The Mythical Man Month" };
                InitializeComponent();
            }
        }
    

    The book object

    public class Book : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
    
        }
    
        private string bookName;
    
        public string BookName
        {
            get { return bookName; }
            set
            {
                if (bookName != value)
                {
                    bookName = value;
                    OnPropertyChanged("BookName");
                }
            }
        }
    }
    
  • orberkov
    orberkov almost 11 years
    The main issue was: "You cannot bind to fields you will need to convert TheBook into property". In the XAML i fixed the TextBox binding like this: <TextBox Text="{Binding Path=TheBook.BookName}" />. The DataContext="MainWindow" remains. Thank you!
  • dkozl
    dkozl almost 11 years
    @orberkov but DataContext="MainWindow" dose not set DataContext to an instance of MainWindow but to a string which value is MainWindow
  • Robert Jørgensgaard Engdahl
    Robert Jørgensgaard Engdahl over 9 years
    @dkozl but DataContext="MainWindow" sets DataContext to something named MainWindow in the resulting CLR object. And since the <Window> has x:Name="MainWindow", the DataContext is set to equal the CLR object itself. This is why Path ends up referencing the right property. (sorry for the 2 years delay, but noone seem to have addressed this comment)
  • dkozl
    dkozl over 9 years
    @RobertJørgensgaardEngdahl no it doesn't mean that. DataContext="MainWindow" will set it to MainWindow string and nothing more. DataContext="{Binding ElementName=MainWindow}" will bind it to x:Name="MainWindow" control and DataContext="{StaticResource MainWindow}" will set it to x:Key="MainWindow" resource. You can check it in debugger. Besides I can have both resource and control called MainWindow.