WPF XAML binding does not update

binding, c#, wpf

Solution

There are a few things that are incorrect. The `Binding` markup will look at the object in the `DataContext` property of the control. This property inherits the `DataContext` from the declaring parent unless otherwise specified. Out of the box, this is `null` for a `Window` control.

There are two options for this problem. You can either set the `DataContext` explicitely in the code-behind or the XAML

// In XAML
<Window DataContext={Binding RelativeSource={RelativeSource Self}}>

or

// In the code-behind
DataContext = this;

Another problem is that the binding is applied at initialization. Initially, your properties are empty. After the `InitializeComponent` phase, the controls will "bind" to the properties (which are empty). When you set your properties afterward, the controls have no way to know it has changed. There are two mechanism to allow this. On the control level, you can make these properties as `DependencyProperty` or implement the `INotifyPropertyChanged` interface and raise the changes. If you want to go the INPC route, you can implement your properties and Window as such:

public partial class MainWindow : INotifyPropertyChanged
{
    private string firstString;
    private string secondString;
    private string thirdString;
    private string fourthString;

    public string FirstString
    {
        get { return firstString; }
        set
        {
            firstString = value;
            RaisePropertyChanged("FirstString");
        }
    }

    public string SecondString
    {
        get { return secondString; }
        set
        {
            secondString = value;
            RaisePropertyChanged("SecondString");
        }
    }

    public string ThirdString
    {
        get { return thirdString; }
        set
        {
            thirdString = value;
            RaisePropertyChanged("ThirdString");
        }
    }

    public string FourthString
    {
        get { return fourthString; }
        set
        {
            fourthString = value;
            RaisePropertyChanged("FourthString");
        }
    }

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

        FirstString = "First";
        SecondString = "Second";
        ThirdString = "Third";
        FourthString = "Fourth";
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    private void RaisePropertyChanged(string propertyName)
    {
        var handlers = PropertyChanged;

        handlers(this, new PropertyChangedEventArgs(propertyName));
    }
}

Problem

I have a WPF project in which I have 4 `TextBlock`. What I want is to change the `Text` of each `TextBlock` via `Binding`. So far I have my XAML: ``` <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock x:Name="First" Text="{Binding FirstString}" Grid.Row="0"/> <TextBlock x:Name="Second" Text="{Binding SecondString}" Grid.Row="1"/> <TextBlock x:Name="Third" Text="{Binding ThirdString}" Grid.Row="2"/> <TextBlock x:Name="Fourth" Text="{Binding FourthString}" Grid.Row="3"/> </Grid> ``` And in my code I have: ``` public partial class MainWindow : Window { public string FirstString { get; set; } public string SecondString { get; set; } public string ThirdString { get; set; } public string FourthString { get; set; } public MainWindow() { InitializeComponent(); FirstString = "First"; SecondString = "Second"; ThirdString= "Third"; FourthString= "Fourth"; } } ``` But the `Binding` doesn't work at all. Am I doing something wrong? EDIT: After following Chris Mantle's suggestion in the comments to look at the debug output (I had to enable Warnings for the Binding), I get the following error: System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=FirstString; DataItem=null; target element is 'TextBlock' (Name='First'); target property is 'Text' (type 'String')

Original source