【问题标题】:A generic Boolean Convertor一个通用的布尔转换器
【发布时间】:2011-04-11 15:44:43
【问题描述】:

我有以下转换器

  [ValueConversion(typeof(bool), typeof(Visibility))]
public sealed class BoolToVisibilityConverter : IValueConverter
{
    public Visibility TrueValue { get; set; }
    public Visibility FalseValue { get; set; }

    public BoolToVisibilityConverter()
    {
        // set defaults
        TrueValue = Visibility.Visible;
        FalseValue = Visibility.Collapsed;
    }

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if (!(value is bool))
            return null;
        return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if (Equals(value, TrueValue))
            return true;
        if (Equals(value, FalseValue))
            return false;
        return null;
    }
}
<conv:BoolConverter x:Key="enableStyleConvertor" TrueValue="Visible" FalseValue="Collapsed" />

有没有办法让它更通用,即它可以返回任何类型的对象?

【问题讨论】:

标签: wpf


【解决方案1】:

您只需创建 Object 类型的 TrueValue 和 FalseValue。您可能需要更新 Equals 代码以查看对象是否也实现了 IComparable

[ValueConversion(typeof(bool), typeof(object))]
public sealed class MyConverter : IValueConverter
{
    public object TrueValue { get; set; }
    public object FalseValue { get; set; }

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if (!(value is bool))
            return null;
        return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if (IsEqual(value, TrueValue))
            return true;
        if (IsEqual(value, FalseValue))
            return false;
        return null;
    }

    private static bool IsEqual(object x, object y) {
        if (Equals(x, y))
          return true;

        IComparable c = x as IComparable;
        if (c != null)
           return (c.CompareTo(y) == 0);

        return false;
    }
}

要使用它,您现在需要明确定义值:

<local:MyConverter>
    <local:MyConverter.TrueValue>
        <Visibility>Visible</Visibility>
    </local:MyConverter.TrueValue>
    <local:MyConverter.FalseValue>
        <Visibility>Collapsed</Visibility>
    </local:MyConverter.FalseValue>
</local:MyConverter>

编辑:

通用版本如下所示:

[ValueConversion(typeof(bool), typeof(object))]
public sealed class MyConverter<T> : IValueConverter {
    public T TrueValue { get; set; }
    public T FalseValue { get; set; }

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture) {
        if (!(value is bool))
            return null;
        return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture) {
        if (IsEqual(value, TrueValue))
            return true;
        if (IsEqual(value, FalseValue))
            return false;
        return null;
    }

    private static bool IsEqual(object x, object y) {
        if (Equals(x, y))
            return true;

        IComparable c = x as IComparable;
        if (c != null)
            return (c.CompareTo(y) == 0);

        return false;
    }
}

不过,这并不容易从 XAML 访问。 XAML 2009 有一些用于泛型的additional support,但主要用于loose XAML files(即未编译)。

【讨论】:

  • 如果它们是对象类型,XAML 怎么知道TrueValue="Visible" 需要转换为myBoolConverter.TrueValue = System.Windows.Visibility.Visible,而不是例如字符串“Visible”?
  • @Heinzi - 是的,这是你放弃的一件事。您必须明确定义这些值。我会更新我的答案。
  • 有没有办法将该方法创建为 T 类型的泛型类?
  • @Marcom - 您可以将上述内容设为通用,但这会使在 XAML 中使用它变得更加困难。有关在 XAML 中创建泛型类的更多信息,请参阅 this question。或者,您可以基于泛型版本创建具体类,以便更轻松地通过 XAML 使用。
  • @Marcom - 基于this,看起来在 .NET 4 中,使用 XAML 中的泛型类型更容易。稍后我会尝试鞭打一些东西。
【解决方案2】:

我会简单地使用两个类,

BooleanToVisibilityConverter (Visible on true)
OppositeBooleanToVisibilityConverter (Visible on false)

或者我将传递一个名为“inverse”的转换器参数

<Button 
   Visibility="{Binding myValue, 
      Converter={StaticResource booleanToVisibility},
      ConverterParameter=inverse}" />

然后您可以检查在 ConverterParameter 中传递的反向并在 false 时返回 Visible。

您可以在 ConverterParameter 上传递任何内容,也可以将其绑定到可以控制您的逻辑的内容。

【讨论】:

    猜你喜欢
    • 2012-10-26
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    相关资源
    最近更新 更多