Benutzer mit den meisten Antworten
Datagridview in ein neues Formular übergeben

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) { } } }
- Bearbeitet Thorsten DörflerEditor Montag, 22. November 2010 19:13 Codeformatierung
- Verschoben Thorsten DörflerEditor Montag, 22. November 2010 19:15 Off-Topic (aus:Visual Basic (ab Version 2002 / .NET))
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
- Als Antwort vorgeschlagen Marcel RomaModerator Dienstag, 23. November 2010 11:02
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 24. November 2010 15:10
-
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- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 24. November 2010 15:10
Alle Antworten
-
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 -
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
- Als Antwort vorgeschlagen Marcel RomaModerator Dienstag, 23. November 2010 11:02
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 24. November 2010 15:10
-
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- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 24. November 2010 15:10
-
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
-
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