Search code examples
c#xamldata-binding

Binding to a property of an object in XAML not working


I am new to WPF and data binding. So I am trying some things but now encountered a problem that defies everything I find in reference material.

I have a test program with a string TestString1 that is bound to the Text property of a TextBox tbTest1, that works.

And I have an object TestString2 from ClassTestString2 that contains one property Str. And I want to bind Str to the Text property of a TextBox tbTest2. So I use Text="{Binding Path=TestString2.Str}". According to all documentation you can drill down to a property of an object with the normal C# syntax. But it simply doesn't bind, it doesn't show when starting the program and also making changes in tbTest2 are not reflected in TestString2.Str.

When I use this.DataContext = TestString2; and Text="{Binding Path=Str}", it works but than TestString1 is not bound anymore.

I have the following simple piece of XAML:

<Window x:Class="WpfBindingStringOnly.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfBindingStringOnly"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TextBox 
            x:Name="tbTest1" 
            Text="{Binding Path=TestString1}"
            HorizontalAlignment="Left" Height="41" 
            Margin="124,47,0,0" TextWrapping="Wrap" 
            VerticalAlignment="Top" Width="250"/>
        <TextBox 
            x:Name="tbTest2" 
            Text="{Binding Path=TestString2.Str}" 
            HorizontalAlignment="Left" Height="45" 
            Margin="124,126,0,0" TextWrapping="Wrap" 
            VerticalAlignment="Top" Width="250"/>
    </Grid>
</Window>

And C# code behind:

using System;
using System.Windows;
using static WpfBindingStringOnly.MainWindow;

namespace WpfBindingStringOnly
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public string TestString1 { get; set; }

        public class ClassTestString2
        {
            public string Str { get; set; }

            public ClassTestString2(string s)
            {
                Str = s;
            }
        }

        public ClassTestString2 TestString2;

        public MainWindow()
        {
            TestString1 = "Hello1";
            TestString2 = new("Hello2");

            InitializeComponent();
            this.DataContext = this;
        }
    }
}


Solution

  • Bindings work on properties, not fields.

    Change your TestString2 member from

    public ClassTestString2 TestString2; // This is a field.
    

    to

    public ClassTestString2 TestString2 { get; set; } // This is a property.