2010-10-20 16 views
76

Estoy tratando de unirse a una propiedad de entero:cómo pasar un entero como ConverterParameter?

<RadioButton Content="None" 
      IsChecked="{Binding MyProperty, 
         Converter={StaticResource IntToBoolConverter}, 
         ConverterParameter=0}" /> 

y mi Converter es:

[ValueConversion(typeof(int), typeof(bool))] 
public class IntToBoolConverter : IValueConverter 
{ 
    public object Convert(object value, Type t, object parameter, CultureInfo culture) 
    { 
     return value.Equals(parameter); 
    } 

    public object ConvertBack(object value, Type t, object parameter, CultureInfo culture) 
    { 
     return value.Equals(false) ? DependencyProperty.UnsetValue : parameter; 
    } 
} 

el problema es que cuando mi convertidor se llama el parámetro es una cadena. Necesito que sea un número entero. por supuesto, puedo analizar la cadena, pero ¿tengo que hacerlo?

gracias por cualquier ayuda konstantn

+1

¿Alguien sabe cómo lograr esto en la plataforma Windows Phone donde tenemos una sintaxis ligeramente diferente para las vinculaciones? {propiedad de unión, convertidor = {} StaticResource MYCONVERTER, ConverterParameter = INT_VAL} en este ejemplo INT_VAL será pasado como una cadena –

Respuesta

83

Here you go!

<RadioButton Content="None" 
      xmlns:sys="clr-namespace:System;assembly=mscorlib"> 
    <RadioButton.IsChecked> 
     <Binding Path="MyProperty" 
       Converter="{StaticResource IntToBoolConverter}"> 
      <Binding.ConverterParameter> 
       <sys:Int32>0</sys:Int32> 
      </Binding.ConverterParameter> 
     </Binding> 
    </RadioButton.IsChecked> 
</RadioButton> 

El truco consiste en incluir el espacio de nombres para los tipos básicos del sistema y luego escribir al menos la unión del ConverterParameter en forma de elemento.

+2

Esto no cambia el hecho de que el tipo de 'IValueConverter.Convert()' s * "parameter" * parameter es 'object'. Aún tiene que convertirlo/analizarlo ... –

+4

@djacobson - Es cierto, pero eso es lo que el atributo ValueConversion le permite especificar. No estoy seguro de si realmente se utiliza en tiempo de compilación o en tiempo de ejecución. En términos de la pregunta de los carteles originales, él especificó que "necesito que sea un número entero. Por supuesto que puedo analizar el hilo, ¿pero tengo que hacerlo?" Así que mi respuesta alivia eso, ya que no hay un análisis sintáctico de una cadena, sino solo el desempaquetado de un entero que todavía soy mucho más seguro. – jpierson

4

No utilice value.Equals. Uso:

Convert.ToInt32(value) == Convert.ToInt32(parameter) 
+5

¿Por qué no quieren usar 'value.Equals'? – Zack

0

que sería bueno para expresar de alguna manera la información de tipo para la ConverterValue en XAML, pero no creo que es posible a partir de ahora. Así que supongo que tienes que analizar el objeto convertidor a tu tipo esperado mediante alguna lógica personalizada. No veo otra manera.

36

Para completar, una solución más posible (tal vez con menos mecanografía): (. Por supuesto, Window puede ser reemplazado con UserControl, y IntZero puede definirse más cerca del lugar de uso real)

<Window 
    xmlns:sys="clr-namespace:System;assembly=mscorlib" ...> 
    <Window.Resources> 
     <sys:Int32 x:Key="IntZero">0</sys:Int32> 
    </Window.Resources> 

    <RadioButton Content="None" 
       IsChecked="{Binding MyProperty, 
            Converter={StaticResource IntToBoolConverter}, 
            ConverterParameter={StaticResource IntZero}}" /> 

24

No estoy seguro de por qué WPF personas tienden a ser reacios a usar MarkupExtension. Es la solución perfecta para muchos problemas, incluido el problema mencionado aquí.

public sealed class Int32Extension : MarkupExtension 
{ 
    public Int32Extension(int value) { this.Value = value; } 
    public int Value { get; set; } 
    public override Object ProvideValue(IServiceProvider sp) { return Value; } 
}; 

Si esta extensión de marcado está disponible en XAML espacio de nombres 'm', entonces el ejemplo de su creador original se convierte en:

<RadioButton Content="None" 
      IsChecked="{Binding MyProperty, 
         Converter={StaticResource IntToBoolConverter}, 
         ConverterParameter={m:Int32 0}}" /> 

Esto funciona porque el analizador extensión de marcado puede ver el tipo fuerte del argumento del constructor y convierta en consecuencia, mientras que el argumento ConverterParameter de Binding es (menos informativo) Object-typed.

+0

Creé una extensión similar aquí: http://stackoverflow.com/a/31993746/1254743 – Onur

+0

Gracias, eso fue útil. Será mi primera extensión XAML. Pero creo que es mejor hacer de 'Value' un' object' en lugar de 'int', para evitar incluirlo cada vez en' ProvideValue'. (Y luego, hazlo 'privado' para evitar asignar algo ilegal directamente). – Zeus

+1

@Zeus Normalmente, 'ProvideValue' solo se llama una vez por instancia de extensión de marcado, por lo que el boxeo solo debe ocurrir una vez. Al no hacerlo en el constructor, evito el boxeo si nunca se llama a 'ProvideValue'. En cuanto a hacer que 'Value' sea privado, esto impediría usar la extensión de marcado en la sintaxis del elemento de objeto' XAML': https://msdn.microsoft.com/en-us/library/ms788723(v=vs.100).aspx# object_element_syntax –

Cuestiones relacionadas