none
Datagridview in ein neues Formular übergeben RRS feed

  • Frage

  • Hallo,

    ich arbeite mit Visual Studio 2008 und hole mir meine Kundendaten mittels DataGridView aus meiner Datenbank. Das Formular heist Form1.cs. Im DataGridView habe ich einige Colums ausgeblendet die ich in der Ansicht nicht brauche. Ich habe ein neues Formular addkunde.cs hinzugefügt (Detailansicht) wo die Daten weiterbearbeitet werden sollen. Mittels Doppelclick auf die Zeile im DataGridView sollte sich das Formular addkunde.cs öffnen und die Daten des ausgewählten Kunden anzeigen um die nötigen Daten zu vervollständigen. Googeln hat mir nicht viel weitergebracht. Ich bitte um Eure Hilfe.

    Liebe Grüße

    Das Formular Form1.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace ESCxrm
    {
     public partial class Form1 : Form
     {
      public Form1()
      {
       InitializeComponent();
      }
    
      private void Form1_Load(object sender, EventArgs e)
      {
       // TODO: Diese Codezeile ldt Daten in die Tabelle "escxrmDataSet.kunde". Sie knnen sie bei Bedarf verschieben oder entfernen.
       this.kundeTableAdapter.Fill(this.escxrmDataSet.kunde);
      }
    
      private void tabPage2_Click(object sender, EventArgs e)
      {
    
      }
    
      private void kundeBindingNavigatorSaveItem_Click(object sender, EventArgs e)
      {
       this.Validate();
       this.kundeBindingSource.EndEdit();
       this.tableAdapterManager.UpdateAll(this.escxrmDataSet);
      }
    
      private void kundeDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
      {
      }
    
      private void toolStripTextBox1_Click(object sender, EventArgs e)
      {
      }
    
      private void kundeBindingNavigator_RefreshItems(object sender, EventArgs e)
      {
    
      }
    
      private void fillByLastNameToolStripButton_Click(object sender, EventArgs e)
      {
       try
       {
        this.kundeTableAdapter.FillByLastName(this.escxrmDataSet.kunde, kndnameToolStripTextBox.Text);
       }
    
       catch (System.Exception ex)
       {
        System.Windows.Forms.MessageBox.Show(ex.Message);
       }
      }
      private void fillByLastNameToolStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
      {
      }
    
      private void kundeDataGridView_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
      {
      }
     }
    }

    Das Formular addkunde.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace ESCxrm
    {
     public partial class addkunde : Form
     {
      public addkunde()
      {
       InitializeComponent();
      }
    
      private void kundeBindingNavigatorSaveItem_Click(object sender, EventArgs e)
      {
       this.Validate();
       this.kundeBindingSource.EndEdit();
       this.tableAdapterManager.UpdateAll(this.escxrmDataSet);
      }
    
      private void addkunde_Load(object sender, EventArgs e)
      {
       // TODO: Diese Codezeile ldt Daten in die Tabelle "escxrmDataSet.kunde". Sie knnen sie bei Bedarf verschieben oder entfernen.
       this.kundeTableAdapter.Fill(this.escxrmDataSet.kunde);
      }
    
      private void kndnameTextBox_TextChanged(object sender, EventArgs e)
      {
      }
     }
    }
    Sonntag, 21. November 2010 12:43

Antworten

  • Hallo Wolfgang,

    eines solltest Du Dir ganz zu Anfang (an dem wohl Du noch stehst) verdeutlichen:
    Das DataGridView ist nur ein Steuerelement (unter vielen), dass mit den Daten arbeitet.
    Wichtig ist hier die Datenquelle selbst und das wäre hier zunächst die BindingSource ,
    die die Verbindung mit dem DataSet (escxrmDataSet) und der dort enthaltenen DataTable (kunde).
    Der Austausch der Daten erfolgt zwischen den Steuerelementen (DataGridView, TextBox usw.)
    über diese Komponenten.

    Du solltest die Funktionsweise der BindingSource-Komponente verstanden haben,
    um die Datenbindung erfolgreich zwischen mehreren Formularen einsetzen zu können.

    Für den konkreten Fall:
    Wenn Dein zweites Formular zum Erstellen (AddKunde) eine neuen Datensatzes (Kunde)
    gedacht ist, so mußt Du die Datenquelle aus dem ersten Formular übernehmen.
    Eine zusätzliche Datenquelle und TableAdapter - wie sie Dir der Designer eingebaut hat -
    hilft dann nicht weiter. Denn das wären zwei unabhängige Datenquellen, die nichts von
    einander wissen.

    Willst Du den Code vom Designer nutzen, so entferne zunächst den Fill-Abschnitt
    aus Load-Ereignis. Anstatt dessen weise der BindingSource in dem AddKunde-Formular
    die gleiche Datenquelle via DataSource , DataMember zu.

    Auch solltest Du überlegen ob Du das Formular nicht zugleich für Hizufügen und Ändern
    verwendest, jeweils ein eigenes Dateil-Formular ist im allgemeinen nicht erforderlich.

    Gruß Elmar



    Dienstag, 23. November 2010 09:15
    Beantworter
  • Hallo Wolfgang,

    hier auch die entsprechenden Microsoft-Referenzen und Empfehlungen zum Handling bei Detail-Tabellen und gemeinsamen BindingSource:

    [Gewusst wie: Erstellen eines Master-/Detailformulars mit zwei DataGridView-Steuerelementen in Windows Forms]
    http://msdn.microsoft.com/de-de/library/c12c1kx4(v=VS.100).aspx

    [Exemplarische Vorgehensweise: Erstellen eines Master-/Detailformulars mit zwei DataGridView-Steuerelementen in Windows Forms]
    http://msdn.microsoft.com/de-de/library/y8c0cxey.aspx

    Vorteilhaft ist, wenn Du den BindingSource wirklich über die Formen gleich hältst.

    [Gewusst wie: Freigeben von gebundenen Daten in Formularen mithilfe der BindingSource-Komponente]
    http://msdn.microsoft.com/de-de/library/ms404320.aspx

     


    ciao Frank
    Dienstag, 23. November 2010 13:30

Alle Antworten

  • Hallo Wolfgang,

    nicht nur das dieses hier VB-Community ist, aber bitte - Was soll uns Dein Code sagen?

    --

    Gruß Scotty

    Sonntag, 21. November 2010 16:01
  • Hallo Karsten,

    sorry, das ich in die falsche Community gepostet habe

    Montag, 22. November 2010 18:23
  • Hallo Wolfgang,

    ich habe Deinen Beitrag ins passendere Forum für C# verschoben. Zur Codeformatierung: Verwende das nächste mal bitte die Funktion "Codeblock einfügen" im Foreneditor, wenn Du Code aus Visual Studio hier einfügst oder mache einen Zwischenschritt über Notepad um unnötige Formatierungsanweisungen zu entfernen, mit denen der Foreneditor nichts anzufangen weiß.


    Thorsten Dörfler
    Microsoft MVP Visual Basic
    vb-faq.de
    Montag, 22. November 2010 19:20
    Beantworter
  • Hallo Wolfgang,

    eines solltest Du Dir ganz zu Anfang (an dem wohl Du noch stehst) verdeutlichen:
    Das DataGridView ist nur ein Steuerelement (unter vielen), dass mit den Daten arbeitet.
    Wichtig ist hier die Datenquelle selbst und das wäre hier zunächst die BindingSource ,
    die die Verbindung mit dem DataSet (escxrmDataSet) und der dort enthaltenen DataTable (kunde).
    Der Austausch der Daten erfolgt zwischen den Steuerelementen (DataGridView, TextBox usw.)
    über diese Komponenten.

    Du solltest die Funktionsweise der BindingSource-Komponente verstanden haben,
    um die Datenbindung erfolgreich zwischen mehreren Formularen einsetzen zu können.

    Für den konkreten Fall:
    Wenn Dein zweites Formular zum Erstellen (AddKunde) eine neuen Datensatzes (Kunde)
    gedacht ist, so mußt Du die Datenquelle aus dem ersten Formular übernehmen.
    Eine zusätzliche Datenquelle und TableAdapter - wie sie Dir der Designer eingebaut hat -
    hilft dann nicht weiter. Denn das wären zwei unabhängige Datenquellen, die nichts von
    einander wissen.

    Willst Du den Code vom Designer nutzen, so entferne zunächst den Fill-Abschnitt
    aus Load-Ereignis. Anstatt dessen weise der BindingSource in dem AddKunde-Formular
    die gleiche Datenquelle via DataSource , DataMember zu.

    Auch solltest Du überlegen ob Du das Formular nicht zugleich für Hizufügen und Ändern
    verwendest, jeweils ein eigenes Dateil-Formular ist im allgemeinen nicht erforderlich.

    Gruß Elmar



    Dienstag, 23. November 2010 09:15
    Beantworter
  • Hallo Wolfgang,

    hier auch die entsprechenden Microsoft-Referenzen und Empfehlungen zum Handling bei Detail-Tabellen und gemeinsamen BindingSource:

    [Gewusst wie: Erstellen eines Master-/Detailformulars mit zwei DataGridView-Steuerelementen in Windows Forms]
    http://msdn.microsoft.com/de-de/library/c12c1kx4(v=VS.100).aspx

    [Exemplarische Vorgehensweise: Erstellen eines Master-/Detailformulars mit zwei DataGridView-Steuerelementen in Windows Forms]
    http://msdn.microsoft.com/de-de/library/y8c0cxey.aspx

    Vorteilhaft ist, wenn Du den BindingSource wirklich über die Formen gleich hältst.

    [Gewusst wie: Freigeben von gebundenen Daten in Formularen mithilfe der BindingSource-Komponente]
    http://msdn.microsoft.com/de-de/library/ms404320.aspx

     


    ciao Frank
    Dienstag, 23. November 2010 13:30
  • Vielen Dank.

    Dienstag, 23. November 2010 18:19
  • Hallo Elmar,

    vielen Dank für die Hilfe, ich habe mir die Beispiele angeschaut und hat dann auch gleich funktioniert!

    Gruß Wolfgang

    Mittwoch, 24. November 2010 18:25
  • Hallo Elmar,

    leider funktioniert es doch noch nicht so wie ich es gerne hätte. Wenn ich auf die Zelle Doppelclicke, dann öffnet sich zwar die Form2.cs, jedoch mit dem ersten Datensatz und nicht der mit der markierten Zeile.

    In der Form1.cs habe ich follgenden Code drinnen.

    private void kundeDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
            {
                System.Data.DataRowView SelectedRowView;
                DataSet.kundeRow SelectedRow;
                SelectedRowView = (System.Data.DataRowView)kundeBindingSource.Current;
                SelectedRow = (DataSet.kundeRow)SelectedRowView.Row;
                Form f = new Form2();
                f.ShowDialog();

             }

    In der Form2.cs habe ich follgenden Code drinnen.

    private void Form2_Load(object sender, EventArgs e)
            {

                this.kundeTableAdapter.Fill(this.dataSet.kunde);
            }

    Was mache ich falsch?

    Gruß Wolfgang

    Samstag, 4. Dezember 2010 17:56
  • Hallo Wolfgang,

    Dir fehlt noch der Bezug zwischen den beiden Formularen.

    Unten mal zwei Varianten, wie man es lösen kann.
    Verwendet habe ich dabei die altbekannte Northwind Customers.
    Das erste Formular CustomerGridForm enthält ein Standard-DataGridView Formular,
    das zweite eine CustomerDetailForm ein DetailFormular.
    Beide sind über den Datenquellen Dialog "zusammengeklickt" worden.

    Variante 1 zeigt das bereits angesprochene Verknüpfen der BindingSource.
    Dabei erfolgt die Übergabe im Konstruktor erfolgt.

    Variante 2 ist etwas aufwändiger. Dabei wird der Primärschlüssel (hier CustomerID) übergeben.
    Und das Formular lädt die Daten separat ins eigene lokale DataSet.
    Dazu ist ein erweiterter parametrisierter TableAdapter erforderlich.
    Damit die Daten wieder zurückkommen, ruft das Tabellenformular seinerseits
    die Daten  bei erfolgreichem Editieren ab (ist aber optional).

    Empfehlenswert ist die Variante, wenn das Detail-Formular komplexer ist,
    z. B. die Datenquellen sich deutlicher voneinander unterscheiden.

    Die beiden Formulare, zumächst das CustomerGridForm:

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Windows.Forms;
    using ElmarBoye.Samples.Data;
    
    namespace ElmarBoye.Samples.Forms
    {
      public partial class CustomerGridForm : Form
      {
        public CustomerGridForm()
        {
          InitializeComponent();
        }
    
        private void CustomerGridForm_Load(object sender, EventArgs e)
        {
          this.customersTableAdapter.Fill(this.northwindDataSet.Customers);
          // this.customersBindingSource.Filter = "Country = 'Germany'";
        }
    
        private void customerDataGridView_DoubleClick(object sender, EventArgs e)
        {
          // Aufruf der jeweiligen Variante:
          ShowDetailFormWithBindingSource();
          //ShowDetailFormByPrimaryKey();
        }
    
        private void ShowDetailFormWithBindingSource()
        {
          // Erstellen des DetailFormulars mit BindingSource als Parameter
          // Alternativ auch via Eigenschaft, siehe 2. Beispiel.
          using (var dialog = new CustomerDetailForm(this.customersBindingSource))
          {
            dialog.ShowDialog(this);
          }
        }
    
        private void ShowDetailFormByPrimaryKey()
        {
          // Abrufen der aktuellen Zeile
          var currentRow = this.customersBindingSource.Current as DataRowView;
          if (currentRow != null)
          {
            // Extrahieren des PrimaryKey (hier CustomerID)
            string customerID = (currentRow.Row as NorthwindDataSet.CustomersRow).CustomerID;
            using (var dialog = new CustomerDetailForm())
            {
              dialog.CustomerID = customerID;
    
              // Anzeigen des Dialogs
              if (dialog.ShowDialog(this) == DialogResult.OK)
              {
                // Optional: Aktualisieren der lokalen Datenquelle 
                var table = this.customersTableAdapter.GetDataByCustomerID(customerID);
                this.northwindDataSet.Customers.Merge(table, false);
              }
            }
          }
        }
      }
    }
    
    

    und dazu das CustomerDetailForm als Detail-Formular:

    using System;
    using System.Data;
    using System.Windows.Forms;
    
    namespace ElmarBoye.Samples.Forms
    {
      public partial class CustomerDetailForm : Form
      {
        public CustomerDetailForm()
        {
          InitializeComponent();
        }
    
        public CustomerDetailForm(BindingSource source)
        {
          InitializeComponent();
    
          // Verknüpfen der BindingSource 
          this.customersBindingSource.DataSource = source;
          this.customersBindingSource.Position = source.Position;
        }
    
        private string _customerID;
        public string CustomerID
        {
          get { return this._customerID ?? ""; }
          set { this._customerID = value; }
        }
    
        private void CustomerDetailForm_Load(object sender, EventArgs e)
        {
          this.customersTableAdapter.FillByCustomerID(this.northwindDataSet.Customers, this.CustomerID);
        }
    
        private void customersBindingNavigatorSaveItem_Click(object sender, EventArgs e)
        {
          try
          {
            this.Validate();
            this.customersBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.northwindDataSet);
    
            // Gespeichert
            this.DialogResult = DialogResult.OK;
          }
          catch (Exception ex)
          {
            MessageBox.Show(ex.Message);
          }
        }
      }
    }
    
    

    Probiere das ganze mal aus und frage nach, wenn Verständnisprobleme bleiben.

    Gruß Elmar

    Montag, 6. Dezember 2010 09:47
    Beantworter
  • Hallo Elmar,

    beide Beispiele haben funktioniert, anhand von Deinem Beispiel habe ich die BindingSource jetzt verstanden.

    Vielen Dank für Deine Hilfe.

    Gruß Wolfgang

    Montag, 6. Dezember 2010 16:01