2010-10-20 3 views
76

Ich versuche, auf eine ganze Zahl Eigenschaft zu binden:Wie übergibt man eine Ganzzahl als ConverterParameter?

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

und mein Konverter ist:

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

das Problem ist, dass, wenn mein Konverter der Parameterzeichenfolge aufgerufen wird. Ich brauche es eine Ganzzahl zu sein. natürlich kann ich die string parsen, aber muss ich?

Dank für jede Hilfe konstantin

+1

Weiß jemand, wie man dies auf Windows Phone-Plattform erreichen kann, wo wir etwas unterschiedliche Syntax für Bindungen haben? {Binding PROPERTY, Konverter = {StaticResource MYCONVERTER}, ConverterParameter = INT_VAL} In diesem Beispiel wird INT_VAL als String übergeben –

Antwort

83

Hier geht's!

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

Der Trick ist, den Namensraum für die Grundsystemtypen aufzunehmen und dann zu schreiben, zumindest das in Converterelementform zu binden.

+2

Das ändert nichts daran, dass der Typ des Parameters 'IValueConverter.Convert()' s * "Parameter" * "Objekt" ist. Sie müssen es immer noch konvertieren/analysieren ... –

+4

@djacobson - True, aber das können Sie mit dem ValueConversion-Attribut festlegen. Nicht genau, ob dies wirklich zur Kompilierungszeit oder zur Laufzeit überhaupt verwendet wird. In Bezug auf die ursprüngliche Posterfrage stellte er fest, dass "ich brauche, dass es eine Ganzzahl ist. Natürlich kann ich die Zeichenkette analysieren, aber muss ich das?" Meine Antwort lindert also, dass es kein Parsen einer Zeichenkette gibt, sondern nur das Unboxing einer Ganzzahl, die ich noch viel sicherer bin. – jpierson

4

Sie value.Equals nicht verwenden. Verwendung:

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

Warum möchten Sie nicht 'value.Equals' verwenden? – Zack

0

Es wäre schön, irgendwie für die ConverterValue in XAML die Typinformationen zum Ausdruck bringen, aber ich glaube nicht, dass es ab sofort möglich ist. Also denke ich, dass Sie das Converter-Objekt durch eine benutzerdefinierte Logik zu Ihrem erwarteten Typ analysieren müssen. Ich sehe keinen anderen Weg.

36

Der Vollständigkeit halber eine weitere mögliche Lösung (vielleicht mit weniger Tipp): (. Natürlich Window mit UserControl ersetzt werden, und IntZero kann näher an den Ort der tatsächlichen Nutzung definiert werden)

<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

Nicht sicher warum WPF Leute neigen dazu, zur Verwendung MarkupExtension abgeneigt zu sein. Es ist die perfekte Lösung für viele Probleme einschließlich des hier genannten Problems.

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

Wenn diese Markup-Erweiterung in XAML Namespace ‚m‘ zur Verfügung steht, dann das Beispiel der Original-Poster wird:

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

Das funktioniert, weil der Markup-Erweiterung Parser den starken Typen des Konstruktorargument sehen und konvertieren Sie entsprechend, während Binding ConverterParameter Argument (weniger informativ) Object-typed ist.

+0

Ich habe eine ähnliche Erweiterung hier erstellt: http://StackOverflow.com/a/31993746/1254743 – Onur

+0

Danke, das war nützlich. Es wird meine erste XAML-Erweiterung sein. Aber ich denke, es ist besser, "Value" zu einem "Objekt" anstatt zu "int" zu machen, um es nicht jedes Mal in "ProvideValue" zu verpacken. (Und dann, machen Sie es "privat", um zu vermeiden, dass etwas direkt illegal zugewiesen wird). – Zeus

+1

@Zeus Normalerweise wird 'ProvideValue' nur einmal pro Markup-Erweiterungsinstanz aufgerufen, daher sollte das Boxen nur einmal ausgeführt werden. Wenn ich das nicht im Konstruktor mache, vermeide ich das Boxen, wenn 'ProvideValue' nie aufgerufen wird. Was den Wert "privat" betrifft, würde dies die Verwendung der Markuperweiterung in der Syntax des XAML-Objektelements verhindern: https://msdn.microsoft.com/en-us/library/ms788723(v=vs.100).aspx# object_element_syntax –