2010-10-20 11 views
76

Sto cercando di legarsi a una proprietà intero:come passare un intero come ConverterParameter?

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

e il mio convertitore è:

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

il problema è che quando il mio convertitore viene chiamato il parametro è stringa. ho bisogno che sia un numero intero naturalmente posso analizzare la stringa, ma devo?

Grazie per qualsiasi aiuto Konstantin

+1

Qualcuno sa come ottenere questo su piattaforma Windows Phone in cui abbiamo una sintassi leggermente diversa per i binding? {associazione di proprietà, convertitore = {} StaticResource MYCONVERTER, ConverterParameter = INT_VAL} in questo esempio INT_VAL verrà passato come stringa –

risposta

83

Ecco qua!

<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> 

Il trucco è quello di includere il namespace per i tipi di base del sistema e poi di scrivere almeno vincolante il ConverterParameter in forma elemento.

+2

Questo non cambia il fatto che il tipo di parametro 'IValueConverter.Convert()' s * "parametro" * è 'object'. Devi ancora scriverlo/analizzarlo ... –

+4

@djacobson - Vero ma questo è quello che l'attributo ValueConversion ti permette di specificare. Non è esattamente sicuro se questo è realmente usato da compilare in tempo reale o in fase di esecuzione. In termini di domande sui poster originali, ha specificato che "ho bisogno che sia un numero intero, ovviamente posso analizzare la stringa, ma devo?" Quindi la mia risposta allevia che in questo non c'è parsing di una stringa ma solo l'unboxing di un intero che io sono ancora molto più sicuro. – jpierson

4

Non utilizzare value.Equals. Usa:

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

Perché non si desidera utilizzare 'value.Equals'? – Zack

0

sarebbe bello per esprimere in qualche modo le informazioni sul tipo per il ConverterValue in XAML, ma non credo sia possibile, al momento. Quindi suppongo che devi analizzare l'oggetto Converter in base al tuo tipo previsto con una logica personalizzata. Non vedo un altro modo.

36

Per completezza, un'altra possibile soluzione (magari con meno battitura): (. Naturalmente, Window può essere sostituito con UserControl e IntZero può essere definita più vicino al luogo di utilizzo effettivo)

<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

Non sono sicuro del motivo per cui le persone WPF tendono ad essere poco inclini all'utilizzo di MarkupExtension. È la soluzione perfetta per molti problemi incluso il problema menzionato qui.

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

Se questa estensione di markup è disponibile in XAML namespace 'm', allora l'esempio del manifesto originale diventa:

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

Questo funziona perché il parser estensione di markup può vedere il forte tipo di argomento del costruttore e converti di conseguenza, mentre l'argomento di Binding's ConverterParameter è (meno informativamente) tipizzato da un oggetto.

+0

Ho creato un'estensione simile qui: http://stackoverflow.com/a/31993746/1254743 – Onur

+0

Grazie, è stato utile. Sarà la mia prima estensione XAML. Ma penso che sia meglio rendere 'Value' un' object' piuttosto che 'int', per evitare di inscatolarlo ogni volta in' ProvideValue'. (E poi, rendilo 'private' per evitare di assegnare qualcosa di illegale direttamente). – Zeus

+1

@Zeus In genere 'ProvideValue' viene chiamato solo una volta per ogni istanza dell'estensione di markup, quindi la boxe dovrebbe essere eseguita solo una volta. Non facendolo nel costruttore, evito del tutto la boxe se 'ProvideValue' non viene mai chiamato. Per quanto riguarda la privazione di 'Value', questo preclude l'uso dell'estensione di markup nella sintassi dell'elemento dell'oggetto' XAML': https://msdn.microsoft.com/en-us/library/ms788723(v=vs.100).aspx# object_element_syntax –

Problemi correlati