14

I have this Text dependency property in code behind:

public static DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(MainWindow),
        new PropertyMetadata("Hello world"));

public string Text {
    get { return (string)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}

I want to bind content of label to that Text property so that the label displays actual value of Text property and vice-versa.

<Label Content="{Binding ???}" />

How can I do it ?

I have done that some time before but now I cannot remember how - and it is very simple. The simplest code will be accepted.

Rasto
  • 17,204
  • 47
  • 154
  • 245
  • I have tried this: `` and it also does not work... Could it be that binding does not work in completely new WPF project where everything else works ? – Rasto Apr 28 '11 at 20:48

4 Answers4

18

Set DataContext of your Window/Control to the same class and then specify the path on the binding, something like this:

public class MyWindow : Window {

    public MyWindow() {
        InitializeComponents();
        DataContext = this;
    }

    public string Text { ... }    
}

Then in your xaml:

<Label Content="{Binding Path=Text}">
Hadi Eskandari
  • 25,575
  • 8
  • 51
  • 65
  • It works thanks. But why for does it not show the `Label`s content in VS designer ?! – Rasto Apr 28 '11 at 20:58
  • When setting DataContext from code-behind, blend won't show data bound to the data context. You can use d:DataContext to set the design-time data context to another object which facilitates designing in blend. See here: http://stackoverflow.com/questions/862829/what-is-the-advantage-of-setting-datacontext-in-code-instead-of-xaml – Hadi Eskandari Apr 28 '11 at 21:07
  • I don't want it in Blend but in VisualStudio. Is it the same ? – Rasto Apr 28 '11 at 21:12
  • I tried to put `DataContext="{Binding RelativeSource={RelativeSource Self}}"` into XAML code but VS still don't display binded data in the `Label`. Do you experience the same think ? Or your VS displays bound data in visual designer? – Rasto Apr 28 '11 at 21:30
  • 1
    If you're setting the Label's DataContext property, you're basically setting it to itself. Label happens to have a Text property, so you won't see any data binding errors, probably. You want to set the data context to {RelativeSource FindAncestor,AncestorType={x:Type Window}} or something to that effect. – Kevin Hsu Apr 28 '11 at 21:46
13

You have to set the DataContext of the window for it to work. XAML:

<Window x:Class="WpfApplication2.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" 
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
      <StackPanel>
        <Label Content="{Binding Text}" />
        <Button Content="Click me" Click="HandleClick" />
      </StackPanel>

    </Grid>
</Window>

Code-behind:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MainWindow), new PropertyMetadata("Hello world"));
    public string Text 
    { 
        get { return (string)GetValue(TextProperty); } 
        set { this.SetValue(TextProperty, value); } 
    }

    public MainWindow()
    {
        InitializeComponent();
    }

    protected void HandleClick(object sender, RoutedEventArgs e)
    {
        this.Text = "Hello, World";
    }
}
Ari Roth
  • 5,392
  • 2
  • 31
  • 46
  • 3
    My bad, forgot the DataContext. Try now. Sorry. (Tested it and it works.) – Ari Roth Apr 28 '11 at 21:01
  • +1 Better but others were faster, before you could edit. Thanks for nice example anyway it will be useful for others. – Rasto Apr 28 '11 at 21:03
  • I like this method better because you don't have to look at the codebehind to see the DataContext assignment. But if you find yourself binding more than 2 or 3 things to codebehind, you should really consider splitting them out into a ViewModel! – piedar Feb 06 '14 at 19:49
2

Setting DataContext in XAML to Code-Behind can be a little bit tricky but in general these situation are the most common:

  1. You want to make the DataContext the the whole Window or Custom UserControl

.

<Window
blahhhh..
DataContext={Binding RelativeSource={RelativeSource Mode=Self}}>

or

<UserControl
Blahhhh....
DataContext={Binding RelativeSource={RelativeSource Mode=Self}}>

2. if you set the DataContext of the Window or user control to something else than the code behind and have a child control you would need to set it's DataContext to the Code-Behind you can use the following:

<Label DataContext={Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}/>

for custom UserControl :

<Label DataContext={Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}/>

in this Case setting the DataContext to self, will make Binding refer to the Label Object itself not the Control's Code-Behind. I hope that will help.

1

When you say it's in the code-behind, you mean it's in the code for the Window of your class?

You may want to bind to the RelativeSource where the ancestor type is Window. Alternatively, if your data context is not already set, in your Load event, set the window's DataContext property to the window itself (this), and just use {Binding Text}.

Kevin Hsu
  • 1,726
  • 11
  • 14
  • yes code-behind means that the `Label` is in the same class as the `Text` dependency property. The only difference here is that `Label` is in XAML and dependency property in code. – Rasto Apr 28 '11 at 20:53