2017-04-06 1 views
-1

ich ein Optionsfeld Boolean haben Konverter Klasse integer:Boolean Integer-Konverter Problem, wenn sie von Ansichtsmodell gesetzt

public class RadioBoolToIntConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
          CultureInfo culture) 
    { 
     int integer = (int)value; 
     if (integer == int.Parse(parameter.ToString())) 
      return true; 
     else 
      return false; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, 
           CultureInfo culture) 
    {    
     return parameter; 
    } 
} 

Ich habe zwei Radio-Buttons in einem Stackpanel auf eine Eigenschaft „TestTypeRef“ gebunden:

<StackPanel Orientation="Horizontal"> 
    <RadioButton 
     Content="Screening" 
     Margin="0 0 10 0" 
     IsChecked="{Binding Path=TestTypeRef, Mode=TwoWay, Converter={StaticResource RadioBoolToIntConverter}, ConverterParameter=0 }" /> 
    <RadioButton 
     Content="Full" 
     Margin="0 0 10 0" 
     IsChecked="{Binding Path=TestTypeRef, Mode=TwoWay, Converter={StaticResource RadioBoolToIntConverter}, ConverterParameter=1 }" /> 
</StackPanel> 

Das Problem tritt auf, wenn ich versuche, den Wert der Eigenschaft, an die die Radiobuttons gebunden sind, im zugehörigen ViewModel festzulegen.

Wenn ich den Wert von 0 bis 1 einstellen - das ist in Ordnung.

Wenn ich den Wert von 1 auf 0 gesetzt - Wert der Eigenschaft bleibt 1:

Im Inneren des Ansichtsmodell:

// Set the default test type. 
TestTypeRef = 0; 
// ~~> TestTypeRef = 0 
TestTypeRef = 1; 
// ~~> TestTypeRef = 1   
TestTypeRef = 0; 
// ~~> TestTypeRef = 1 i.e. no change. 

Vielen Dank für jede Hilfe, die Sie anbieten können.

Update: Vielen Dank sowohl @Rachel und @Will für ihre Rückmeldung. Die ConvertBack-Routine war fehlerhaft. Dies hat es behoben:

+0

In Ihrer 'ConvertBack' Methode des Wandlers liefert immer den Wert des' ConverterParameter', so ist es immer 0 oder 1 sein würde, je nachdem, was Sie es in der Benutzeroberfläche festgelegt. Das scheint falsch zu sein und riecht, als hätte es etwas mit dem zu tun, was Sie beobachten. Sie sollten die ConvertBack-Methode korrekt implementieren oder sehen, was dort passiert, wenn Sie auf die Benutzeroberfläche zurückkehren. – Will

+0

Hallo @Will. Yep - Fehler in der ConvertBack-Methode. Vielen Dank für Ihren Kommentar. – AndyS

Antwort

1

Ich denke, man kann falsch einen Konverter verwenden, aber ich bin nicht sicher, ob ich Ihre ursprüngliche Prämisse zu verstehen.

Ein Konverter wird verwendet, um einen gebundenen Wert in einen anderen Typ zu konvertieren. Also, was Ihr Konverter sagt, wenn es die Eigenschaft aus dem UI für IsChecked liest, ist

„Grenzwert vergleichen (TestTypeRef) mit dem Parameter angegeben. Wenn die gleiche, überprüfen Sie den Radiobutton“

Es sagt auch, dass, wenn die umgekehrte Umwandlung zu tun (den IsChecked Wert zurück an den gebundenen Wert schreiben (TestTypeRef), nur

„den Parameterwert zurückzuschicken“

Also, um die Logik zu tun ...

Wenn bindet die UI die Werte die IsChecked Eigenschaft

 
If TestTypeRef is equal to 0 

    Radio 0 is checked because the value equals the parameter (0) 
    Radio 1 is unchecked because the value does not equal the parameter (1) 

If TestTypeRef is equal to 1 

    Radio 0 is unchecked because the value does not equals the parameter (0) 
    Radio 1 is checked because the value equals the parameter (1) 

Jetzt kommt das Problem in für Ihre Reverse lesen Bindung, wenn sie einen Wert zurück an die Datenquelle schreibt

 
If Radio 0 is checked, write 0 to the datasource 
If Radio 0 is unchecked, write 0 to the datasource 
If Radio 1 is checked, write 1 to the datasource 
If Radio 1 is unchecked, write 1 to the datasource 

Wenn Wenn Sie den Wert der Datenquelle auf einen Wert setzen, löst dies eine Aktualisierung des IsChecked-Werts aus, der wiederum an die DataSource zurückgibt

 
Default : TestTypeRef = 0 
    Radio 0 is checked 
    Radio 1 is unchecked 

Set TestTypeRef = 1 
    Update Radio 0 Binding (Checked > Unchecked) 
    Update Radio 1 Binding (Unchecked > Checked) 

Because the IsChecked updates, it uses ConvertBack to update the data source. 
    If Radio 1 is checked, write 1 to the datasource 

Beachten Sie, dass zu diesem Zeitpunkt das Änderungsereignis für die Radio0-Bindung nicht ausgeführt wird, wahrscheinlich, weil es jetzt nichts geändert hat - Änderungsereignis wurde ausgelöst, aber der Wert wurde von 1 auf 1 geändert, sodass Code nicht ausgeführt wird um etwas zu aktualisieren.

Sie können dies bestätigen, indem Sie einen Breakpoint in Ihre ConvertBack-Methode einfügen. Sie werden feststellen, dass der Wert "1" erreicht wird, wenn Sie versuchen, den Wert auf 0 zu setzen. Ein anderer Haltepunkt im Setter von Zeigen Sie auch, dass der Wert zuerst auf 0 und dann wieder auf 1 geändert wird.

Lange Rede kurzer Sinn, reparieren Sie Ihren Konverter. Oder noch besser, fixieren Sie Ihr Design.

Von was ich sagen kann, Sie versuchen zu sagen, "wenn der gebundene Wert gleich einem Wert ist, isChecked ist wahr", aber aus dieser Anweisung können Sie nicht genau umgekehrt erhalten. Wenn der Benutzer den Radiobutton aktiviert, legen Sie den gebundenen Wert gleich dem Parameter fest. Wenn der Benutzer das Optionsfeld deaktiviert, hat er keine Ahnung, wofür der gebundene Wert festgelegt werden soll.

Also entweder

  1. Ihre Bindungen sie oneway ändern so nie ConvertBack und aktualisieren Sie die Datenquelle ausgeführt. Nicht ideal, wenn Sie möchten, dass Benutzer die Optionsfelder tatsächlich verwenden.
  2. Ihren gebundenen Wert ändern, damit es in der richtigen Art und Weise zu Anzeigedaten, wie zum Beispiel zwei Bool Eigenschaften genannt IsFull und IsScreening formatiert ist, die Sie direkt für diesen
  3. Implementieren Sie eine bessere Reihe von UI-Steuerelemente binden können. Meine persönliche Vorliebe ist eine ListBox bound to a single value and styled with RadioButtons, aber das könnte für einen im Wesentlichen einen bool Wert übertrieben sein.

Persönlich würde ich vorschlagen, 2 für Sie jetzt.

public bool IsScreening 
{ 
    get { return TestTypeRef == 0; } 
    set { if (value) TestTypeRef = 0; } 
} 

public bool IsFull 
{ 
    get { return TestTypeRef == 1; } 
    set { if (value) TestTypeRef = 1; } 
} 
+0

Vielen Dank, @Rachel, für einen ausgezeichneten Spaziergang. Die ConvertBack-Routine war fehlerhaft. Dies hat es behoben: Rückgabewert.Equals (falsch)? DependencyProperty.UnsetValue: Parameter; – AndyS

0

Wir müssen einen Konverter-Parameter verwenden, um anzugeben, welchen Wert ein Radio-Button entspricht. Wenn Ihre Eigenschaft diesem Wert entspricht, wird diese Schaltfläche aktiviert und andere Schaltflächen deaktiviert. Diese Lösung funktioniert unabhängig davon, ob Sie die GroupName-Eigenschaft festlegen oder nicht, obwohl Sie sie normalerweise festlegen sollten.

you can see the solution

Verwandte Themen