views:

79

answers:

2

I have another WPF databinding question... one that I haven't found an answer to anywhere, and this surprises me since it seems like it is very basic.

Essentially, I have a string in code behind that I would like to establish a two-way binding with with a textbox in my GUI. I thought it was a simple matter of creating a DependencyProperty in the code behind, and then tying it to the TextBox via a Source binding. The problem is, I can't get one or both parts right.

Here is my DependencyProperty definition from the code behind:

    public static readonly DependencyProperty FilePathProperty = DependencyProperty.Register( "FilePath", typeof(string), typeof(Window1));
    public string FilePath
    {
        get { return (string)GetValue(FilePathProperty); }
        set { SetValue( FilePathProperty, value); }
    }

And here is my XAML:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ReportingInterface Test Application" Height="300" Width="536">

    <Menu DockPanel.Dock="Top">
        <MenuItem Name="menu_plugins" Header="File">
            <MenuItem Header="Open">
                <StackPanel Orientation="Horizontal">
                    <Label>File location:</Label>
                    <TextBox Name="text_filepath" Width="100" Text="{Binding Source=FilePath, Path=FilePath, Mode=TwoWay}"></TextBox>
                    <Button Margin="3" Width="20">...</Button>
                </StackPanel>
            </MenuItem>
        </MenuItem>
    </Menu>

The part I know is obviously wrong is the Binding part... I hate to waste people's time here with this question, but I honestly have come up short with every search (but now at least this request will populate subsequent google searches). :)

Thank you!

+2  A: 

When you defined a binding in XAML, it binds to whatever is set as the DataContext for the object (or it's parent).

This typically means you'd set the DataContext of the Window to some class, and then the binding will work:

<TextBox Name="text_filepath" Width="100" Text="{Binding Path=FilePath, Mode=TwoWay}" />

You can fix this by adding, in the Window's constructor:

this.DataContext = this;

That will make the binding work against the window itself.

Alternatively, you can setup the binding to bind against a specific source object. If, in this case, you wanted to be able to use something else as the DataContext, but still want to bind to a Dependency Property defined in your Window, you could do:

<TextBox Name="text_filepath" Width="100" Text="{Binding Path=FilePath, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"></TextBox>

This works by telling the binding to find the first ancestor of type "Window", and bind it the "FilePath" property on that object.

Reed Copsey
Thank you, Reed! I have played with DataContext and still am a bit fuzzy on it, and couldn't get it working with my current project. I'll give it a shot now! :)
Dave
Yeah, baby! Thanks, the magical line this.DataContext.this worked like a charm. :)
Dave
+1  A: 

For what it's worth, I would recommend looking into the M-V-VM pattern (Model, View, ViewModel)- essentially, what you do is have this class that serves as the DataContext for your XAML, and all your fun exposed properties/commands/what have you are exposed as public members of that class (called a ViewModel).

Here's a good overview webcast: MVVM video

And here's another from MSDN mag: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

JerKimball
MVVM is definitely on my ever-growing list of concepts to learn. It's an absolute must for me.
Dave