2008-09-24 3 views
12

Ich möchte einen konstanten Wert zu einer eingehenden gebundenen Ganzzahl hinzufügen. In der Tat habe ich mehrere Stellen, an denen ich an den gleichen Quellwert binden möchte, aber verschiedene Konstanten hinzufügen. So wäre die ideale Lösung so etwas wie diese ...WPF DataBinding mit einfacher arithmetischer Operation?

<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myInt, Constant=5}"/> 
<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myInt, Constant=8}"/> 
<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myInt, Constant=24}"/> 

(Hinweis: Dies ist ein Beispiel ist die Idee zu zeigen, ist mein eigentliches Bindung Szenario nicht auf die Leinwand Eigenschaft eines TextBox Aber dies zeigt die Idee. klarer)

Im Moment ist die einzige Lösung, die ich mir vorstellen kann, die Bereitstellung vieler verschiedener Quelleigenschaften, von denen jede eine andere Konstante zum selben internen Wert hinzufügt. So kann ich so etwas tun ...

<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myIntPlus5}"/> 
<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myIntPlus8}"/> 
<TextBox Canvas.Top="{Binding ElementName=mySource, Path=myIntPlus24}"/> 

Aber das ist ziemlich düster, weil ich in Zukunft halten muß möglicherweise neue Eigenschaften für neue Konstanten hinzufügen. Auch wenn ich die Wertschöpfung ändern muss, muss ich das Quellobjekt ändern, was ziemlich nett ist.

Es muss einen allgemeineren Weg geben als das? Irgendwelche WPF Experten haben irgendwelche Ideen?

Antwort

6

Ich glaube, dass Sie dies mit einem Wertkonverter tun können. Hier ist ein blog entry, der das Übergeben eines Parameters an den Wertkonverter in der XAML adressiert. Und this blog gibt einige Details zum Implementieren eines Wertkonverters.

+0

Die Tatsache der Werteumwandler einen Parameter nehmen kann, scheint wie ein guter Ansatz, um das Problem hier zu lösen. Danke für die Eingabe. –

0

Ich habe noch nie WPF verwendet, aber ich habe eine mögliche Lösung.

Kann Ihr Bindungspfad zu einer Karte zugeordnet werden? Wenn ja, sollte es dann in der Lage sein, ein Argument (der Schlüssel) zu nehmen. Sie müssten eine Klasse erstellen, die die Map-Schnittstelle implementiert, aber wirklich nur den Basiswert zurückgibt, den Sie initialisiert haben, die "Karte" mit dem Schlüssel hinzugefügt.

public Integer get(Integer key) { return baseInt + key; } // or some such 

Ohne eine gewisse Fähigkeit, die Zahl aus dem Tag zu passieren, sehe ich nicht, wie Sie es bekommen werden verschiedene Deltas vom ursprünglichen Wert zurückzukehren.

4

Die Verwendung eines Wertkonverters ist eine gute Lösung für das Problem, da Sie den Quellwert ändern können, während er an die Benutzeroberfläche gebunden ist.

Ich habe das folgende in ein paar Orten verwendet.

public class AddValueConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     object result = value; 
     int parameterValue; 

     if (value != null && targetType == typeof(Int32) && 
      int.TryParse((string)parameter, 
      NumberStyles.Integer, culture, out parameterValue)) 
     { 
      result = (int)value + (int)parameterValue; 
     } 

     return result; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Beispiel

<Setter Property="Grid.ColumnSpan" 
     Value="{Binding 
        Path=ColumnDefinitions.Count, 
        RelativeSource={RelativeSource AncestorType=Grid}, 
        Converter={StaticResource addValueConverter}, 
        ConverterParameter=1}" 
    /> 
18

Ich benutze ein MathConverter, dass ich mit allen einfachen arithmatic Operationen zu tun erstellt. Der Code für den Wandler ist here und es kann wie folgt verwendet werden:

<TextBox Canvas.Top="{Binding SomeValue, 
      Converter={StaticResource MathConverter}, 
      [email protected]+5}" /> 

Sie können es sogar mit erweiterten arithmatic Operationen verwenden wie

Width="{Binding ElementName=RootWindow, Path=ActualWidth, 
       Converter={StaticResource MathConverter}, 
       ConverterParameter=((@VALUE-200)*.3)}" 
+0

Nizza Konverter, aber das bricht, wenn der Wert eine negative Zahl ist. Eine schnelle Abhilfe wäre die Verwendung eines anderen Vorzeichens für Minus, nicht "-" und die Änderung der Operandenliste im MathConverter-Code. Eine echte Lösung würde natürlich mehr Logik beim Parsen hinzufügen. –

+0

@MaximZabolotskikh Eine negative Zahl ist nur '0 - @ VALUE', so dass Benutzer es einfach als das eingeben können. Oder als eine bessere Lösung, überprüfen Sie einfach ein "-" Symbol, wenn wir ein numerisches Token erwarten, und wenn es gefunden wird, es richtig analysieren. Ich denke, dass ich das tatsächlich in der Kopie des Konverters getan habe, den ich in meiner WPF-Bibliothek behalte ... – Rachel

+0

0 - @VALUE wird nicht funktionieren. Um genau zu sein, ich habe eine 0-basierte Liste und möchte den Text "Element x von y" zeigen, also binde ich index (x) als "@VALUE + 1". Die leere Liste gibt jedoch -1 als Index zurück, also wird sie -1 + 1, mathconverter teilt sich nach Operanden auf, als für minus wird die zweite Zahl nicht gefunden, so ähnlich. Also sollte etwas mehr Parsing gemacht werden. Aber im Grunde war der Zweck meines Kommentars nur ein mögliches Problem für irgendjemanden aufzuzeigen, der diesen Code in Zukunft verwenden könnte. Es ist sowieso ein hilfreicher Konverter. –