【问题标题】:WPF ToggleButton multibinding of IsChecked through MarkupExtension throws通过 MarkupExtension 抛出 IsChecked 的 WPF ToggleButton 多重绑定
【发布时间】:2020-04-24 09:13:39
【问题描述】:

我正在尝试通过解析为MultiBinding 的标记扩展来绑定ToggleButtonIsChecked 属性。在 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'.

我查了一下,ToggleButton 实现上的IsChecked 属性实际上并没有标记

[Bindable(true)]

但仅限于

[Category("Appearance")]
[TypeConverter(typeof (NullableBoolConverter))]
[Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)]

在 XAML 中通过 BindingMultiBinding 直接绑定有效。

简化示例代码以突出问题。在实际代码中不可能避免 MarkupExtension,因为实现更加复杂。

【问题讨论】:

  • 你见过this吗?您可以尝试从 MultiBinding 而不是 MarkupExtension 派生。

标签: wpf data-binding togglebutton markup-extensions


【解决方案1】:

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);
}

【讨论】:

    猜你喜欢
    • 2011-06-25
    • 2010-12-04
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多