ToggleButton绑定到Enum,如何防止切换关闭

本文关键字:何防止 绑定 Enum ToggleButton | 更新日期: 2023-09-27 18:17:35

我在XAML的同一容器内设置了一组按钮,如下所示:

<ribbon:RibbonGroup Header="Layouts">
    <ribbon:RibbonToggleButton Label="One"
        IsChecked="{Binding PaneManager.Layout,
                            Converter={StaticResource EnumToBooleanConverter},
                            ConverterParameter={s:Static windows:Layouts.One}}"/>
    <ribbon:RibbonToggleButton Label="Two Vertical"
        IsChecked="{Binding PaneManager.Layout,
                            Converter={StaticResource EnumToBooleanConverter},
                            ConverterParameter={s:Static windows:Layouts.TwoVertical}}"/>
    <!-- etc. for 2 horizontal and 4 panes -->
</ribbon:RibbonGroup>

我使用相同的EnumToBooleanConverter概述在这个答案:

public class EnumToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(parameter);
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? parameter : Binding.DoNothing;
    }
}
问题是,当用户单击已经选中的切换按钮时,切换按钮会自动关闭——即使绑定值与该切换按钮匹配。在跟踪代码时,会调用ConvertBack方法并返回Binding.DoNothing。之后,不调用Convert来重新赋值。当ConvertBack返回一个值(即点击第二次,IsChecked再次为真),调用Convert方法重新赋值。

如果我改变返回类型false为DependencyObject.UnsetValue,切换按钮仍然是关闭的,但现在它有一个红色的轮廓。

我如何强制WPF重新评估绑定值,使切换按钮保持在上?

ToggleButton绑定到Enum,如何防止切换关闭

好的,似乎我必须控制切换按钮IsHitTestVisible是否使其行为正确。如果我把切换按钮改成这样:

<ribbon:RibbonGroup Header="Layouts">
    <ribbon:RibbonToggleButton Label="One"
        IsChecked="{Binding PaneManager.Layout,
                            Converter={StaticResource EnumToBooleanConverter},
                            ConverterParameter={s:Static windows:Layouts.One}}"
        IsHitTestVisible="{Binding IsChecked,
                                   RelativeSource={RelativeSource Self},
                                   Converter={StaticResource InverseBooleanConverter}}"/>
    <ribbon:RibbonToggleButton Label="Two Vertical"
        IsChecked="{Binding PaneManager.Layout,
                            Converter={StaticResource EnumToBooleanConverter},
                            ConverterParameter={s:Static windows:Layouts.TwoVertical}}"
        IsHitTestVisible="{Binding IsChecked,
                                   RelativeSource={RelativeSource Self},
                                   Converter={StaticResource InverseBooleanConverter}}"/>
    <!-- etc. for 2 horizontal and 4 panes -->
</ribbon:RibbonGroup>

然后提供以下转换器:

public class InverseBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return !(bool)value;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return !(bool)value;
    }
}

这感觉像一个hack,但它确实防止切换回。我非常愿意接受更优雅的解决方案