2011-04-11 11 views
5

Tengo el siguiente convertidor deUn genérico de Boole convertidor

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

¿Hay una manera de hacerlo más genérico, es decir, puede devolver cualquier tipo de objeto?

+0

Solo para asegurarse: sabe que [System.Windows.Controls.BooleanToVisibilityConverter] (http://msdn.microsoft.com/en-us/library/system.windows.controls.booleantovisibilityconverter.aspx) ya existe ? – Heinzi

+0

sí, esto es solo un fragmento de código antiguo para explicar mi punto – Marcom

+0

Puede consultar mi publicación reciente sobre este mismo tema: http://kentb.blogspot.com/2011/02/booleantovisibilityconverter.html –

Respuesta

3

Acabas de hacer TrueValue y FalseValue de tipo Object. Es posible que desee actualizar el código Equals para ver si los objetos implementan también 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; 
    } 
} 

Para utilizar este que había necesidad de definir explícitamente los valores ahora, sin embargo:

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

EDIT:

Una versión genérica se vería así:

[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; 
    } 
} 

Sin embargo, esto no es fácilmente accesible desde XAML. XAML 2009 tiene algunos additional support para genéricos, pero eso es principalmente para loose XAML files (es decir, no compilado).

+0

Si son de type object, ¿cómo sabrá XAML que 'TrueValue =" Visible "' debe convertirse a 'myBoolConverter.TrueValue = System.Windows.Visibility.Visible' en lugar de, por ejemplo, la cadena" Visible "? – Heinzi

+0

@Heinzi - Sí, esa es una cosa a la que te rindes. Tendría que definir explícitamente los valores. Actualizaré mi respuesta. – CodeNaked

+0

@Heinzi - Actualizado. – CodeNaked

1

Me basta con utilizar dos clases,

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

O voy a pasar un parámetro del convertidor llamado "inversa"

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

A continuación, puede comprobar inversa que se pasa en ConverterParameter y volver visible en falso .

Puede pasar cualquier cosa en ConverterParameter o también puede estar vinculado a algo que pueda controlar su lógica.