1

In a WPF application using a fairly standard MVVM pattern, I need to bind from a row in a DataTable (i.e. deep inside the visual tree) to the data context of the whole window. I am assuming the only way to do this is to use Mode=RelativeSource, but it requires that I specify the AncestorLevel.

  1. How do I determine the AncestorLevel?
  2. Why should I need to specify this at all when I know there is only ever one window? In other words, why can't I simply specify the type I want to bind to and have the binding engine reverse up the tree until it finds the first object of the required type?
  3. If I do figure out the AncestorLevel, doesn't this make the code brittle? (If I change the nesting of the visual elements, it will obviously break.)

If there is no good solution involving RelativeSource, I thought I could take an alternative approach and 'propagate' the page-level property down through the logical tree to the individual items in the list. Is there an accepted pattern for this?

Has RelativeSource ever had a way of traversing up the tree searching only by type (or am I imagining this)?

Patrick
  • 769
  • 6
  • 18

3 Answers3

0

See my question, similar issue was raised there:
WPF finding ancestor for binding

In short - when you give the ancestor type, it is searched upwards the elements tree until the ancestor of that given type is found (Level 1). Should you need to search two levels up (e.g. you have a grid in a grid and you're aiming for the "outer" grid), you specify AncestorLevel=2 and the ancestor is then a second element of that particular type while traversing the elements tree.

Mike
  • 1,225
  • 10
  • 21
0

How do I determine the AncestorLevel?

By looking at the visual tree and figuring out the number of occurances of a specific type of parent element. There can only be only one top-level parent window though.

Why should I need to specify this at all when I know there is only ever one window?

You don't have to. It's perfectly fine and also very common to only specify the AncestorType like this:

{Binding SomePropertyOfTheWindow, RelativeSource={RelativeSource AncestorType=Window}}" />

If I do figure out the AncestorLevel, doesn't this make the code brittle? (If I change the nesting of the visual elements, it will obviously break.)

Yes, this is correct, but this is how you tell the binding engine to which particular item of a specific type that you want to bind to - assuming there are several to choose from.

mm8
  • 163,881
  • 10
  • 57
  • 88
0

Although this is not binding to a Relative source, but another way of binding without the complexities of Relative and type.

Another option instead of binding to a specific type of control, you can name your controls in the xaml with x:Name. Then you can bind directly to that control and property on it. Ex:

<SomeControl x:Name="IWantThisControl" />

[bunch of other controls]

<YourOtherControl ThisControlProperty={Binding ElementName=IWantThisControl, Path=PropertyOnTheOtherControl}" />

It does not matter the nesting level of the controls when you use the binding to ElementName reference.

DRapp
  • 47,638
  • 12
  • 72
  • 142