| Autor |
Beitrag |
dinazavric
      
Beiträge: 75
|
Verfasst: Di 26.04.11 15:30
Hallo,
als Anfänger habe ich eine Frage zur Data binding für ComboBox. Wie es für eine ComboBox funkzioniert habe ich schon rausgefunden:
C#-Quelltext 1: 2:
| P1_Name.DataSource = dataSet2.Tables["Parameters"].DefaultView; P1_Name.DisplayMember = "Parameter Name"; |
Was muss ich aber nun tun, wenn eine weitere ComboBox habe, die je nach Auswahl der P1_Name bspw. dazu gehörigen Werte beinhalten soll? Da gibt es im Internet gar nichts drüber (oder ich habe es nicht gefunden...)
Vielleicht muss ich noch dazu sagen, dass ich im dataSet2 zwei Tabellen habe, die voher schon über Relations verbunden wurden. Hier muss ich ja auch die Rows aus unterschiedlichen Tables verbinden... Was ich unter dem Strich brauche ist, dass bei der Auswahl won einem Parameter (Tabelle "Parameters") die dazu gehörigen Eigenschaften aufgelistet werden (Tabelle "Parameter Values"). Da gilt aber sie Relation von voher noch oder?
Ich habe schon viele Varianten versucht. Das letzte, das zumindest keine Fehlermeldung hatte war:
C#-Quelltext 1: 2: 3: 4: 5:
| P1_Name.DataSource = dataSet2.Tables["Parameters"].DefaultView; P1_Name.DisplayMember = "Parameter Name";
P1_Value.DataSource = dataSet2.Tables["Parameter Values"].DefaultView; P1_Value.DisplayMember = "Value Defenition"; |
Da kriege ich aber in der "P1_Value"-ComboBox alle möglichen Values aufgelistet, nicht aber die, die zum ausgewählten Parameter gehören...
Es muss doch ganz easy sein, das weis ich. Ich bitte um Hilfe :-/
Vielen Dank im Voraus!
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Di 26.04.11 16:36
Hallo,
so viel ich weiß, nützen dir dabei die Relationen nichts.
Du mußt selber das SelectedIndexChanged-Ereignis der ersten ComboBox behandeln und dann einen Filter auf die DataView der 2. ComboBox setzen:
C#-Quelltext 1: 2: 3:
| int id = (int)P1_Name.SelectedItem; DataView dataView = P1_Value.DataSource as DataView; dataView.RowFilter = "<spalte> = " + id; |
Für diesen Beitrag haben gedankt: dinazavric
|
|
dinazavric 
      
Beiträge: 75
|
Verfasst: Mi 27.04.11 10:32
Ich hoffe, ich habe es richtig umgesetzt:
C#-Quelltext 1: 2: 3: 4: 5: 6:
| private void P1_Name_SelectedIndexChanged(object sender, EventArgs e) { String selected = P1_Name.SelectedItem.ToString(); DataView dataView = P1_Value.DataSource as DataView; dataView.RowFilter = "Parameters = " + selected; } |
Nun kommt aber die Fehlermeldung: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt" und zwer bei der Definition vom String...
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 27.04.11 10:50
Hallo,
du mußt noch bei deiner ComboBox die Eigenschaft 'ValueMember' setzen, d.h. den Namen der Spalte.
Und dann die SelectedValue-Eigenschaft benutzen (sorry, hatte mich bei SelectedItem vertan).
Und am besten zusätzlich noch den SelectedValue in der Methode auf 'null' abfragen.
Und bei Strings als RowFilter mußt du noch Anführungsstriche setzen (wie bei SQL):
C#-Quelltext 1:
| dataView.RowFilter = "Parameters = '" + selected + "'"; |
P.S. CrossPost bitte immer möglichst angeben: www.mycsharp.de/wbb2...d.php?threadid=95059
(im anderen Forum sind im übrigen keine CrossPosts erlaubt, also nicht wundern, wenn der Thread dort bald zugemacht wird.)
Für diesen Beitrag haben gedankt: dinazavric
|
|
dinazavric 
      
Beiträge: 75
|
Verfasst: Mi 27.04.11 11:38
das habe ich eigentlich schon auch rausgefunden (ich meine die nachkommene Korrektur  ) Nun habe ich Folgendes:
C#-Quelltext 1: 2: 3: 4: 5: 6:
| dataSet2.Relations.Add("ParameterProperties", dataSet2.Tables["Parameters"].Columns["Parameter ID"], dataSet2.Tables["Parameter Values"].Columns["Parameter ID"]); P1_Value.DisplayMember = "ParameterProperties"; P1_Value.DataSource = dataSet2.Tables["Parameter Values"].DefaultView; String selected = P1_Name.SelectedValue.ToString(); DataView dataView = P1_Value.DataSource as DataView; dataView.RowFilter = "Parameters = '" + selected + "'"; |
In der ComboBox P1_Value wird aber gar nichts angezeigt... Vielleicht habe ich das falsche Filter. Die Relation wurde über Parameter ID erstellt und die P1_Name beinhaltet die Parameternamen dazu, also nicht die IDs, kann es daran liegen?
Komischerweise wenn ich P1_Name.SelectedValue.ToString() einer TextBox zuweise wird da gar nichts angezeigt, auch wenn da was ausgewählt wird... hmmm
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 27.04.11 12:46
Hallo,
wie schon geschrieben, setze noch den ValueMember:
C#-Quelltext 1:
| P1_Value.ValueMember = "Parameter ID"; |
(sofern dies ein String ist, sollte dein Code dann funktionieren 
Für diesen Beitrag haben gedankt: dinazavric
|
|
dinazavric 
      
Beiträge: 75
|
Verfasst: Mi 27.04.11 12:53
| Zitat: | | wie schon geschrieben, setze noch den ValueMember: |
passiert immer noch nichts. Also die zweite ComboBox ist einfach leer, egal was in der ersten passiert...
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 27.04.11 13:07
Ich sehe gerade, daß du natürlich auch die RowFilter-Spalte anpassen mußt:
C#-Quelltext 1:
| dataView.RowFilter = "Parameter ID = '" + selected + "'"; |
(ich hoffe mal, daß das Leerzeichen keine Probleme macht, ansonsten müßtest du die Spaltennamen mal ändern, d.h. am besten schon direkt in der Datenbank.)
Für diesen Beitrag haben gedankt: dinazavric
|
|
dinazavric 
      
Beiträge: 75
|
Verfasst: Mi 27.04.11 13:36
Da ich doch lieber mit dem Parameternamen als Parameter-ID arbeite, habe ich nun alles auf den Parameternamen umgestellt:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| dataSet2.Relations.Add("ParameterProperties", dataSet2.Tables["Parameters"].Columns["Parameter Name"], dataSet2.Tables["Parameter Values"].Columns["Parameter Name"]); P1_Value.DisplayMember = "ParameterProperties"; P1_Value.ValueMember = "Parameter Name"; P1_Value.DataSource = dataSet2.Tables["Parameter Values"].DefaultView; String selected = P1_Name.SelectedValue.ToString(); Test.Text = P1_Name.SelectedIndex.ToString(); DataView dataView = P1_Value.DataSource as DataView; dataView.RowFilter = "Parameter Name = '" + selected + "'"; |
Die P1_Value-ComboBox zeigt jetzt laute "System.Data.DataRowView" und zwar so viele, wie viele Values ich insgesammt habe, d.h. es wird immer noch nicht gefiltert. Bei einem Parameter sollten so 3-5 Vlaues kommen
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 27.04.11 14:26
Also ich muß zugeben, ich komme nicht ganz mit deinen Bezeichnungen klar.
So sollte es m.E. aussehen:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| P1_Name.DisplayMember = "Parameter Name"; P1_Name.ValueMember = "Parameter Id"; P1_Name.DataSource = dataSet2.Tables["Parameters"].DefaultView;
P1_Value.DisplayMember = "Value Name"; P1_Value.DataSource = dataSet2.Tables["Parameter Values"].DefaultView;
private void P1_Name_SelectedIndexChanged(object sender, EventArgs e) { int id = (int)P1_Name.SelectedValue; DataView dataView = P1_Value.DataSource as DataView; dataView.RowFilter = "Parameter Id = " + id; } |
So ich hoffe, du verstehst jetzt besser, was genau DisplayMember (Anzeige) und ValueMember (interner Wert) bedeuten...
P.S. Die Anzeige "System.Data.DataRowView" kriegst du, wenn der Spaltenname in "DisplayMember" nicht gefunden wird (da dann intern einfach die ToString()-Methode aufgerufen wird).
Für diesen Beitrag haben gedankt: dinazavric
|
|
dinazavric 
      
Beiträge: 75
|
Verfasst: Mi 27.04.11 14:50
ein kleiner Unterschied gibt es bei mir und zwar, dass ich nicht die ID, sondern den Namen in der ComboBox auswähle, deswegen habe ich bei mir stehen:
C#-Quelltext 1: 2: 3:
| String id = (String)P1_Name.SelectedValue; DataView dataView = P1_Value.DataSource as DataView; dataView.RowFilter = "Parameter Name = '" + id + "'"; |
Der Rest ist gleich und doch kommt nichts dabei raus auser sehr vielen "System.Data.DataRowView" eben...
andere Variante, die ich ausprobiert habe ist hier dargestellt:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| dataSet2.Relations.Add("ParameterProperties", dataSet2.Tables["Parameters"].Columns["Parameter Name"], dataSet2.Tables["Parameter Values"].Columns["Parameter Name"]);
P1_Name.DisplayMember = "Parameter Name"; P1_Name.ValueMember = "Parameter Name"; P1_Name.DataSource = this.dataSet2.Tables["Parameters"].DefaultView;
P1_Value.DisplayMember = "ParameterProperties"; P1_Value.ValueMember = "Value Name"; P1_Value.DataSource = this.dataSet2.Tables["Parameters"].DefaultView; |
Dabei geht es leider nicht ohne Fehler: "Eine Relation mit dem Namen 'ParameterProperties' ist bereits in diesem DataSet vorhanden", ansonsten wäre es gegangen, denke ich...
KORREKTUR: Die Fehlermeldung kommt nicht mehr, es wird auch die richtige Anzahl von Values im P1_Value angezeigt, leider aber wieder als "System.Data.DataRowView". Was ich auch noch gemerkt habe, wenn ich in P1_Value-ComboBox was ändere, also die "System.Data.DataRowView" durch scrolle, dann ändern sich auch die Werte im P1_Name-ComboBox, was nicht der Fall sein soll. Jetzt blick ich nicht mehr durch!
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 27.04.11 15:39
Hallo,
ist denn "ParameterProperties" wirklich eine Spalte deiner Tabelle???
Und du willst doch in der Values-ComboBox diese Daten aus der Tabelle "Parameter Values" anzeigen (und nicht aus der "Parameters" - wie die erste ComboBox), also
C#-Quelltext 1:
| P1_Value.DataSource = dataSet2.Tables["Parameter Values"].DefaultView; |
Und laß mal die Relation einfach weg (außer du verwendest den anderen Weg, wie ihn ProgrammierHans im anderen Forum gepostet hat - du mußt dich aber für einen dieser beiden entscheiden - beides geht nicht).
Irgendwie drehst du dich im Kreis, hast du überhaupt das Prinzip "DataBinding" verstanden?
Nimm einfach mal meinen Code und achte nur genau auf die Spaltennamen.
Am besten, du postest mal das Table-Layout.
Hier wie ich es verstehe:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| Parameters: - Parameter ID - Parameter Name
Parameter Values: - Value ID - Value Name - Parameter ID |
Und die Verbindung zwischen den beiden ComboBoxen sollte eben über die "Parameter ID" gehen (denn diese ist ja wohl eindeutig), also deshalb wird für 'ValueMember' und beim 'RowFilter' dieser Spaltenname benutzt (es ist völlig egal, was im 'DisplayMember' drinsteht, also was dort angezeigt wird).
Für diesen Beitrag haben gedankt: dinazavric
|
|
dinazavric 
      
Beiträge: 75
|
Verfasst: Mi 27.04.11 15:56
ich probiere gerne beides und da es mit der anderen Variante zumindest ein Bisschen was rauskommt, habe ich sie im Moment favorisiert. Bin aber auch gerne bei Deiner Variante dabei, falls es irgendwann mal funktionieren soll  Als Anfänger ist man doch neugierig alles auszuprobieren, was von Profies vorgeschlagen wird
Aber nun zu meiner Tabellen-Struktur. Ich habe folgende Tabellen in meinem DataSet2:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Protocols: - Protocol Name - Protocol ID
Parameters: - Protocol ID - Parameter ID - Parameter Name - Parameter Length
Parameter Values: - Parameter Name - Value ID - Value Name |
Dabei habe ich Parameter Name als Anbindungszeile genommen, da es für einen Benutzer doch einfacher ist aus einer Liste einen Namen rauszusuchen, statt mit irgendwelchen IDs zu arbeiten, die nichts aussagen. Rein technisch gesehen, hätte ich lieber mit IDs gearbeitet, da es deutlicher für mich als Programmer ist. Aber gut
Nun werde ich zu Deiner Variante zurück kommen und schauen ob ich da was übersehen habe... Was ich im Moment habe ist:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| P1_Name.DisplayMember = "Parameter Name"; P1_Name.ValueMember = "Parameter Name"; P1_Name.DataSource = this.dataSet2.Tables["Parameters"].DefaultView;
P1_Value.DisplayMember = "Value Name"; P1_Value.DataSource = this.dataSet2.Tables["Parameter Values"].DefaultView;
...
private void P1_Name_SelectedIndexChanged(object sender, EventArgs e) { if (P1_Name.SelectedValue != null) { String id = (String)P1_Name.SelectedValue.ToString(); DataView dataView = P1_Value.DataSource as DataView; dataView.RowFilter = "Parameter Name = '" + id + "'"; } } |
ICh hoffe, ich habe es richtig Interpretiert, was Du mir vorgeschlagen hast.
Nun kommt der Fehler beim RowFilter: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt", dabei habe ich doch genau danach beim if geschaut... Ohne Filter kommen schon die richtigen Daten raus, nur eben alle 
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Do 28.04.11 09:36
Hallo nochmal,
bei solchen Fehlern kannst du doch einfach debuggen (Haltepunkt setzen und dann Variablen anschauen).
Anscheinend ist 'dataView' gleich 'null', d.h. in 'P1_Value.DataSource' hast du doch keine DataView übergeben (hast du diesen Wert evtl. irgendwo wieder gelöscht?).
Für diesen Beitrag haben gedankt: dinazavric
|
|
dinazavric 
      
Beiträge: 75
|
Verfasst: Do 28.04.11 09:41
nein, habe ich nicht. Vor allem, wenn ich es richtig verstehe, würde "if" gar nicht behandelt, wenn es null wäre....
|
|
dinazavric 
      
Beiträge: 75
|
Verfasst: Do 28.04.11 11:20
Habe in der Zwischenzeit die andere Variante ausprobiert und sie geht! Hier ist der Code dazu:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| dataSet2.Relations.Add("ParameterProperties", dataSet2.Tables["Parameters"].Columns["Parameter Name"], dataSet2.Tables["Parameter Values"].Columns["Parameter Name"]);
P1_Name.DisplayMember = "Parameters.Parameter Name"; P1_Name.ValueMember = "Parameters.Parameter Name"; P1_Name.DataSource = this.dataSet2;
P1_Value.DisplayMember = "Parameters.ParameterProperties.Value Name"; P1_Value.ValueMember = "Parameters.ParameterProperties.Parameter Name"; P1_Value.DataSource = this.dataSet2; |
Würde aber trotzdem mit der zweiten Variante versuchen ob auch sie funkzioniert. Den Fehler finde ich leider nicht...
|
|
|