Announcement

Collapse
No announcement yet.

DataGridView füllen und speichern

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • DataGridView füllen und speichern

    Hallo,

    ich habe jetzt schon ewig gesucht, aber nur gefunden, dass es so nicht geht oder dass es irgendwie geht aber nicht wie konkret...

    Ich nutze VB.net 2008 Express, als DB mom. SQL Server 2008 SP1 Express. Ich baue eine WinForms Anwendung.

    Vereinfacht sind in der DB 2 Tabellen. In Tabelle A ist ein Fremdschlüssel aus Tabelle B enthalten. Dem Anwender will ich in einer DataGridview jedoch nicht den Fremdschlüssel, sondern dien Bezeichnung aus Tabelle B anzeigen. Soweit kein Problem durch inner joins.

    Es gibt ja die Möglichkeit ComboBoxes in der DataGridView anzuzeigen, aber ich weiß nicht, wie ich das über 2 Tabellen machen soll. (Geht das überhaupt)?

    Im DataSet sind alle Tabellen und Beziehungen modelliert. Ebenso wurde TableApdapter erstellt für insert, update etc. Bei einer JOIN Abfrage kann jedoch kein Update erstellt werden.

    Meine Frage ist nun:

    1. Wie kann ich in der Datagridview weiterhin die gejointen Tabellen anzeigen lassen und
    2. Wie kann ich diese zurückschreiben, auch wenn der Anwender in der gejointen Anzeige die Bezeichnung ändert (welche in Tabelle B vorhanden sein muss) und .net jetzt in Tabelle A den passenden FK eintragen muss.

    Danke...
    VG
    Chris

  • #2
    zu 1. da du das scheinbar schon hast nichts tun.
    zu 2. ein entsprechendes UpdateCommando(SQL) selbst im Tableadapter schreiben. Bei einem Join kann nur kein Kommando automatisch generiert werden das hindert einen aber nicht daran es selbst zu machen.

    Comment


    • #3
      Hallo,

      ich schlage vor, die Tabellen ohne JOIN separat in zwei DataTables einzulesen, diese per DataRelation zu verbinden (das sollte der Table-Designer können) und dann die DataGridViewComboBoxColumn zu nutzen.

      Eine Anleitung dazu habe ich unter DataGridView: Master/Detail über ComboBox veröffentlicht. Es ist aber C#, und die Lösung erschließt sich erst durch die gesamte Diskussion. (Ich muss wohl noch eine zusammenfassende Lösung ans Ende setzen, am besten auch in VB - aber im Moment geht mir zu viel anderes durch den Kopf.) Wichtig ist vor allem, dass DataPropertyName benutzt wird.

      Vielleicht kommst du dennoch damit weiter. Jürgen

      Comment


      • #4
        Ok...

        Hi,

        d.h. wie würde ich das konkret machen?
        1. fall mit Joins
        Ich habe ein Dataset mit Tabellen und Relationen, dann habe ich TableAdpater für jede Tabelle, auch mit Joins. Für das Speichern muss ich nun beim TableAdapter den Update CommandText manuell schreiben. Wenn ich aber einen Join im TableAdpater habe, dann kann ich gar kein Update erzeugen, habe also auch keinen Ansatzpunkt den CommandText zu ändern. Muss ich das in der IDE machen oder im Code, wenn ja wo? Die einzige Stelle wo dazu was steht ist in der DataSet.xsd, die wurde ja autogeneriert hat aber über 8000 Zeilen code. Da steht dann der UpdateText drin....

        Wie würde dann so ein Update aussehen? Etwa so

        UPDATE <TableDerFKenthält>
        SET TableDerFKenthält.FK=(SELECT ALL [ID] TOP 1 FROM MasterTable WHERE ShortName LIKE @AT-SN)

        oder kann ich auch nach dem FK Wert suchen?

        2. Fall
        D.h ich würde dann eine ComboBox Column in die DataGridview machen und ausschließlich aus der Mastertabelle die Daten laden? Beim speichern müsste ich dann aber irgendwie auch die ID des Values aus der Combo wissen...

        Nur zur Darstellung:
        Ich habe das so gemacht, wie da beschrieben, ich kann die Combobox aber nicht ausklappen. Passiert nix:

        Dim ReleaseTableAdapter As New ATDataSetTableAdapters.ReleaseTableAdapter
        ReleaseTableAdapter.Fill(ATDataSet.Release)
        DataGridView1.DataSource = ATDataSet
        DataGridView1.DataMember = ATDataSet.Tables("Artifacts").TableName.ToString
        Debug.Print(ATDataSet.Release.Rows.Count.ToString)
        ArtifactsTableAdapter.Update()
        Dim cmb As New DataGridViewComboBoxColumn
        cmb.DataSource = ATDataSet.Tables("Release")
        cmb.ValueMember = "ID"
        cmb.DisplayMember = "ShortName"
        cmb.DataPropertyName = "ReleaseFK"
        cmb.HeaderText = "AAAAAAAAA"
        cmb.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
        DataGridView1.Columns.Add(cmb)

        Grundsätzlich verstehe ich den Ansatz aber im Detail ists nicht ganz klar...

        danke
        VG
        Zuletzt editiert von DataLtCommander; 14.10.2009, 17:21.

        Comment


        • #5
          1. fall mit Joins
          Im Dataset Designer einfach auf den gewünschten Tableadapter klicken und in den Properties des Tableadapters die UpdateCommand Property raussuchen.
          Dort steht wahrscheinlich {none} daneben weil er automatisch kein updateCommand generieren konnte. Dort dann {new} auswählen und du erhältst ein leeres Command Object. In den Properties kannst du nun den CommandText füllen.

          Um zu sehen wie ein korrekter CommandText auszusehen hat solltest du dir am einfachsten mal einen der automatisch generierten UpdateCommands einer deiner anderen Tableadapter ansehen. Dann sollte schnell klar sein was da wie rein zuschreiben ist.

          Comment


          • #6
            2. Fall
            D.h ich würde dann eine ComboBox Column in die DataGridview machen und ausschließlich aus der Mastertabelle die Daten laden? Beim speichern müsste ich dann aber irgendwie auch die ID des Values aus der Combo wissen...
            Das erklärt die Hilfe zur DataGridViewComboBoxColumn recht ordentlich.
            Sieh dir mal die Remarks bezüglich dem befüllen der ComboxListe an und wie dazu ValueMember und DisplayMember einzusetzen sind.

            So wie ich dein Problem jetzt verstanden habe würde ich dieses Vorgehen auch deinem Fall 1 vorziehen.

            Comment


            • #7
              Originally posted by Ralf Jansen View Post
              Um zu sehen wie ein korrekter CommandText auszusehen hat solltest du dir am einfachsten mal einen der automatisch generierten UpdateCommands einer deiner anderen Tableadapter ansehen. Dann sollte schnell klar sein was da wie rein zuschreiben ist.
              Ok, habe ich gefunden. ich weiß nur momentan nicht, wie ich das Update gestalten soll. Die DGV enthält eine ComboBoxColumn einer Mastertabelle. Wenn der Benutzer einen Button klickt, wird das Update des tableAdapters aufgerufen. Die Frage ist, wie ich den ValueMember der ComboBoxSpalte an den UpdateParameter im CommandText der Update Anweisung des TableAdapters der Detailtabelle bekomme? Bisher rufe ich lediglich den TableAdapter.update auf und übergebe die Tabelle des DataSets.

              Gibt es da eine bestPractice? Wenn bspw. in der DVG der CellValue changed könnte ich die ID des ValueMembers auslesen. Die Frage ist nur wo ich die hinschreiben soll.

              Danke...
              VG
              Zuletzt editiert von DataLtCommander; 14.10.2009, 19:28.

              Comment


              • #8
                Gibt es da eine bestPractice? Wenn bspw. in der DVG der CellValue changed könnte ich die ID des ValueMembers auslesen. Die Frage ist nur wo ich die hinschreiben soll.
                Das macht Databinding eigentlich alles automatisch richtig. Du solltest also nichts irgendwohin manuell hinschreiben müssen. Ich glaube wir (oder besser ich ) haben dich an der Stelle etwas verwirrt.

                Comment


                • #9
                  Hi Ralf,

                  danke für deine Antworten.
                  Das Hauptproblem ist bei mir noch, dass ich das speichern nicht ganz hinbekomme.
                  Wenn ich eine normale Tabelle ohne FK habe, dann macht das Update Command alles automatisch. Sobald ich aber statt dem FK eine andere Spalte der MasterTable anzeige, funktioniert das nicht mehr. Nun soll ich ja den Update Commandtext selbst schreiben. Das Problem ist aber, wie ich das jetzt mit der Detailtabelle und dem FK löse.

                  Kannst du mir das v. einmal als Beispiel ein Feld einer Master Detaitabelle updaten?
                  Ziel:
                  Ich nutze eine DGV und zeige bestimmte Spalten von der Detailtabelle A an, bestimmte Spalten durch joins aus Mastertabelle B. Ich will nun, dass der Anwender die Möglichkeit hat in der DGV ein Feld aus der Mastertable als ComboBox Spalte angezeigt bekommt und ändern kann.
                  Wie schreib ich jetzt die UpdateAnweisung für den TableApapter und wie binde ich die ComboBoxSpalte, dass er das automatisch machen kann. Ich übergebe ja keine Parameter an das UpdateCommand sondern das wird im Hintergrund ja irgendwie automatisch gemacht.
                  Ideal wäre ja, wenn ich die Combobox Spalte auch so intergrieren könnte, dass ich die auch als UpdateParameter auswählen kann.
                  Ich komm hier so leider nicht weiter....

                  Was mich auch wundert ist dass ich im dataSet Designer keine weiteren Abfragen definieren kann, er ändert immer wieder die eine Select Abfrage. Wie gehe ich denn vor, wenn ich eine View verwenden will? Trägt man dann als DataSource für die DVG das Select Statement ein? Hätte ja gerne die Datenverwaltung und die GUI getrennt...

                  thx

                  Comment


                  • #10
                    Einen Schritt weiter...

                    Hallo,

                    ich weiß zwar immer noch nicht, wie ich die UpdateCommand Objekte etc übergebe und ändere, aber ich weiß jetzt, wie ich das machen kann, was ich ursprünglich wollte.

                    Prinzipiell ist es von MS sicherlich so gewollt, dass das DataSet das DB-Provider unabhängige DB Schema repräsentiert. Deshalb sollte man dort auch nur per Select die Tabelle abfragen und nicht Joinen etc.

                    Man kann aber, so wie ich das wollte, einfach die DataTable als Member der DVG benutzen. Dann haben wir das Problem, dass er die FKs als Column anzeigt. Dies kann man ändern, indem man im DS die Relationen gepflegt hat und dann im Eigenschaftsfenster der DVG in der Columns Auslistung den ColumnType auf DataGridViewComboBoxColumn ändern und dann die Bindungen vornimmt mit der BindingSource und vor allem dem ValueMember als ID PK der Mastertable. (Die DataSource ist die BindingSource der Mastertable).

                    Dies führt dazu, dass er eine ComboBox anzeigt mit dem gewünschten Feld der MasterTable anstelle des FK. Gespeichert wird dies einfach durch den simplen Aufruf des TableAdapters.Update für die DetailTable. Den FK, der dort eingetragen wird sucht sich das Control automatisch durch den Valuemember raus.

                    Zur DesignTime kann man auch die Columns etc in Form.Designer.vb bearbeiten. Da sourct VB den generierten Code aus, der aber auch interessant ist und bearbeitet werden kann.

                    VG
                    Chris

                    Comment

                    Working...
                    X