24

I am trying to bind several different properties in my Xaml:

<Label Content="{Binding Description}" 
Visibility="{Binding Path=DescriptionVisibility, 
ElementName=_UserInputOutput}"               
FontSize="{Binding Path=FontSizeValue, ElementName=_UserInputOutput}"  
HorizontalAlignment="Left" VerticalAlignment="Top" Padding="0" />

You will noticed I have used two Different binding techniques here. The ones using Element Name work, the other does not. Here is code behind:

public string Description
{
     get { return (string)GetValue(DescriptionProperty); }
     set { SetValue(DescriptionProperty, value); }
}
public static readonly DependencyProperty DescriptionProperty = 
DependencyProperty.Register("Description", typeof(string), typeof(UserControl), 
new UIPropertyMetadata(""));

Each Binding has a different name but they all look like this for the most part. I want my Binding to be able to work with:

{Binding Description}

Instead of:

{Binding Path=Description, ElementName=_UserInputOutput}

It only seems to be working when ElementName is used. I need to export/import this XAML, so I can't have a ElementName or the import won't work.

I thought this would be best:

{Binding Path=Description, RelativeSource={RelativeSource Self}}

This did not work.

Any ideas?? Thank you!

H.B.
  • 166,899
  • 29
  • 327
  • 400
B-Rad
  • 1,519
  • 5
  • 17
  • 32
  • [This article](http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/30/debugging-data-bindings-in-a-wpf-or-silverlight-application.aspx) might be of interest. – H.B. Aug 16 '12 at 23:01

2 Answers2

40

{RelativeSource Self} targets the object that owns the property that is being bound, if you have such a binding on a Label it will look for Label.Description, which isn't there. Instead you should use {RelativeSource AncestorType=UserControl}.

Bindings without a source (ElementName, Source, RelativeSource) are relative to the DataContext, however in UserControls you should avoid setting the DataContext to not mess with external bindings.

Community
  • 1
  • 1
H.B.
  • 166,899
  • 29
  • 327
  • 400
33

You haven't set the DataContext, which is what the RelativeSource is using to determine what it's relative to. You need to set the DataContext at a higher level, like the UserControl. I typically have:

<UserControl ... DataContext="{Binding RelativeSource={RelativeSource Self}}">
</UserControl>

This tells the UserControl to bind itself the class in the codebehind.

Douglas
  • 53,759
  • 13
  • 140
  • 188
Joel Lucsy
  • 8,520
  • 1
  • 29
  • 35
  • 20
    "which is what the RelativeSource is using to determine what it's relative to" That statement is plain incorrect. Also setting the DataContext of a UserControl is rarely a good idea... – H.B. Aug 16 '12 at 22:52
  • 6
    I think this is not a good idea since it violates the MVVM paradigm: When we want to use WPF with MVVM we have a View that binds to its ViewModel. So inside the constructor of the code behind of the View we say `View() { InitializeComponent(); DataContext = new ViewModel(); }` This makes all data binding operations work on the ViewModel so we can separate the view from the ViewModel. – codingdave Sep 15 '16 at 11:57
  • 1
    Its unlikely that you want (or even need) to do what is suggested here. The upvotes seem ill-advised. – ToolmakerSteve Nov 20 '21 at 23:43
  • @codingdave I agree except there's some thinking that you can simplify using your controls in a hierarchy if you either let the parent set the view model or use binding to bind the dependency. – TJ Bandrowsky May 07 '23 at 23:16