I am trying to bind the IsChecked property of a ToggleButton through a markup extension which resolves to a MultiBinding. In XAML I have two source toggle buttons and a target toggle button which should have its IsChecked bound to the IsChecked of the source buttons.
<ToggleButton x:Name="Source1" Content="Source 1" Margin="5" Padding="5,2"/>
<ToggleButton x:Name="Source2" Content="Source 2" Margin="5" Padding="5,2"/>
<ToggleButton Content="Target" Margin="5" Padding="5,2">
<ToggleButton.IsChecked>
<local:ExMultiBinding Converter="{StaticResource AnyConverter}">
<Binding ElementName="Source1" Path="IsChecked"/>
<Binding ElementName="Source2" Path="IsChecked"/>
</local:ExMultiBinding>
</ToggleButton.IsChecked>
</ToggleButton>
My markup extension providing the MultiBinding looks like this
[ContentProperty("Bindings")]
public class ExMultiBindingExtension : MarkupExtension, INotifyPropertyChanged
{
public Collection<BindingBase> Bindings { get; set; } = new Collection<BindingBase>();
public IMultiValueConverter Converter { get; set; }
public BindingMode Mode { get; set; }
public UpdateSourceTrigger UpdateSourceTrigger { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
var multi = new MultiBinding
{
Converter = Converter,
Mode = Mode,
UpdateSourceTrigger = UpdateSourceTrigger
};
return multi;
}
public event PropertyChangedEventHandler PropertyChanged;
}
Starting the UI yields
ArgumentException: 'System.Windows.Data.MultiBinding' is not a valid value for property 'IsChecked'.
I checked and the IsChecked property on the ToggleButton implementation is actually not marked with
[Bindable(true)]
but only with
[Category("Appearance")]
[TypeConverter(typeof (NullableBoolConverter))]
[Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)]
Direct binding through a Binding or MultiBinding in XAML works.
The example code is simplified to highlight the problem. It is not possible to avoid the MarkupExtension in the real code since the implementation is more complicated.
BindingBaseitself is aMarkupExtension. And of course amarkupExtensionis not of typebooland can't be assigned to a member of typebool.The reason why your extension is called is because the XAML parser wants to resolve every
MarkupExtension. It's done by invoking theMarkupExtension.ProvideValuemethod. In this case theBindingBaseobject will be associated with aBindingExpressionBaseobject. ThisBindingExpressionBasewill resolve the underlying binding to return the actual value (simplified).So you have to manually resolve the
BindingBasemarkup: