0

I have the following hierarchy in my XAML:

Grid
  Ruler
  Ruler
  ScrollViewer
    ItemsControl
      ItemsControl.ItemsPanel
        ItemsPanelTemplate
          DrawingCanvas

Here Ruler and DrawingCanvas are my UserControls. DrawingCanvas exposes a property named MousePosition that I want both Rulers to bind to. After reading about PropertyPath Syntax, I tried the following:

Chip="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Mode=OneWay, Path=Children[2].(ScrollViewer.Content).(ItemsControl.ItemsPanel).(local:DesignerCanvas.MousePosition).X}"

but this doesn't seem to work. What am I doing wrong?

dotNET
  • 33,414
  • 24
  • 162
  • 251

2 Answers2

0

You are selecting element 3 in the Children collection which will map to the fourth element inside of the Grid. You are looking for Children[2].

Jon G Stødle
  • 3,844
  • 1
  • 16
  • 22
0

Generally in these circumstances you would simply name the element you wish to bind to. It is much less brittle than finding your way through the tree:

Chip="{Binding MousePosition.X, ElementName=myCanvas}" 

However, because your canvas is part of the ItemsControl template, the ElementName will not be visible to elements outside the ItemsControl.

In order to bind the two together, you need some intermediate property that both can see. One way would be to declare a DependencyProperty in your code-behind for the view. Both your Canvas and Rulers could then bind to that property using ElementName on the view root.

Another alternative is to hijack the Tag property that every element has, so in your case you could use ItemsControl.Tag as the intermediary:

Chip="{Binding Tag.X, ElementName=myItemsControl}" 

<DrawingCanvas MousePosition={Binding Tag, 
                              ElementName=myItemsControl, 
                              mode=OneWayToSource} />
GazTheDestroyer
  • 20,722
  • 9
  • 70
  • 103
  • Interesting idea, but `MousePosition` is a readonly property of `DrawingCanvas` itself (returns the current mouse position w.r.t the DrawingCanvas). The above binding won't work in my case, right? – dotNET Aug 14 '15 at 13:27
  • Depends if MousePosition is a DependencyProperty. If yes, then it should work. – GazTheDestroyer Aug 14 '15 at 13:29
  • `MousePosition` is a DP, but was readonly. I added setter to the property and it compiled then, but at runtime it throws exception that "'MousePosition' property cannot be data-bound." – dotNET Aug 14 '15 at 13:33
  • That sucks. See http://stackoverflow.com/questions/658170/onewaytosource-binding-from-readonly-property-in-xaml – GazTheDestroyer Aug 14 '15 at 13:36
  • Thanks for the post. That looks like a big fat bug. Seeing that it is still here after WPF has spent over a decade of its life is lame. I manage to solve the problem by redefining `MousePosition` property as read/write. Seems there is no other workaround. Big thanks for your input. – dotNET Aug 14 '15 at 13:43