views:

15

answers:

1

I have trouble to understand how dependency properties can be used between C# and xaml code. This is a smal code example of my question

XAML code:

<Window x:Class="WpfChangeTextApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<StackPanel>
    <Label Name="statusTextLabel" Content="{Binding StatusText}"></Label>
    <Button Name="changeStatusTextButton" Click="changeStatusTextButton_Click">Change Text</Button>
</StackPanel>

C# code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();            
    }

    public string StatusText
    {
        get { return (string)GetValue(StatusTextProperty); }
        set { SetValue(StatusTextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for StatusText.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty StatusTextProperty =
        DependencyProperty.Register("StatusText", typeof(string), typeof(MainWindow));

    private void changeStatusTextButton_Click(object sender, RoutedEventArgs e)
    {
        StatusText = "Button clicked";
    }
}

So, my trouble is that Label statusTextLabel dose not get updated when I click on the button. My trouble is that I don't know in what part of the code that I'm doing something wrong, is it in the xaml or in the C#? In the xaml I might doing something wrong in the Binding? Or have I missed doing something in the C# code?

A: 

By default, binding paths are relative to the DataContext property of the current element. You have not set it to anything, so it can't resolve the binding. If you want the StatusText property on your window class, then there are two approaches. One is to use a binding with a RelativeSource of FindAncestor to find the Window in the tree and bind to its properties directly:

<Label Name="statusTextLabel" Content="{Binding StatusText, 
    RelativeSource={RelativeSource AncestorType=Window}}"></Label>

The other is to set the DataContext of the Window to itself, so it will be inherited by the label. For example, in your constructor:

public MainWindow()
{
    this.DataContext = this;
    InitializeComponent();
}

For most applications, you will actually want a separate class to represent the data, and you will set an instance of that class as the DataContext. You can also use ordinary CLR properties instead of dependency properties, although you will need to implement INotifyPropertyChanged if you want to UI to be informed when properties change. Dependency properties are more useful when you are writing a custom control and you want users to be able to set the properties using data binding.

Quartermeister