Binding WPF element to an object






When binding a WPF element to another WPF element you can use the ElementName property. But when binding to an Object you use the Source property instead. You don’t need to set the source in the element itself. If source isn’t set the system searches for a source set for the DataContext property further up in the visual tree. In the example you can see how it works.

In this example I’ve created an object in the Window.Resources section and refer to that one in the DataContext parameter. Pay attention to the namespace local that’s being created on line 4.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="464" Width="584">
  <Window.Resources>
    <local:Customer x:Key="myCustomer" />
  </Window.Resources>
  <Grid DataContext="{StaticResource myCustomer}">
    <TextBox Width="200" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" 
	Margin="80,10,0,0" Text="{Binding Path=name}" />
    <TextBox Width="200" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" 
	Margin="80,40,0,0" Text="{Binding Path=age}" />
  </Grid>
</Window>

Sometimes you wan’t to set the source dynamically in the code instead and then you just omit the source in the XAML but keep the Binding part.

For all the following examples here I use a simple little data class named Customer.

class Customer
{
  public string name { get; set; }
  public int age { get; set; }
  public Customer()
  {
    name = "Johan";
    age = 34;
  }
}







In this code there is no Source or DataContext because it’ll be set further down. Note that the grid needs a name to be set from the code. We have also set binding mode to TwoWay so the text boxes will be update if the Customer class is updated.

<Grid Name="Grid1">
  <TextBox Name="customerName" Width="200" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" 
	Margin="80,10,0,0" Text="{Binding Path=name, Mode=TwoWay}" />
  <TextBox Name="customerAge" Width="200" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" 
	Margin="80,40,0,0" Text="{Binding Path=age, Mode=TwoWay}" />
</Grid>

In the code we then create the data binding to the Customer object. By binding to the grid all the elements under the grid in the visual tree will have access to the Customer object.

Customer myCustomer = new Customer();
Grid1.DataContext = myCustomer;

To extend the code a little we can also add support for the event SourceUpdated that will be executed when the data source is being changed by this element.

<TextBox Name="customerName" Width="200" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" 
	Margin="80,10,0,0" Text="{Binding Path=name, NotifyOnSourceUpdated=True, Mode=TwoWay}" 
	SourceUpdated="TextBox_SourceUpdated" />

This is the code that handles the data source updates. In this example it’s being called every time the textbox causes the value to change, not if other sources causes it to change.

private void TextBox_SourceUpdated(object sender, DataTransferEventArgs e)
{
  TextBox t = (TextBox)sender;
  if (t.Name == "customerAge")
    MessageBox.Show("Updated age to " + myCustomer.age.ToString());
  else if (t.Name == "customerName")
    MessageBox.Show("Updated name to " + myCustomer.name);
}