views:

91

answers:

1

I have a problem with a multibinding:

<Canvas>
 <local:SPoint x:Name="sp" Width="10" Height="10">
  <Canvas.Left><!-- irrelevant binding here --></Canvas.Left>
  <Canvas.Top>
   <MultiBinding Converter="{StaticResource myConverter}" Mode="TwoWay">
    <Binding ElementName="cp1" Path="(Canvas.Top)"/>
    <Binding ElementName="cp1" Path="Height"/>
    <Binding ElementName="cp2" Path="(Canvas.Top)"/>
    <Binding ElementName="cp2" Path="Height"/>
    <Binding ElementName="sp" Path="Height"/>
    <Binding ElementName="sp" Path="Slope" Mode="TwoWay"/>
   </MultiBinding>
  </Canvas.Top>
 </local:SPoint>
 <local:CPoint x:Name="cp1" Width="10" Height="10" Canvas.Left="20" Canvas.Top="150"/>
 <local:CPoint x:Name="cp2" Width="10" Height="10" Canvas.Left="100" Canvas.Top="20"/>
</Canvas>

In order to calculate the Canvas.Top value, myConverter needs all the bound values. This works great in Convert(). Going the other way, myConverter should ideally calculate the Slope value (Binding.DoNothing for the rest), but it needs the other values in addition to the Canvas.Top one passed to ConvertBack(). What is the right way to solve this?

I have tried making the binding OneWay and create an additional multibinding for local:SPoint.Slope, but that causes infinite recursion and stack overflow. I was thinking the ConverterParameter could be used, but it seems like it's not possible to bind to it.

+1  A: 

The approach may not be the most elegant one but it does work around the limits of multi bindings and the fact that ConverterParameter is not a DependencyProperty.

Make your converter derive from FrameworkContentElement. Define a number of DependencyProperty proprerties. You will need as many of them as there are values that you need on both ends of conversion.

Since your converter normally sits in XAML resources, DataContext and ElementName bindings won't work without some help from DataContextSpy and/or ElementSpy, depending on your particular binding needs.

The oddity of this approach is that you will have two identical bindings, one in <MultiBinding> section of XAML and the other one in Resources where you define your converter. The former one is needed to trigger the MultiBinding while the latter one actually provides the value in ConvertBack direction.

A downside is that resources are shared and thus if you need the same functional converter somewhere else on the page, you might need to declare a second one in your resources. This is only if two MultiBindings need different parameters. If parameters are shared, you may as well use the same resource. You might also try x:Shared="False" on the converter resource but I am not sure if that would work.

wpfwannabe
Thanks, this is very insightful. It also reminds me that when things get complicated, the problem could be the design. :) I'll possibly reconsider my approach.
absence