我正在尝试通过解析为IsChecked
的标记扩展来绑定ToggleButton
的MultiBinding
属性。在XAML中,我有两个源切换按钮和一个目标切换按钮,应将其IsChecked
绑定到源按钮的IsChecked
。
<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>
提供MultiBinding
的我的标记扩展名如下
[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;
}
启动UI产量
ArgumentException: 'System.Windows.Data.MultiBinding' is not a valid value for property 'IsChecked'.
我已检查并且IsChecked
实现上的ToggleButton
属性实际上未标记为
[Bindable(true)]
但仅限于
[Category("Appearance")]
[TypeConverter(typeof (NullableBoolConverter))]
[Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)]
通过XAML中的Binding
或MultiBinding
直接绑定。
示例代码经过简化以突出显示该问题。在实际代码中,无法避免MarkupExtension是因为实现更为复杂。
BindingBase
本身就是MarkupExtension
。当然,markupExtension
的类型不是bool
,并且不能分配给bool
类型的成员。
之所以调用您的扩展名,是因为XAML解析器要解析每个MarkupExtension
。通过调用MarkupExtension.ProvideValue
方法来完成。在这种情况下,BindingBase
对象将与BindingExpressionBase
对象关联。此BindingExpressionBase
将解析基础绑定以返回实际值(简化)。
所以您必须解决BindingBase
标记:
public override object ProvideValue(IServiceProvider serviceProvider)
{
var multi = new MultiBinding
{
Converter = Converter,
Mode = Mode,
UpdateSourceTrigger = UpdateSourceTrigger
};
// Resolve the MarkupExtension BindingBase
return multi.ProvideValue(serviceProvider);
}