3
votes

I am having a really weird problem. I am trying to bind a property to the DataContext but it is not working. This is what I am doing (in the Window.Resources section):

<myNS:MyClass x:Key="myObj" MyProp="{Binding}"/>

Elsewhere in the code, I set the data context like this:

myWindow.DataContext = MyNameSpace.MySingleton.Instance;

I didn't get any errors, but the binding didn't happen. So I added a Debug converter to see if I could figure out what was going on:

<myNS:MyClass x:Key="myObj" MyProp="{Binding Converter={StaticResource Debug}}"/>

I set a breakpoint in the converter and the value being passed was null. Figuring that things were out of order, I set a breakpoint on the line that sets the DataContext. It was hit first, then the breakpoint in the converter. So the DataContext is being set before the binding occurs.

Finally, to try to get something to work, I changed to this:

<myNS:MyClass x:Key="myObj" MyProp="{Binding Source={x:Static myNS:MySingleton.Instance}}"/>

That worked.

I really don't like spreading out the bindings like this. I would rather just bind to the DataContext. The window in question contains many bindings to properties on the DataContext and these all work fine.

Can anyone explain what I am doing wrong here?

JAB

2
"Elsewhere in the code, I set the data context". Where exactly?adPartage
If the class does not derive from FrameworkElement, it is not really part of the Visual Tree, therefore the DataContext is not automatically 'inherited'.Silvermind

2 Answers

0
votes

Resources, as well as some other elements like Context Menus are not part of the visual tree.

Thus, they have no governing FrameworkElement to get a data context from. Usually, a standard class won't take advantage of the binding syntax, as it requires deriving from DependencyObject, but if you do end up needing a binding in a resource (say, for a converter) you can use this trick:

  1. Set your root element to have x:Name="Root"
  2. Use your bindings like this:

    MyProp="{Binding Source={x:Reference Root}, Path=DataContext.<YourProp>

This binds using the root framework element as the "starting point" and you can get to the data context normally.

0
votes

What an idiot I am!

I started to respond to @BradleyDotNET (thanks for the response, by the way. It is what helped me solve the problem), and figured out the solution. My class DOES derive from FrameworkElement. I did that because I needed to make use of data binding, even though it has no visible component.

I posted another question dealing with how to instantiate an object declared in the resource section. I would still like to know the answer to that, but since my class derives from FrameworkElement, I don't need to declare it in the resource section; I can put it directly in the tree. This causes it to be instantiated AND inherit the DataContext.