Search code examples
c#wpfxamldata-binding

Help with WPF data binding


I'm new to WPF and I'm trying to figure out how data binding works, but I'm not having much luck.

I'm trying to start with something simple - binding the contents of a text box to a string variable in my program.

I read lots and lots of pages of MSDN documentation about data binding, XML namespaces, markup extensions, resources, dependency properties and whatnot, and I'm still not able to get it to work.

Here's my MainWindow.xaml:

<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:c="clr-namespace:WpfTest"
        Title="MainWindow">
    <Grid>
        <Grid.Resources>
            <c:Foo x:Key="MyFoo"/>
        </Grid.Resources>
        <TextBox Width="100" Height="28"
                 Text="{Binding Source=MyFoo,
                                Path=BarProperty,
                                Mode=TwoWay,
                                UpdateSourceTrigger=PropertyChanged}"/>
    </Grid>
</Window>

And my MainWindow.xaml.cs:

namespace WpfTest
{
    public class Foo : DependencyObject
    {
        public static readonly DependencyProperty BarProperty = DependencyProperty.Register("Bar", typeof(String), typeof(Foo));

        public String Bar
        {
            get { return (String)GetValue(BarProperty); }
            set { SetValue(BarProperty, value); }
        }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MyFoo = new Foo { Bar = "hello" };
        }

        public Foo MyFoo { get; set; }
    }
}

I would expect the text box to show "hello" when the program starts up, but it is empty.

Can someone tell me what I am doing wrong?


Solution

  • You need to specify the source. Either:

    Give the window a name like Name="mywin", alter your binding witn ElementName="myWin"

    Or set the window DataContext like:

    DataContext="{Binding ElementName="myWin"} - you can also use a RelativeSource if you don't want the name I just couldn't post it untested - Bindings tend to require testing as you also noticed :)