2009-05-04 5 views
1

Ich fülle Elemente aus einer XML-Datei mit einer DataTable in meine ComboBox. Momentan habe ich es so eingestellt, dass eine Spalte ComboBox's DisplayMember und eine andere Spalte ist Value Member. Dies funktioniert jedoch nicht immer für mich, da ich den Parameter selectedItem setzen muss und value member möglicherweise nicht eindeutig ist.DataRow als Wertelement für ComboBox festlegen

Ich weiß nicht, ob es ein Duplikat des Wertelements in der Tabelle oder nicht gibt, also meine Idee war, dass ich gesamte DataRow als Wert Mitglied der ComboBox setzen und dann ComboBox.SelectedITem = (DataRow) some_data_row; zum Auswählen, und es würde immer das richtige ComboBox-Objekt auswählen.

Wie würde ich das erreichen? Gibt es einen besseren Weg, dies zu tun? Ich bin offen für Vorschläge, aber es ist sehr wichtig, dass ich zu beiden, Anzeige Mitglied und Wert Mitglied kann.

Vielen Dank für Ihre Hilfe!

EDIT: Vielleicht war ich vorher nicht klar genug, aber während ich frage, ob dies hier der beste Ansatz ist, habe ich auch fragen mich, wie dies zu tun. Wenn ich den valueMember-Parameter nicht setze, ist das SelectedItem vom DataRowView-Typ ... Bitte beachten Sie, dass ich den selectedValue-Parameter verwenden möchte, um Elemente aus ComboBox auszuwählen, und wenn ich das versuche, ohne den Wert member explizit festzulegen Ausnahme wird ausgelöst.

Antwort

0

Zunächst einmal danke Adam Robinson, ich bin sicher, deine Antwort war richtig, aber es war einfach nicht das, was ich hören wollte. Ich habe mein Problem auf eine andere Art und Weise gelöst und denke, dass es für jemand anderen nützlich sein könnte, also poste ich es hier.

Ich habe eine neue Klasse erstellt, in meinem Fall nannte ich sie ListObject, die eine Eigenschaft DataRow hatte (wie Sie später sehen werden, funktioniert es auch für andere Typen, ich habe das nur benutzt, weil ich das eigentlich bin wollte als meine Artikelwert-Eigenschaft). Er überschreibt auch Methoden:

  • String toString()
  • bool Equals (object obj)
  • int GetHashCode() --is nicht in meinem Fall benötigt, aber Visual Studio
    Sie warnt es sich, außer Kraft gesetzt.

Die Idee war, dass ich ComboBox.Items Sammlungen mit Objekten meiner eigenen Klasse füllen könnte, eine benutzerdefinierte Zeichenfolge angezeigt werden (wenn ich es nicht funktioniert hatte, wie dies aus, meine nächste Frage auf Stack-Überlauf wäre wahrscheinlich über das Anpassen DisplayMembers beim Lesen von Elementen aus einer DataRow) und vergleichen Sie nur das Element einer Klasse (in meinem Fall DataRow).

Also hier ist der Code und es funktioniert gut (zumindest für das, was ich damit machen wollte).

public class ListObject 
{ 
    public DataRow element; 

    public String DisplayObject = null; 

    public ListObject(DataRow dr) 
    { 
     element = dr; 
    } 

    public ListObject(DataRow dr, String dspObject) 
    { 
     element = dr; 
     DisplayObject = dspObject; 
    } 

    public override String ToString() 
    { 
     if (DisplayObject == null) throw new Exception("DisplayObject property was not set."); 

     return element[DisplayObject].ToString(); 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj.GetType() == typeof(ListObject)) 
      return Equals(((ListObject)obj).element, this.element); 
     else return base.Equals(obj); 
    } 

    public override int GetHashCode() 
    { 
     return base.GetHashCode(); 
    } 
} 

In meinem Fall funktioniert es super, weil ich einfach die mit einer foreach-Anweisung des ComboBox füllen:

dtUsers.ReadXml(Program.Settings.xmlInputUsers); 

foreach(DataRow dr in dtUsers.Rows) 
{ 
    cmbUser.Items.Add(new ListObject(dr, "Name")); 
} 

Und wenn ich das DataRow bekommen wähle ich möchte ich dies nur tun:

cmbUser.SelectedItem = new ListObject(dlg.SelectedDataRow); 

Wo ich mich nicht um das DisplayMember usw. kümmern muss, weil nur DataRows verglichen werden, und Ihre Anzeigeparameter werden immer noch festgelegt, wenn Sie die ComboBox.Items-Auflistung gefüllt haben. Da die toString-Methode außer Kraft gesetzt wird, können Sie Ihre Ausgabe wirklich anpassen.

diese Klasse herzustellen war nur möglich, weil der Msdn Artikel auf ComboBox.SelectedItem Property, in der darauf hingewiesen wurde, dass SelectedItem Eigenschaft funktioniert die IndexOf-Methode. Diese Methode verwendet die Equals-Methode zum Bestimmen der Gleichheit.

1

Wenn Sie eine ListBox einen DataTable binden, Sie verbindlich, es tatsächlich zu einem DataView, die darstellt, dass DataTable (DataTable implementiert IListSource, und das gibt eine DataView). Sie können SelectedItem nicht direkt auf eine DataRow Instanz setzen, Sie müssen sie auf eine DataRowView Instanz setzen. Leider gibt es keine einfache Möglichkeit, eine DataRowView von einer DataRow zu erhalten.

Sie würden besser tun, nur alle Ihre Interaktionen durch eine DataRowView zu tun. Dadurch können Sie SelectedItem explizit festlegen.

Sie können die SelectedValue Eigenschaft nicht verwenden, dafür müssen Sie SelectedItem verwenden.

0

Dies ist die einfachste Art und Weise Datatable eine Combobox

private void load() { 
DataTable dt = // get data from DB 
comboBox1.ValueMember = null; // allows you to get all fields in the obj to combobox 
comboBox1.DisplayMember = "ccType";//label displayed from dt 
comboBox1.DataSource = dt; 
} 
//to test 
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 

     DataRowView current = (DataRowView)comboBox1.SelectedValue; 
     string drs = current.Row["ID"].ToString(); 

    } 
zu erhalten
Verwandte Themen