WPF Simple Binding to INotifyPropertyChanged Object
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; }
...
}
orberkov
Updated on August 01, 2020Comments
-
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 almost 11 yearsThe 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}" />
. TheDataContext="MainWindow"
remains. Thank you! -
dkozl almost 11 years@orberkov but
DataContext="MainWindow"
dose not setDataContext
to an instance ofMainWindow
but to a string which value is MainWindow -
Robert Jørgensgaard Engdahl over 9 years@dkozl but
DataContext="MainWindow"
setsDataContext
to something namedMainWindow
in the resulting CLR object. And since the<Window>
hasx:Name="MainWindow"
, theDataContext
is set to equal the CLR object itself. This is whyPath
ends up referencing the right property. (sorry for the 2 years delay, but noone seem to have addressed this comment) -
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 tox:Name="MainWindow"
control andDataContext="{StaticResource MainWindow}"
will set it tox:Key="MainWindow"
resource. You can check it in debugger. Besides I can have both resource and control called MainWindow.