2011-04-11 90 views
5

我有以下转炉一个通用的布尔转换器

[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" /> 

有没有一种方法,使之更加通用的,也就是说,它可以返回任何类型的对象?

+0

只是为了确保:您知道[System.Windows.Controls.BooleanToVisibilityConverter](http://msdn.microsoft.com/zh-cn/library/system.windows.controls.booleantovisibilityconverter.aspx)已经存在? – Heinzi 2011-04-11 15:55:16

+0

是的,这只是一个老的片段来解释我的观点 – Marcom 2011-04-11 15:59:11

+0

你可能想看看我最近的帖子关于这个主题:http://kentb.blogspot.com/2011/02/booleantovisibilityconverter.html – 2011-04-11 17:28:39

回答

3

您只需制作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(即未编译)。

+0

如果他们是类型对象,XAML将如何知道'TrueValue =“Visible”'需要转换为'myBoolConverter.TrueValue = System.Windows.Visibility.Visible',而不是例如字符串“Visible”? – Heinzi 2011-04-11 15:57:38

+0

@ Heinzi - 是的,那是你放弃的一件事。你必须明确定义这些值。我会更新我的答案。 – CodeNaked 2011-04-11 16:00:41

+0

@Heinzi - 已更新。 – CodeNaked 2011-04-11 16:03:01

1

我会简单地使用两班,

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

或者我会通过所谓的“反向”转换器参数

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

然后,您可以检查逆在ConverterParameter传递和假返回可见。

你可以在ConverterParameter上传递任何东西,或者它也可以绑定到可以控制你的逻辑的东西。