【问题标题】:ToggleButton bound to Enum, how do you prevent toggling off?ToggleButton 绑定到 Enum,如何防止切换?
【发布时间】:2015-10-14 13:21:52
【问题描述】:

我的 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>

我正在使用this answer 中概述的相同 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 重新评估绑定值以使切换按钮保持打开状态?

【问题讨论】:

  • PaneManager.Layout的数据类型是什么? ConvertBack 应该返回该数据类型的有效值。
  • 规则 #1:始终首先定义 ..Parameter。关于问题:你不能使用单参数转换器,因为你需要传递枚举的 current 值来转换 IsChecked 回来(我假设你正在使用 [Flag] 枚举)。我自己会使用命令和单向转换器。您可能会决定使用 MultiValueConverter。
  • @KingKing 这是一个特定于应用程序的enum。在切换按钮之间切换时,转换器提供的功能就像一个魅力。
  • @Sinatr 这不是 [Flag] 枚举。只是一个标准的互斥值。我没有遇到第二个定义 CoonverterParameter 的任何问题。命令似乎过于架构,因为需要完成的所有事情都在 DependencyProperty 更改的回调中处理。
  • 我以为你想切换位。您出于未知原因使用HasFlag,可能是一个简单的检查(Enum)value == (Enum)parameterPaneManager.Layout 不必是DependencyPropertyIsChecked 可以绑定到普通属性。

标签: c# wpf c#-4.0 binding enums


【解决方案1】:

好的,看来我必须控制切换按钮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,但它确实可以防止切换回来。我非常愿意接受更优雅的解决方案。

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多