2009-08-13 3 views
4

In Windows Forms (.NET 2.0, Visual Studio 2005 SP1): Ich habe eine getippte DataSet, mit einer Spalte, die System.Boolean ist, die Nullable ist und der Standardwert ist DBNull. Ich habe eine Form, die ein CheckBox Steuerelement enthält, das ich an den vorherigen Wert der Spalte binden möchte.Wie binden Sie eine CheckBox an eine bool-typisierte DbColumn, die keine NULL-Werte zulässt?

  • Ich habe versucht, die Checked Eigenschaft auf die Spalte über den Designer zu binden: es funktioniert super, nur dann, wenn der Standardwert für die Spalte entweder True oder False gesetzt.
  • Ich habe versucht, die CheckState Eigenschaft auf die Spalte über den Designer zu binden, und meine eigenen Format und Parse Event-Handler Anbringen aber sie nie aufgerufen:

    b.Format+=delegate(object sender, ConvertEventArgs cevent) { 
        cevent.Value=DoFormat((CheckState)cevent.Value); // cf. end of the question 
    }; 
    b.Parse+=delegate(object sender, ConvertEventArgs cevent) { 
        cevent.Value=DoParse(cevent.Value); // cf. end of the question 
    }; 
    
  • Ich habe Binding eine benutzerdefinierte zu schaffen versucht, Beispiel im Code, fügen sie meine Event-Handler und es die CheckBox Bindungen hinzufügen: die Event-Handler genannt noch nie bekommen ...

    Binding b=new Binding("CheckState", _BindingSource, "MyColumn", false, DataSourceUpdateMode.OnPropertyChanged, DBNull.Value); 
    

Als ein Hinweis: ein DBNull Wert ist nur akzeptabel, wenn aus dem DataSet kommen (es bedeutet, der Wert wurde nie festgelegt). Der Benutzer sollte jedoch nur den Wert True oder False über die CheckBox festlegen können.

Als Referenz hier ist der Code der Parsen und Formatierungsmethoden:

internal static CheckState DoParse(object value) 
{ 
    if ((value==null) || (value is DBNull)) 
     return CheckState.Indeterminate; 

    bool v=Convert.ToBoolean(value); 
    return (v ? CheckState.Checked : CheckState.Unchecked); 
} 

internal static object DoFormat(CheckState value) 
{ 
    switch (value) 
    { 
    case CheckState.Checked: 
     return true; 
    case CheckState.Indeterminate: 
     return DBNull.Value; 
    case CheckState.Unchecked: 
     return false; 
    } 

    return null; 
} 
+0

Ich habe hinzugefügt Informationen über ** warum es * bis zum Ende meiner Antwort funktioniert. –

Antwort

7

Haben Sie versucht CheckBox.CheckState an die Datacolumn Bindung ohne Befestigung mit der Bindung an Parse und Format Ereignisse oder messing?

Leider habe ich keine Instanz von Visual Studio 2005 zur Verfügung, aber ich stelle eine schnelle Form in Visual Studio 2008 und es hat genau, was Sie angegeben:

Als Anmerkung: ein DBNull Wert ist nur akzeptabel, wenn es aus dem DataSet kommt (dh der Wert wurde nie gesetzt). Der Benutzer sollte den Wert jedoch nur über die CheckBox auf True oder False setzen können.

Ich kann das Parse, Format oder Bindung im Weg oder es kann sein, dass Windows Forms anders als im Jahr 2008 verhält sich in 2005


UPDATE 18. August: Es funktioniert auf Visual Studio 2005 auch durch den Designer und durch Code. Hier ist der Code, es funktioniert demonstriert:


using System; 
using System.Data; 
using System.Drawing; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 { 
    public partial class Form1 : Form { 
     DataTable table = new DataTable(); 
     public Form1() { 
      InitializeComponent(); 

      //Creates the table structure 
      table.Columns.Add("Name", typeof(string)); 
      table.Columns.Add("MyColumn", typeof(bool)); 

      //Populates the table with some stuff 
      for (int i = 0; i < 5; i++) { 
       table.Rows.Add(i.ToString()); 
      } 

      //Creates the controls and puts them on the form. 
      TextBox textBox = new TextBox(); 
      textBox.Location = new Point(10, 10); 
      textBox.DataBindings.Add("Text", table, "Name"); 

      CheckBox checkBox = new CheckBox(); 
      checkBox.Left = textBox.Left; 
      checkBox.Top = textBox.Bottom + 10; 

      //Without true on the last argument, it will not work properly. 
      checkBox.DataBindings.Add("CheckState", table, "MyColumn", true); 

      Button previous = new Button(); 
      previous.Text = ""; 
      next.Top = previous.Top; 
      next.Left = previous.Right + 5; 
      next.Click += new EventHandler(next_Click); 

      this.Controls.AddRange(new Control[] { textBox, checkBox, previous, next }); 
     } 

     void next_Click(object sender, EventArgs e) { 
      this.BindingContext[this.table].Position++; 
     } 

     void previous_Click(object sender, EventArgs e) { 
      this.BindingContext[this.table].Position--; 
     } 
    } 
} 


UPDATE 23. August:

Warum es

Bindung hat eine private Methode arbeitet format genannt, die für den Erhalt verantwortlich ist eine Darstellung des Wertes, der von der Datenquelle kommt und für die Anzeige auf dem Steuerelement geeignet ist.

Wenn die Formatierung aktiviert ist, Binding.FormatObject() wird durch einen Codepfad ausführen, die eventuell Handler aufrufen werden Sie für die Binding.Format Veranstaltung. Wenn ein Handler den Wert ändert, der über ConvertEventArgs.Value von der Datenquelle an das Steuerelement weitergegeben wird, wird dieser Wert verwendet. Andernfalls ruft es einen Standardformatierer namens FormatObject für eine interne Klasse namens System.Windows.Forms.Formatter auf.

Die Kommentare zu dem Quellcode Zustand:

„Die eigentliche Umwandlung der Arbeit innerhalb FormatObjectInternal geschieht()“

Die Kommentare für FormatObjectInternal Zustand:

„Führen einige Sonderfallkonvertierungen (zB . Boolean to CheckState) "

Innerhalb von FormatObjectInternal überprüft es, ob der Wert von der Datenquelle Null oder DBNull ist und wenn dies der Fall ist, überprüft es, ob der Typ von Die gebundene Eigenschaft ist CheckState. Wenn das der Fall ist, gibt es CheckState.Indeterminate zurück.

Wie Sie sehen können, ist dies ein solcher gemeinsamer Fall, dass es eine Überraschung ist es nicht unter Windows funktionierte 1.x Forms Zum Glück hat das auf 2.0 und darüber hinaus behoben.

+0

Ich denke, es wäre meinem Kopf verletzt (viel) ein boolean Daten an einen Aufzählungstyp zu binden (mit 3 möglichen Werten!), Aber ich werde es doch aus Neugier versuchen ... – Mac

+0

ich auf Visual Studio 2005 versucht, und es hat auch gearbeitet. Sowohl über den Designer und über Code. –

+0

Ihr Beispiel funktioniert, ist aber für diese Frage nicht korrekt. @Mac will "DBNull kann von Zeile zu Steuerelement gefüllt werden, aber nicht von Steuerelement zu Zeile gefüllt werden". Die Datenbindung zwischen "MyColumn" und "CheckState" erreicht dies nicht. Für korrektes Verhalten müssen Sie das Format/Parse-Ereignis haken und den übergebenen Wert bearbeiten. - Wenn es ein Szenario ist, wie @Max häufig geschrieben hat, ist es besser, eine wiederverwendbare Lösung zu verwenden. – TcKs

1

Der einfachste Weg ich weiß, ist von CheckBox-Klasse abgeleitet werden, fügen Sie „Datavalue“ Eigenschaft, die DBNull-Werte verarbeiten kann und binden die Daten zu „Datavalue“ Eigenschaft:

public class DataCheckBox : CheckBox { 
    public virtual object DataValue { 
     get { return this.Checked; } 
     set { 
      if (value == null || value is DBNull) { 
       this.CheckState = CheckState.Indeterminate; 
      } 
      else { 
       this.Checked = (bool)value; 
      } 
     } 
    } 
} 
+0

Nun, das ist eine clevere ein ... – Mac

+0

Clever, aber nicht wirklich notwendig, da CheckBox unterstützt Datenbindung an NULLABLE (DBNull) Spalten, wie ich unter Beweis gestellt. –

Verwandte Themen