2008-12-05 4 views
8

Ich habe ein Binärfeld in meiner Datenbank, das auf einer Benutzeroberfläche nur schwer mit einem einzigen "Is XXXX?" - Kontrollkästchen zu beschreiben ist. Ich würde lieber ein Paar Optionsfelder verwenden (z. B. "Do it the Foo way" und "Do not the bar way"), aber im Moment sind alle anderen Felder in meinem Formular datengebunden an ein Geschäftsobjekt. Ich möchte auch das Radiobutton-Paar an das Business-Objekt binden, aber ich habe noch keinen guten Weg gefunden, es zu tun. Ich kann eine der Schaltflächen an das Feld binden, so dass das Feld "True" festgelegt wird, wenn die Schaltfläche ausgewählt ist, während die Auswahl der anderen Schaltfläche die erste deaktiviert (dh die beiden Optionsfelder sind ordnungsgemäß verknüpft)), der Wert des Feldes wird nicht aktualisiert, um dies zu reflektieren.Wie verwende ich Datenbindung mit Windows Forms-Optionsfeldern?

Ich mag würde in der Lage sein

button1.DataBindings.Add(new Binding("checked", source, "useFoo")); 
button2.DataBindings.Add(new Binding("checked", source, "!useFoo")); 

zu sagen, aber ich bin mir ziemlich sicher, dass werfen, wenn es läuft. Gibt es einen einfacheren Weg, oder sollte ich nur darüber nachdenken, wie man ein einzelnes Kontrollkästchen anspricht? Ich möchte keine zusätzlichen Funktionen hinzufügen, um etwas mit diesem trivialen ...

ETA: Ein Kommentator hat vorgeschlagen, ein Dropdown (ComboBox) zu berücksichtigen. Ich hatte darüber nachgedacht, aber wie würde ich das an ein boolesches Feld in einer Datenbank/Eigenschaft in einem Geschäftsobjekt binden? Wenn ich das SelectedItem an die useFoo -Eigenschaft binden würde, was würde dann in der Items-Auflistung passieren? Muss ich nur "True" und "False" hinzufügen, oder könnte ich irgendwie ein Schlüssel/Wert-Paar-Objekt hinzufügen, das ein angezeigtes Objekt ("Use Foo"/"Do not Use Foo") an den booleschen Wert dahinter bindet? Ich habe Probleme, Dokumente zu diesem Thema zu finden.


Über die Antwort ein: die Lösung, die ich involviert das Business-Objekt mit Liquidation modifizieren - die Grundidee ist sehr ähnlich dem von Gurge geschrieben, aber ich kam mit ihm getrennt, bevor ich seine Antwort lesen. Kurz gesagt, ich habe eine separate Eigenschaft hinzugefügt, die einfach !useFoo zurückgibt. Ein Optionsfeld ist an source.UseFoo gebunden und das andere ist an source.UseBar (der Name der neuen Eigenschaft) gebunden. Es ist wichtig, sicherzustellen, dass die neue Eigenschaft sowohl Getter als auch Setter hat, oder Sie werden mit wirklich merkwürdigem Verhalten enden.

Antwort

1

Ich habe einen Weg gefunden, dies mit DataSet/DataTable zu tun.

Ich mache eine berechnete Spalte in der DataTable mit dem Ausdruck IIF (Foo = true, false, true). Nennen wir diese Spalte Bar.

Balken ist vom Typ Boolean. Jetzt können Sie einen Radiobutton an Foo und einen an Bar binden.

Um Bar Überprüfung/unchecking zu Foo propagieren zurück Sie auf die erzeugte Datentabelle Code gehen und eine Zeile, die letzte in dieser Probe hinzu:

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
     public bool Bar { 
      get { 
       try { 
        return ((bool)(this[this.tableradio.BarColumn])); 
       } 
       catch (global::System.InvalidCastException e) { 
        throw new global::System.Data.StrongTypingException("The value for column \'Bar\' in table \'radio\' is DBNull.", e); 
       } 
      } 
      set { 
       this[this.tableradio.BarColumn] = value; 
       this[this.tableradio.FooColumn] = !value; 
      } 
     } 
+2

Und vergessen Sie nicht, diese Änderung jedes Mal erneut vorzunehmen, wenn Sie Ihr DataSet bearbeiten! :-( – Mac

-3

Sie sollten nur eines der Steuerelemente binden müssen, solange Sie sicherstellen, dass sie in derselben Gruppe sind.

Sie könnten auch einen DropDown betrachten.

+1

Versuchen Sie Folgendes: Erstellen Sie ein Optionsfeld und ein Kontrollkästchen und binden Sie ein Optionsfeld und das Kontrollkästchen an dieselbe boolsche Eigenschaft unter einer Bindungsquelle. Aktivieren Sie das Kontrollkästchen und schalten Sie die Radios ein - nichts passiert. Wenn Sie nun das Kontrollkästchen deaktivieren, können Sie es aktivieren, aber nie ausschalten. – Coderer

1

Wenn Ihr Business-Objekt implementiert INotifyPropertyChanged (die macht bindende Arbeit netter), Sie können den folgenden Code der visuellen Schnittstelle hinzufügen, wo BO Ihr Geschäftsobjekt ist und mit events deklariert wird und BO.Value ist die boolesche Eigenschaft, an die Sie binden möchten.

Public Property NotValue() As Boolean 
    Get 
     Return Not BO.Value 
    End Get 
    Set(ByVal value As Boolean) 
     BO.Value = Not value 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NotValue")) 
    End Set 
End Property 


Private Sub BO_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Handles BO.PropertyChanged 
    If e.PropertyName = "Value" Then 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NotValue")) 
    End If 
End Sub 

Die folgenden Bindungen verbinden die Optionsfelder.

Die visuelle Schnittstelle sollte auch INotifyPropertyChanged implementieren. Diese Methode funktioniert auf beide Arten: Der ursprüngliche Wert wird aktualisiert, wenn sich die Schnittstelle ändert, und wenn sich der ursprüngliche Wert ändert, wird die Schnittstelle korrekt aktualisiert.

5
  1. Bind die RadioButton, die direkt auf Ihrem boolean Wert verknüpft ist (dh überprüft wird, wenn der Wert true).
  2. ein Event-Handler zum CheckedChanged Ereignisse auf diesen RadioButton hinzufügen, die wie folgt aussieht:

    private void radioButton_CheckedChanged(object sender, EventArgs e) 
    { 
        foreach (Binding b in ((Control)sender).DataBindings) 
         b.WriteValue(); 
    } 
    
1

ich über das gleiche Problem kam, und fand heraus, es mit Standard-Datenbindung tatsächlich möglich ist:

button1.DataBindings.Add(new Binding("checked", source, "useFoo", false, DataSourceUpdateMode.OnPropertyChanged); 
// no need to databind button 2, since button1.checked 
// is set to false when button2 is checked 

Standardmäßig ist DataSourceUpdateMode auf OnValidation eingestellt. Durch Setzen auf OnPropertyChanged wird die Änderung sofort an das datengebundene Objekt weitergegeben.

Mein Geschäftsobjekt implementiert INotifyPropertyChanged;

Beim Testen dieser Lösung stellte ich fest, dass mein Ereignis zweimal ausgelöst wurde, als ich auf klickte. Um dies zu verhindern, setzen Sie einfach

button1.CausesValidation = false; 
button2.CausesValidation = false; 

wie hier gezeigt: TextBox leave causes PropertyChanged get fired twice

1

Sie es manuell in Code. Wenn Sie das Formular laden, setzen Sie Ihre Optionsfelder entsprechend Ihrer Datenbank. Wenn Sie eine "Speichern" -Taste drücken, speichern Sie den Status wie gewünscht. In diesem Beispiel werden Funkgeräte als Bitfelder in der Datenbank gespeichert.

 // Load radio state 
     radioButton1.Checked = ((myModel)myBindingSource.DataSource).boolOption1; 
     radioButton2.Checked = ((myModel)myBindingSource.DataSource).boolOption2; 

-

 // Save radio state 
     ((myModel)myBindingSource.DataSource).boolOption1 = radioButton1.Checked; 
     ((myModel)myBindingSource.DataSource).boolOption2 = radioButton2.Checked; 

Ich habe versucht, Elemente aus dem "Datenquellen" Panel in Visual Studio 2015 zu ziehen, wenn ich meine Radio-Buttons als booleans in der Tabelle definiert, aber es gibt Probleme mit den booleans nicht wird auf false aktualisiert, wenn ein anderer Radiobutton ausgewählt wird. Beim Wechsel zwischen "causesValidation" und "false radiobuttons" wird beim Wechsel zwischen anderen Texteingabefeldern automatisch die Markierung deaktiviert.

Verwandte Themen