使用值转换器将切换按钮绑定到枚举类型

3

我正在处理的一个项目中定义了一个只有两个状态的枚举。我使用一个切换按钮来切换属性值。

我编写了一个将枚举绑定到一组单选按钮的值转换器,但由于Binding.DoNothing,它只能单向更改值,所以无法正常工作。

下面是将枚举转换为布尔值的转换器,它只能单向更改值:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    return value.Equals(parameter);
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    return value.Equals(true) ? parameter : Binding.DoNothing;
}

作为解决方法,我对正在使用的枚举进行了修改,如下所示,在ConvertBack方法中用MyEnum.Off替换了Binding.DoNothing

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value.Equals(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value.Equals(true) ? parameter : MyEnum.Off;
    }

有没有更好的方法来切换这个枚举值,使得切换按钮可以将枚举切换到关闭状态,并且在不同的枚举类型之间可以重复使用?

你有没有考虑过 ConvertBack(...) 方法中的 targetType 参数? - Silvermind
@Silvermind 我不太确定那会怎么样,但应该是可行的。你有什么建议如何做到这一点吗? - Kevin Lannen
2个回答

2
最简单的方法,不需要任何类型/空值等检查,如下所示:
public object Convert(object value, Type targetType, object parameter,
                      System.Globalization.CultureInfo culture)
{
    return System.Convert.ToBoolean(value);
}
public object ConvertBack(object value, Type targetType, object parameter,
                          System.Globalization.CultureInfo culture)
{
    return Enum.ToObject(targetType, value);
}


System.Convert.ToBoolean可以接受任何值类型而不会抛出异常。

您还可以进行一些附加的类型检查,例如if (targetType.IsEnum),但这由您决定。

根据msdn: Enum.ToObject()只接受SByte,Int16,Int32,Int64,Byte,UInt16,UInt32或UInt64。但我怀疑它在内部使用了System.Convert,所以也可以接受布尔值。


1
这个完美地运行了,布尔值确实是Enum.ToObject()方法中可接受的值。 - Kevin Lannen

0
如果你的枚举只有两种状态,使用布尔值会更简单吧?然后你可以将其外部化为一个函数,根据当前值将布尔值切换为true/false。
编辑: 在阅读@Kevin留下的评论后,我意识到我误解了原始问题。以下内容应该更符合您的要求。它将接受一个枚举T并迭代它,返回每个序列中下一个项的int索引,直到达到末尾,然后它将再次返回第一项(0)。
    private int SwitchEnum<T>(Enum G)
    {                        
        int next = Convert.ToInt32(G) + 1;

        if (Enum.IsDefined(typeof(T), next))
        {
            return next;
        }
        else
        {
            return 0;
        }
    }

您可以按照以下方式调用此函数:
    MyEnum a = new MyEnum(); //Assuming MyEnum is your enum
    a = (MyEnum)SwitchEnum<MyEnum>(a);

使用布尔值可以消除UI和viewModel属性之间的转换器,但我仍然需要在viewModel中在布尔值和枚举之间进行转换,以便在系统的其余部分中使用枚举,因此这并没有消除转换器的需求,只是将其移动了位置。 - Kevin Lannen
啊,我误解了。请看编辑。 - Rocky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接