I've been playing around with WPF for quite a while now, but for the first time today, I needed to nest a MultiBinding
inside another, something like:
<MultiBinding>
<Binding />
<MultiBinding>
<Binding />
<Binding />
</MultiBinding>
</MultiBinding>
I get an exception indicating it's not allowed by the framework:
XamlParseException was unhandled: Add value to collection of type 'System.Collections.ObjectModel.Collection(System.Windows.Data.BindingBase)' threw an exception.
The InnerException
is more explicit:
BindingCollection does not support items of type MultiBinding. Only Binding is allowed.
So digging the web for more info, I stumbled upon this Microsoft Connect issue which is exactly my problem.
Thank you for the feedback. WPF doesn't support this today. This feature has been requested for years (most recently earlier this month - see https://connect.microsoft.com/WPF/feedback/details/650164/nested-multibinding). We'll continue to consider this for future releases.
Right now I've made my peace that I won't have it easy. Still I need this, how can I nest MultiBindings?
If you have a converter that takes a parameter, you can do something like this:
DependencyProperties
to the class (so that you can bind the values in Xaml)In your xaml, use a binding with a converter instead of a multibinding, something like this:
<MultiBinding>
<Binding Source="SomeObject" Path="CoreValue" Converter="{StaticResource YourNewConverter}">
<Binding.ConverterParameter>
<ns:ParameterClass Value1="{Binding Parameter1}" Value2="{Binding Parameter1}" />
</Binding.ConverterParameter>
</Binding>
....
The limitation is that (AFAIK) the value will only be recalculated if CoreValue
changes - it won't automatically rebind if the converter parameters change.
(Apologies for any errors, I'm typing this without the benefit of VS to test in...)
An alternative to the other suggestions is to use attached properties to hold nested MultiBinding
s as intermediate values.
For example, instead of:
<Element>
<Element.Property>
<MultiBinding>
<Binding Path="A" />
<MultiBinding>
<Binding Path="B" />
<Binding Path="C" />
</MultiBinding>
</MultiBinding>
</Element.Property>
</Element>
...do this:
<Element Name="ElementName">
<ElementProperties.AttachedProperty>
<MultiBinding>
<Binding Path="B" />
<Binding Path="C" />
</MultiBinding>
</ElementProperties.AttachedProperty>
<Element.Property>
<MultiBinding>
<Binding Path="A" />
<Binding ElementName="ElementName" Path="(ElementProperties.AttachedProperty)" />
</MultiBinding>
</Element.Property>
</Element>
I know this question is more than six years old now, but I ran into it so someone else will, too.
I know that this is an old question but I think this this is a much nicer approach:
<FrameworkElement x:Name="IsBuyAndAmountInReference">
<FrameworkElement.Tag>
<MultiBinding Converter="{StaticResource LogicAndToBool}">
<Binding Path="OrderData.IsBuy" />
<Binding Path="OrderData.AmountInReference" />
</MultiBinding>
</FrameworkElement.Tag>
</FrameworkElement>
<FrameworkElement x:Name="IsSellAndAmountInBase">
<FrameworkElement.Tag>
<MultiBinding Converter="{StaticResource LogicAndToBool}">
<Binding Path="OrderData.IsBuy" Converter="{StaticResource BooleanToBooleanInvert}" />
<Binding Path="OrderData.AmountInReference" Converter="{StaticResource BooleanToBooleanInvert}" />
</MultiBinding>
</FrameworkElement.Tag>
</FrameworkElement>
<Slider Grid.Row="2" Grid.ColumnSpan="4">
<Slider.Visibility>
<MultiBinding Converter="{StaticResource LogicOrToVisibility}">
<Binding ElementName="IsBuyAndAmountInReference" Path="Tag" />
<Binding ElementName="IsSellAndAmountInBase" Path="Tag" />
</MultiBinding>
</Slider.Visibility>
</Slider>
I realise that this is an old question now, but I just hit exactly the same problem as the OP. Fortunately in my case I could bind to a sub-element where the result of the multi-binding was already being calculated, but it got me thinking...
A (though admittedly not very clean) solution would be to write the value of the multi-value binding into a 'spare' property such as an element's 'Tag' which you can then reference in your other multi-value bindings by specifying the 'ElementName' attribute.
If you need more than a single nested multi-value binding then you could create a 'fake' object with some dependency properties on it to store multiple intermediate results.
A pity that Microsoft don't implement a properly nested system...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With