2011-04-11 55 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上傳遞任何東西,或者它也可以綁定到可以控制你的邏輯的東西。