none
Bindingsource.AddNew children RRS feed

  • Allgemeine Diskussion

  • Ich hoffe, daß meine Frage gut gestellt ist, bin Autodidakt und verwende vermutlich nicht die korrekte Terminologie.
    Ich lese aus und schreibe in eine mysql Datenbank, .net 4 und alles mehr oder weniger im Designer erstellt.

    In meiner Anwendung gibt es eine Haupttabelle und einige Untertabellen, die Fremdschlüssel sind als "Nur Beziehung" gesetzt.
    Das Einlesen funktioniert einwandfrei, jede Tabelle hat eine eigene Bindingsource und TableAdapter und im TableAdapterManager sind zumindestens alle Tables korrekt eingetragen.

    Was ich nicht verstehe ist die Vorgehensweise, wie ich einen neuen Datensatz anlege.

                    DataRowView currentRowProjekt = (DataRowView)tprojektBindingSource.AddNew();
                    if (currentRowProjekt != null)
                    {
                        currentRowProjekt["editDatum"] = System.DateTime.Now;
                    }
                    DataRowView currentForecast = (DataRowView)t_forecastBindingSource.AddNew();
    


    und dann

                        tprojektBindingSource.EndEdit();
                        t_forecastBindingSource.EndEdit();
    
                        t_projektTableAdapter.Update(my_projekteDataSet);
                        t_forecastTableAdapter.Update(my_projekteDataSet);
                        my_projekteDataSet.AcceptChanges();


    Der Hauptdatensatz wird eingefügt, aber nicht der Forecast. Das liegt vermutlich daran, daß die zweite Tabelle nicht den Primärschlüssel erhält.
    Denn, wenn ich das per Hand mache (also per Code), dann funktioniert es, aber ich muß mich dann darum kümmern per Hand alle Controls auszulesen.

    Irgendetwas scheine ich nicht richtig in der Vorgehensweise zu verstehen.

    Ich bin für jeden Hinweis sehr dankbar.

    Montag, 9. Januar 2012 18:29

Alle Antworten

  • Hallo,

    auf die "Terminologie" kommt es nicht so an, das kommt schon noch ... und Code versteht man auch so.

    Wenn Du zwei abhängige Tabellen verwendest, so muss auch die BindingSource als abhängig definiert werden,
    was man über die Beziehung erreichen kann.

    Trage dazu die in die zweite Binding (t_forecastBindingSource) als DataSource die erste (tprojektBindingSource) ein.
    Und verwende als DataMember den Namen der Beziehung - dies sollte dann im Designer auftauchen.
    Zum Vergleich kannst Du Dir anschauen:
    Exemplarische Vorgehensweise: Erstellen eines Master-/Detailformulars mit zwei DataGridView-Steuerelementen in Windows Forms
    wo dies zum Verknüpfen zweier DataGridViews verwendet wird (es gilt aber auch ohne diese).

     Wenn die Haupttabelle ("projekt") eine Autoincrement Spalte enthält, so musst Du den aktuellen Wert
    über LAST_INSERT_ID abrufen, damit der effektiv vergeben Wert in den Primärschlüssel übernommen wird.
    Dann muss aber auch die Beziehung in einen Fremdschlüssel mit Aktualisierungsweitergabe geändert werden,
    da sonst die abhängige Tabelle nicht den von der Datenbank vergebenen Schlüssel enthält.

    Das AcceptChanges für das DataSet solltest Du streichen - denn bei Erfolg erledigt das der TableAdapter.

    Gruß Elmar

    Montag, 9. Januar 2012 21:20
    Beantworter

  •  Wenn die Haupttabelle ("projekt") eine Autoincrement Spalte enthält, so musst Du den aktuellen Wert
    über LAST_INSERT_ID abrufen, damit der effektiv vergeben Wert in den Primärschlüssel übernommen wird.
    Dann muss aber auch die Beziehung in einen Fremdschlüssel mit Aktualisierungsweitergabe geändert werden,
    da sonst die abhängige Tabelle nicht den von der Datenbank vergebenen Schlüssel enthält.

    Das AcceptChanges für das DataSet solltest Du streichen - denn bei Erfolg erledigt das der TableAdapter.

    Gruß Elmar

    Lieber Elmar, vielen Dank für Deine Antwort!

    Die Bindungen existieren ja schon, wie geschrieben, das Abrufen funktioniert einwandfrei.
    Aber was ist die richtige Einstellung dort:

    Während des Herumzustochern hab ich im Designer schon ein extra Query im t_projektTableAdapter angelegt.

     

    SELECT        MAX(projektID) AS lastProjekt
    FROM            t_projekt

     

    int lastProjektID = (Int32)t_projektTableAdapter.ScalarQuery();
    Und nun?


    Montag, 9. Januar 2012 21:49
  • Hallo,

    welches die richtige Einstellung ist, hängt letztendlich von der Tabellendefinition
    in der MySql Datenbank ab - das Bild des DataSet Designer verrät da nicht alles.

    "Normalweise" wäre das eine Fremdschlüsseleinschränkung mit Regel aktualisieren + löschen kaskadieren,
    siehe 'DataTable'-Einschränkungen (ADO.NET)

    Wobei es zudem davon abhängt, wie die Datenbank-Einstellung also FOREIGN KEY lautet.

    Und wie bereits gesagt, ob es sich um eine Autoincrement-Spalte handelt,
    siehe Abrufen von Identitäts- oder AutoWert-Werten (ADO.NET)
    (auch wenn dort vom SQL Server die Rede ist, gilt das Gesagte äquivalent, nur eben für LAST_INSERT_ID).

    Ggf. poste das SQL dere beiden Tabellen ausschnittsweise mit Primärschlüssel- / Fremdschlüssel.

    Gruß Elmar

    Montag, 9. Januar 2012 22:13
    Beantworter
  • -- Tabellenstruktur für Tabelle `t_projekt`
    
    CREATE TABLE IF NOT EXISTS `t_projekt` (
      `projektID` int(11) NOT NULL AUTO_INCREMENT,
      `mutterID` int(11) DEFAULT NULL,
      `projektname` varchar(255) NOT NULL,
      `anfangsdatum` date NOT NULL,
      `enddatum` date DEFAULT NULL,
      `projektbeschreibung` varchar(255) DEFAULT NULL,
      `projektpfad` varchar(255) DEFAULT NULL,
      `ort` varchar(255) DEFAULT NULL,
      `planer` varchar(255) DEFAULT NULL,
      `bauherr` varchar(255) DEFAULT NULL,
      `kundennr` varchar(255) DEFAULT NULL,
      `kunde` varchar(255) DEFAULT NULL,
      `vermittler` varchar(255) DEFAULT NULL,
      `statusID` int(11) DEFAULT NULL,
      `notizen` text,
      `editDatum` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      `LastEditBy` int(11) DEFAULT NULL,
      PRIMARY KEY (`projektID`),
      KEY `mutterID` (`mutterID`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=739 ;
    
    
    ALTER TABLE `t_projekt`
      ADD CONSTRAINT `t_projekt_ibfk_1` FOREIGN KEY (`mutterID`) REFERENCES `t_projekt` (`projektID`) ON DELETE CASCADE ON UPDATE CASCADE;
    

    -- Tabellenstruktur für Tabelle `t_forecast`
    
    CREATE TABLE IF NOT EXISTS `t_forecast` (
      `forecastID` int(11) NOT NULL AUTO_INCREMENT,
      `projektID` int(11) DEFAULT NULL,
      `chance` int(11) DEFAULT NULL,
      `zahlungG1` decimal(10,2) DEFAULT NULL,
      `zahlungG2` decimal(10,2) DEFAULT NULL,
      `zahlungG3` decimal(10,2) DEFAULT NULL,
      `zahlungD1` date DEFAULT NULL,
      `zahlungD2` date DEFAULT NULL,
      `zahlungD3` date DEFAULT NULL,
      `einkaufG1` decimal(10,2) DEFAULT NULL,
      `einkaufG2` decimal(10,2) DEFAULT NULL,
      `einkaufG3` decimal(10,2) DEFAULT NULL,
      `einkaufD1` date DEFAULT NULL,
      `einkaufD2` date DEFAULT NULL,
      `einkaufD3` date DEFAULT NULL,
      `zahlungB1` varchar(255) DEFAULT NULL,
      `zahlungB2` varchar(255) DEFAULT NULL,
      `zahlungB3` varchar(255) DEFAULT NULL,
      `einkaufB1` varchar(255) DEFAULT NULL,
      `einkaufB2` varchar(255) DEFAULT NULL,
      `einkaufB3` varchar(255) DEFAULT NULL,
      `forecastperson` int(11) DEFAULT NULL,
      `forecastnotizen` text,
      `editDatum` timestamp NULL DEFAULT NULL,
      `lastEditBy` int(11) DEFAULT NULL,
      PRIMARY KEY (`forecastID`),
      KEY `projektID` (`projektID`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=257 ;
    
    ALTER TABLE `t_forecast`
      ADD CONSTRAINT `t_forecast_ibfk_1` FOREIGN KEY (`projektID`) REFERENCES `t_projekt` (`projektID`) ON DELETE CASCADE ON UPDATE CASCADE;
    
    
    

    Im Designer habe ich die Beziehung auf "Sowohl Beziehungs- als auch Fremdschlüsseleinschränkung" umgestellt und die Regeln auf Cascade gesetzt und [x]Geschachtelte Beziehung.

    Mein jetziger Code funktioniert nicht, was wohl an der generellen Herangehensweise liegen kann, aufgrund meines Form Designs mag da was ausserdem quer liegen*.

            private void btnNeu_Click(object sender, EventArgs e)
            {
    
                if (btnNeu.Text.ToString() == "Neu")
                {
                    btnEdit.Text = "Abbrechen";
                    dataGridViewX1.Enabled = false;
                    DataRowView currentRowProjekt = (DataRowView)tprojektBindingSource.AddNew();
                    dtiProjektAnfang.Value = DateTime.Now;
                    if (currentRowProjekt != null)
                    {
                        currentRowProjekt["editDatum"] = System.DateTime.Now;
                    }
    
                    btnNeu.Text = "Speichern";
                }
                else if (btnNeu.Text.ToString() == "Speichern")
                {
                    if (tbProjektname.Text.Length <= 0)
                    {
                        tbProjektname.Focus();
    
                    } else
                    {
    
                        tprojektBindingSource.EndEdit();
                        t_projektTableAdapter.Update(stageled_projekteDataSet);
                        int lastProjektID = (Int32)t_projektTableAdapter.ScalarQuery();
                        DataRowView currentForecast = (DataRowView)t_forecastBindingSource.AddNew();
                        currentForecast["projektID"] = lastProjektID;
                        MessageBox.Show(lastProjektID.ToString());
                        t_forecastBindingSource.EndEdit();
                        if (t_forecastTableAdapter != null)
                        {
                            t_forecastTableAdapter.Update(stageled_projekteDataSet);
    
                            dataGridViewX1.Enabled = true;
                            btnNeu.Text = "Neu";
                            btnEdit.Text = "Bearbeiten";
                        }
                        //this.t_projektTableAdapter.Fill(this.stageled_projekteDataSet.t_projekt);
                    }
                }
                else if (btnNeu.Text.ToString() == "Abbrechen")
                {
                    tprojektBindingSource.CancelEdit();
                    t_forecastBindingSource.CancelEdit();
                    btnNeu.Text = "Neu";
                    btnEdit.Text = "Bearbeiten";
                }
            }
    


    *
    • Bearbeitet microbender Mittwoch, 11. Januar 2012 19:37
    Mittwoch, 11. Januar 2012 19:28
  • Hallo,

    ich habe das für Deine Tabellen und MySql mit aktuellem .NET Connector nachvollzogen:

    http://www.elmarboye.de/download/CSMySqlMasterDetail.zip

    Reduziert auf zwei Detail fürs Projekt und ein DataGridView für die Forecast (Details).
    Die Verbindungszeichenfolge musst Du in der App.Config auf Deinen Server anpassen.

    Das (uralte) Kern-Problem ist immer noch, dass AutoIncrement-Spalten bei typisierten DataSets
    nicht abgerufen werden. Somit kriegst Du nicht vergebenen Werte.

    Um das zu lösen, habe ich für die beiden Adapter eine Methode dazu gefügt -
    denn leider gibt es keine Stelle, an der man das automatisiert erledigen könnte
    (da hat Microsoft leider einiges versäumt).

    Beispielhaft für t_projekt (forecast äquivalent)

        public partial class t_projektTableAdapter
        {
            /// <summary>
            /// Ergänzt das InsertCommand um einen Abruf der AutoIncrement Spalte.
            /// </summary>
            public void FixAdapter()
            {
                // Ruft die letzte ID für projektID ab
                this.Adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
                this.Adapter.InsertCommand.CommandText += ";\r\nSELECT LAST_INSERT_ID() AS `projektID`;";
            }
        }
    
    und werden im Formular einmalig ausgeführt.

    Tipp am Rande:
    Verwende besser CHARSET=utf8 anstatt Latin1 für die Tabellen, denn .NET arbeitet mit Unicode
    (sonst sind evtl. einige Zeichen später nicht abzubilden, was erneuten Ärger provozieren kann).

    Gruß Elmar

    Donnerstag, 12. Januar 2012 16:18
    Beantworter
  • Vielen Dank für Deine Mühe und das Beispiel, ich mußte erstmal VB nachinstallieren :)

    Ich habe Deinen Code in c# konvertiert und es wird auch ein neuer Datensatz in t_forecast angelegt,
    aber leider ohne die eingegeben Daten. Ich vermute mal, daß es an der falschen Abarbeitung liegt.
    Ich bin eigentlich davon ausgegangen, daß die Verwendung von

    DataRowView currentRowProjekt = (DataRowView)tprojektBindingSource.AddNew();

    Sinn bringt, da damit alle Controls ja auch geleert werden, nun scheint es aber, daß der gleiche Aufruf für
    die t_forecastBindingSource unsinnig ist, denn alle Eingaben im Forecast Tab werden geleert.

    Ohne
           DataRowView currentForecast = (DataRowView)t_forecastBindingSource.AddNew();
    wird kein Datensatz in t_forecast eingetragen.

    Welche Vorgehensweise muß ich verwenden, um die eingegeben Daten im Forecast Tab in die Datenbank zu speichern?

            private void btnNeu_Click(object sender, EventArgs e)
            {
                if (btnNeu.Text.ToString() == "Neu")
                {
                    btnEdit.Text = "Abbrechen";
                    dataGridViewX1.Enabled = false;
                    DataRowView currentForecast = (DataRowView)t_forecastBindingSource.AddNew();
                    dtiProjektAnfang.Value = DateTime.Now;
                    if (currentRowProjekt != null)
                    {
                        currentRowProjekt["editDatum"] = System.DateTime.Now;
                    }
    
                    btnNeu.Text = "Speichern";
                }
                else if (btnNeu.Text.ToString() == "Speichern")
                {
                    if (tbProjektname.Text.Length <= 0)
                    {
                        tbProjektname.Focus();
    
                    } else
                    {
                        MessageBox.Show(tb_chance.Text); //
                        this.Validate();
                        tprojektBindingSource.EndEdit();
                        //DataRowView currentRowProjekt = (DataRowView)tprojektBindingSource.AddNew();
                        t_forecastBindingSource.EndEdit();
                        t_projektTableAdapter.Update(stageled_projekteDataSet);
                        t_forecastTableAdapter.Update(stageled_projekteDataSet);
    
                        dataGridViewX1.Enabled = true;
                        btnNeu.Text = "Neu";
                        btnEdit.Text = "Bearbeiten";
                    }
                }
                else if (btnNeu.Text.ToString() == "Abbrechen")
                {
                    tprojektBindingSource.CancelEdit();
                    t_forecastBindingSource.CancelEdit();
                    btnNeu.Text = "Neu";
                    btnEdit.Text = "Bearbeiten";
                }
            }




    Die Tabellen habe ich auf utf8 umgestellt.

     


    • Bearbeitet microbender Freitag, 13. Januar 2012 17:28
    Freitag, 13. Januar 2012 17:27
  • Hallo,

    Auuaaa, da habe ich wohl kräftig geschlafen... ;-)

    Ich habe das Ganze für C# umgeändert und damit sich es lohnte (und zur Strafe ;-)
    noch einige Änderungen und Erweiterungen vorgenommen:

    http://www.elmarboye.de/download/CSMySqlMasterDetail.zip

    Ich habe wie bei Dir (vereinfacht) ein TabControl für die beiden Tabellen verwendet.
    Die Projektseite dann als Detailanzeige; beim Forecast ist es beim DataGridView geblieben.
    Die Steuerung läuft dabei nicht über den Status von Schaltflächen,
    sondern verwendet die Ereignisse, die ohnehin vorhanden sind.

    Fürs Anlegen mit Vorgaben verwende ich das AddingNew Ereignis der BindingSource, so ist es zentraler.

    Bei den BindingSourcen ist zu beachten, dass die forecastBindingSource von der projektBindingSource
    abgeleitet wird, nur so wird der Primärschlüssel automatisch übertragen.
    (Beim Ziehen aus dem Datenquellenfenster wird das automatisch erzeugt,
    wenn man untergeordneten von t_forecast unterhalb von t_projekt verwendet).

    Auf einen expliziten Bearbeitungsmodus habe ich verzichtet.
    Wenn Du so etwas haben möchtest, solltest Du besser eine Variable (Enumeration) verwenden,
    anstatt die Zustände von Schaltflächen oder ihre Texte abzufragen.
    So etwas ändert man schon mal und dann geht alles mögliche daneben.

    Eine einfache Validation für den Projektnamen über einen ErrorProvider -
    was noch ausbaufähig wäre. Zudem habe ich einen BindingNavigator integriert.

    Gruß Elmar


    Samstag, 14. Januar 2012 10:25
    Beantworter
  • Lieber Elmar, erneut ein großes Danke. Dein Beispiel ist sehr lehrreich, das einzigste was mir jetzt noch in der Herangehensweise schleierhaft ist, ist wie ich einen neuen Datensatz starte.

    Ich möchte den bindingNavigator nicht verwenden, in Deinem Beispiel passiert etwas auf bindingNavigatorAddNewItem_Click, was ich noch nicht verstehe.

     

            private void btnNeu_Click(object sender, EventArgs e)
            {
                if (btnNeu.Text.ToString() == "Neu")
                {
                    dataGridViewX1.Enabled = false;
                    dtiProjektAnfang.Value = DateTime.Now;
                    this.projektBindingSource.AddNew();
                    btnEdit.Text = "Abbrechen";
                    btnNeu.Text = "Speichern";
                }

    this.projektBindingSource.AddNew(); scheint nicht         private void projektBindingSource_AddingNew(object sender, AddingNewEventArgs e) zu starten,
    vermutlich muß ich Daten übergeben?

     



    • Bearbeitet microbender Sonntag, 15. Januar 2012 20:04
    Sonntag, 15. Januar 2012 19:30
  • Hallo,

    bitte schön... und mein "Auua" hat sich etwas gelegt...

    Den BindingNavigator hatte ich mehr der Schnelle verwendet, richtig tut der sowieso nichts,
    das kann man durch eine eigene ToolBar ebenso erreichen
    (Buttons gehen auch, sehen aber IMHO weniger hübsch aus ;-)

    Die AddNew Schaltfläche führt nichts weiter als ein BindingSource.AddNew() aus.
    Entsprechendes gilt für die anderen Schaltflächen, die die Move... Methoden usw. ausführen.

    Entscheidender wäre das BindingSource.AddNew, das das AddingNew Ereignis auslöst.
    Und nur wenn dort e.NewObject null ist, wird das Standardverhalten aktiviert, 
    was einem  DataView.AddNew entspricht.

    Wenn Du es in Deinen Code übernommen hast, und das Ereignis nicht eintritt,
    so schaue, ob Du es zugeordnet hast.

    Gruß Elmar

    Sonntag, 15. Januar 2012 20:21
    Beantworter
  • Mühsam ernährt sich das Eichhörnchen :)

    Ich hatte vergessen die Ereignisse zuzuordnen.
    Leider ist mein Problem noch immer, daß t_projekt und t_forecast in einem Vorgang gefüllt werden sollen,
    wenn Du da noch einen Vorschlag hast, dann biste mich los :)

    Dienstag, 17. Januar 2012 16:59
  • Hallo,

    wann "in einem Vorgang gefüllt"?

    Beim Bearbeiten müsste das Projekt schon vollständig sein, damit es gespeichert werden kann,
    wie z. B. hier der "projektName" ausgefüllt (u. a. deswegen der Debug-Code für Bequeme ;-)

    Dann wäre generell machbar:

                var projektRowView = (DataRowView)this.projektBindingSource.AddNew();
                projektRowView["projektname"] = "Neues Projekt";
                this.projektBindingSource.EndEdit();
    
                // optional in Datenbank speichern (funktioniert nur wenn vollständig)
                this.projektTableAdapter.Update(this.projektDataSet.t_projekt);
                var forecastRowView = (DataRowView)this.forecastBindingSource.AddNew();
                Console.WriteLine("Projekt ID = {0} / {1}", projektRowView["projektID"], forecastRowView["projektID"]);
    
    

    (wobei das Speichern in der Datenbank optional wäre, wenn nicht hast Du negative IDs)

    Da man aber häufig nicht alle Daten automatisiert eintragen kann, ist es dort sinnvoller,
    die Seiten nach und nach zu bearbeiten und hier z. B. Forecast erst freizugeben,
    wenn das Projekt alle notwendigen Werte enthält.

    (Und die Geschichte mit dem Delecting im Beispiel ist aus der Überlegung entstanden).

    Gruß Elmar

    Dienstag, 17. Januar 2012 17:42
    Beantworter
  • Ist der neue Code noch immer basierend auf Deinem Beispiel, oder ist das jetzt ohne die Handler?

    Der Vorgang den ich im Kopf habe ist folgender:

    Anwender klickt den Neu Button und trägt Daten sowohl für t_projekt als für t_forcast in einem Schwung ein und
    dann beendet den Vorgang mit Klick auf Speichern.

    Delecting?

    • Bearbeitet microbender Dienstag, 17. Januar 2012 18:43
    Dienstag, 17. Januar 2012 18:36
  • Hallo,

    ja, das basiert auf meinem Beispiel und setzt die gleichen Datenquellen voraus,
    die AddingNew Handler sind nur fürs Vorbelegen notwendig.

    Alles in einem Rutsch ist mit der Datenbindung relativ schwierig zu implementieren;
    denn am Ende stehen nunmal zwei Datenbank-Tabellen, die über eine Beziehung versorgt werden müssen.

    Ohne Datenbindung und manueller Prüfung könnte man es (leichter) machen -
    was aber den Codierungsaufwand in die Höhe treibt.

    IMO sollte es für den Anwender kein Problem sein, zunächst das Projekt vollständig
    (ausreichend) auszufüllen und danach erst die Forecast Daten.
    Etwas Benutzerführung ist immer besser, als sie wild darauf los tippen zu lassen.
    Denn jede Fehlereingabe bzw. das Beheben derselben liegt ansonsten beim Programmierer,
    und wenn es schief geht sowieso ;-).

    Gruß Elmar

     

    Dienstag, 17. Januar 2012 18:51
    Beantworter
  • Hallo,

    wann "in einem Vorgang gefüllt"?

    Beim Bearbeiten müsste das Projekt schon vollständig sein, damit es gespeichert werden kann,
    wie z. B. hier der "projektName" ausgefüllt (u. a. deswegen der Debug-Code für Bequeme ;-)

    Dann wäre generell machbar:

     

                var projektRowView = (DataRowView)this.projektBindingSource.AddNew();
                projektRowView["projektname"] = "Neues Projekt";
                this.projektBindingSource.EndEdit();
    
                // optional in Datenbank speichern (funktioniert nur wenn vollständig)
                this.projektTableAdapter.Update(this.projektDataSet.t_projekt);
                var forecastRowView = (DataRowView)this.forecastBindingSource.AddNew();
                Console.WriteLine("Projekt ID = {0} / {1}", projektRowView["projektID"], forecastRowView["projektID"]);
    
    

    (wobei das Speichern in der Datenbank optional wäre, wenn nicht hast Du negative IDs)

     

    Da man aber häufig nicht alle Daten automatisiert eintragen kann, ist es dort sinnvoller,
    die Seiten nach und nach zu bearbeiten und hier z. B. Forecast erst freizugeben,
    wenn das Projekt alle notwendigen Werte enthält.

    (Und die Geschichte mit dem Delecting im Beispiel ist aus der Überlegung entstanden).

    Gruß Elmar

    Diese Lösung funktioniert insofern, daß ein neuer Datensatz auch in t_forecast angelegt wird,
    aber alle Eingaben auf dem Forecast Tab werden nicht übernommen.

    Was muß ich machen, damit alle Forecast Eingaben bei

    var forecastRowView = (DataRowView)this.forecastBindingSource.AddNew();
    auch übernommen werden?
    .Current?

    BTW. ich habe jetzt eine checkbox, die mir bei Bedarf eine Console öffnet :)
    http://www.codeproject.com/Articles/9197/Console-and-WinForm-together-for-easy-debugging


    Montag, 23. Januar 2012 18:31
  • Hallo,

    auch für die forecastBindingSource muss ggf. ein EndEdit erfolgen,
    insbesondere wenn Du dort noch im Bearbeitungsmodus bist.

    Was die Konsole angeht:
    Das braucht man nicht, denn als Ausgaben von Console.WriteLine werden
    beim Debuggen im Standard direkt in das Ausgabe-Fenster (STRG+ALT+O) von Visual Studio umgeleitet.
    (zum Glück, denn ich mag keine MessageBox(en), die den Verkehr aufhalten ;-)

    Gruß Elmar

    Montag, 23. Januar 2012 20:09
    Beantworter
  • Hab meinen letzten Beitrag gelöscht, weil ich eine Lösung gefunden habe.

     

                        var oldforecastRowView = (DataRowView)this.forecastBindingSource.Current;
                        projektBindingSource.EndEdit();
                        projektTableAdapter.Update(this.projektDataSet.t_projekt);
                        forecastBindingSource.AddNew();
                        var forecastRowView = (DataRowView)this.forecastBindingSource.Current;
                        forecastRowView["forecastperson"] = oldforecastRowView["forecastperson"];
                        forecastRowView["chance"] = oldforecastRowView["chance"];
                        forecastBindingSource.EndEdit();
                        forecastTableAdapter.Update(this.projektDataSet.t_forecast);
    


    Ich weiß nicht, ob es so jetzt besonders klug ist, aber es funktioniert. In var oldforecastRowView sind alle Eingaben vorhanden und ich weise diese dann forecastRowView zu. Das einzig blöde ist natürlich, daß ich jetzt alle Felder per Hand angeben muss.

    Gibt es eine Möglichkeit einen DataMember (richtiger Begriff?) aus oldforecastRowViewzu entfernen - projektID, sodaß ich in einem Schwung alle Felder an forecastRowView übergeben kann?

     

    Freitag, 27. Januar 2012 17:10
  • Hallo,

    etwas ist der Code ein Widerspruch in sich ;-)
    Soweit ich das von hier sehen kann, müsste forecastRowView == Current == oldforecastRowView sein
    und Du somit die Zuweisung auf die Zeile selbst machen.

    Was Dir evtl. Probleme bereiten könnte, ist das Verhalten von BindingSource aber auch dem DataGridView.
    Die "merken" sich intern eine hinzugefügte Zeile als neue Zeile und löschen sie wieder,
    wenn die Zeile unverändert ist bzw. das Bearbeiten abgebrochen wird (DataGridView u. a. auch Escape)

    Wobei dies normalerweise durch EndEdit abgeschlossen würde (deswegen der vorherige Hinweis).

    Wie sehen denn Deine Ereignis-Behandlungsroutinen für AddingNew aus?
    Oder verwendest Du sie nicht (mehr)?

    Gruß Elmar

    Freitag, 27. Januar 2012 21:18
    Beantworter
  • Mein button Neu startet projektBindingSource.AddNew();
    projektBindingSource_AddingNew macht noch immer, was Du als Beispiel mir geben hast.

    in meiner unsäglichen button logik erfolgt fürs Speichern

    projektBindingSource.EndEdit();
    projektTableAdapter.Update(this.projektDataSet.t_projekt);
    forecastBindingSource.AddNew();
    forecastBindingSource.EndEdit();
    forecastTableAdapter.Update(this.projektDataSet.t_forecast);

    in sämtlichen Variationen werden nie die echten Eingaben aus dem Forecast Tab übernommen.

    Nachdem ich aber zum Button auch noch forecastBindingSource.AddNew(); hinzugefügt hatte und dann
    mit var oldTeamRowView = (DataRowView)this.teamBindingSource.Current; die Eingaben bevor forecastBindingSource.AddNew(); eingesammelt hatte, da warendie Eingaben da.

    Wie gesagt, das gesamte Prinzip ist mir noch schleierhaft und es ist schwer Dokumentation für sowas zu finden.

    Ich hab mir ja schon Deinen Vorschlag zu Herzen genommen und gestalte die Eingabe neuer Projekte nun mit einem Wizzard, zum Glück haben wir eine Lizenz von devComponents gekauft.

     

    Freitag, 27. Januar 2012 22:54
  • Hallo,

    bevor ich endlos spekuliere: Kannst Du das Projekt zur Verfügung stellen -
    wenn nicht öffentlich, dann ggf. auch per E-Mail an mich?

    Der Vorschlag mit dem Wizard kommt sicherlich nicht von mir;
    ich bin nie ein Freund von Assistenten und Zauberlehrlingen und Klick-Dir-eine-Oberfläche gewesen ;-)

    Gruß Elmar

    Samstag, 28. Januar 2012 09:12
    Beantworter
  • Hallo,

    bevor ich endlos spekuliere: Kannst Du das Projekt zur Verfügung stellen -
    wenn nicht öffentlich, dann ggf. auch per E-Mail an mich?

    Der Vorschlag mit dem Wizard kommt sicherlich nicht von mir;
    ich bin nie ein Freund von Assistenten und Zauberlehrlingen und Klick-Dir-eine-Oberfläche gewesen ;-)

    Gruß Elmar

    Ich kann Dir aufgrund der verwendeten Komponenten mein Projekt nicht schicken.
    Der Wizzard von denen ist ja nur eine Navigationsgeschichte, ich führe meine Anwender jetzt Schritt für Schritt durch die Erstellung neuer Projekte, im ersten Schritt erzeuge ich das Projekt und einen leeren Forecast. In den nachfolgenden Schritten ist es nun sehr einfach, da ich update code verwende.
    Mein Auftraggeber findet die Vorgehensweise gut, so nun bleibt nur noch die Frage welche Deiner Antworten als Beantwortet verwenden werden sollte :)

    Montag, 30. Januar 2012 20:29
  • Hallo,

    das war auch nur ein Angebot (was ich eher selten mache).

    Welche meiner Antworten Dir gefällt steht Dir frei zu entscheiden.

    Gruß Elmar

    Dienstag, 31. Januar 2012 08:58
    Beantworter
  • Hallo xpi3000,

    Ich möchte Dich bitten folgendes lesen und die Beiträge die Dir geholfen haben zu bewerten.

    Vielen Dank.

    Nutzen Sie die Bewertungsfunktionen ("Antwort" und "Hilfreich") in den MSDN Foren! Unter anderem können andere später eine Lösung schneller finden. Es ist also wünschenswert, dass die fragenden (Benutzer) die Postings/Beiträge anderer Beantworter bewerten.
    Hier dazu die wichtigsten Anhaltspunkte aus den Forenregeln und FAQs.


    Lösungsbeiträge als „Die Antwort“ markieren:

    Bitte markieren Sie den Beitrag, der zur Lösung geführt hat, als "Die Antwort".
    Durch Bewerten eines Beitrags als "Die Antwort" können andere Teilnehmer die Lösung schneller finden. Außerdem können Sie dem Benutzer, der die Antwort eingereicht hat, für seinen Beitrag danken und zur Steigerung der Antwortqualität in der Diskussionsgruppe beitragen.
    [Quelle: Forenregeln]

    Wie bewerte ich einen Beitrag? Um einen Beitrag als hilfreich zu bewerten, klicken Sie in einem beliebigen Beitrag auf Als hilfreich bewerten. Sie können Ihre Stimme nur einmal für einen Beitrag abgeben.
    [Quelle: Häufig gestellte Fragen]

    Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Mittwoch, 1. Februar 2012 10:15
    Moderator
  • ****************************************************************************************************************
    Dieser Thread wurde mangels weiterer Beteiligung des Fragestellenden ohne bestätigte Lösung abgeschlossen.
    Neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.
    ****************************************************************************************************************

    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Montag, 20. Februar 2012 15:14
    Moderator