Laden...

Frage zu DataBinding und BindingSource.AddNew()

Letzter Beitrag vor einem Jahr 5 Posts 767 Views
Frage zu DataBinding und BindingSource.AddNew()

Hallo zusammen,

ich habe eine BindingSource mit einigen DataBindings an verschiedene Steuerelemente. Ändern und Löschen von Datensätzen funktioniert einwandfrei. Einzig mit dem Hinzufügen neuer DS habe ich ein Problem. Ich verwende die Methode BindingSource.AddNew() und erzeuge dann das Formular zum Eingeben der Daten. Dem Formular wird die BindingSource als Parameter übergeben:

		private void BtnZeitNeu_Click(object sender, EventArgs e)
		{
			BsZeiten.AddNew();
			ZeitEditieren();
		}

		private void ZeitEditieren()
		{
			try
			{
				EingabeZeit form = new(BsZeiten);
				if (form.ShowDialog() == DialogResult.OK)
				{
					Cursor = Cursors.WaitCursor;
					BsZeiten.EndEdit();
					Data.UpdateZeiten();
				}
				else
				{
					BsZeiten.CancelEdit();
				}
			}
			catch (Exception Ex)
			{
				Helper.ShowException(Ex);
			}
			finally
			{
				Cursor = Cursors.Default;
			}
		}

Bei der Initialisierung der Form werden die DataBindings angelegt:

		internal EingabeZeit(BindingSource BsZeiten)
		{
			InitializeComponent();
			_BsZeiten = BsZeiten;

			try
			{

				Binding BdgBeginn = new("Value", _BsZeiten, "Beginn", true, DataSourceUpdateMode.OnPropertyChanged, DateTime.Now);
				Binding BdgEnde = new("Value", _BsZeiten, "Ende", true, DataSourceUpdateMode.OnPropertyChanged, DateTime.Now);
				Binding BdgArt = new("SelectedIndex", _BsZeiten, "Art", true, DataSourceUpdateMode.OnPropertyChanged, 0);
				DtpBeginn.DataBindings.Add(BdgBeginn); //DateTimePicker
				DtpEnde.DataBindings.Add(BdgEnde);
				CmbArt.DataBindings.Add(BdgArt); //ComboBox
				
				//.... weitere Bindungen
			}
			catch (Exception Ex)
			{
				Helper.ShowException(Ex);
			}
		}

Mein Problem ist nun, dass beim Schließen der Form mit DialogResult.OK keine Werte in dem neuen Datensatz stehen. Die DataBindings funktionieren irgendwie nicht, obwohl die Binding-Ereignisse Format und BindingComplete geworfen werden. Einzig das Ereignis Parse wird nicht geworfen. Es wird aber geworfen, wenn ich einen Wert in der Form ändere. Wenn jedoch die Standardwerte der Bindings nicht verändert werden, so werden die nicht in den neuen Datensatz eingetragen.

Was mache ich da nur falsch?

Danke für Eure Antworten!

Auf welche Datenquelle (BindingSource.DataSource) hast du denn gebunden, d.h. welches Objekt (bzw. Liste von Objekten), das die von dir verwendeten Eigenschaften Beginn, Ende und Art enthält?

Außerdem solltest du bei BindingSource.AddNew das Ereignis BindingSource.AddingNew verwenden, um das Datenobjekt hinzuzufügen, s.a. Vorgehensweise: Anpassen der Hinzufügung von Elementen mithilfe der BindingSource in Windows Forms.

Wenn du jedoch nur ein einzelnes Objekt als Datenquelle hast (und keine Liste), dann kannst du auch direkt dieses Objekt beim Binding angeben, anstatt eine BindingSource zu verwenden.

Als Tutorial (wenn auch in englisch) habe ich schon öfters A Detailed Data Binding Tutorial empfohlen.


PS: Du solltest statt dem Eigenschaften-String besser nameof(...) verwenden, so daß der Compiler Tippfehler erkennt (ist leider in den meisten Tutorials nicht so, da diese oft noch direkt auf .NET + C# 2.0 beruhen).

Vielen Dank für die Hinweise! Den Artikel werde ich durcharbeiten (und nameof(...) verwenden).

Es handelt sich um DataTables. Die DataSource ist eine andere BindingSource im Sinne einer Master/Detail-Struktur (Tage haben Zeiten / Zeiten haben Beginn, Ende, Art usw.). Hier ein Ausschnitt:

DataSet.Relations.Add("TageZeiten", Tage.Columns["Id"], Zeiten.Columns["TagId"], true);
BsTage.DataSource = Data.DataSet;
BsTage.DataMember = "Tage";
BsZeiten.DataSource = BsTage;
BsZeiten.DataMember = "TageZeiten";

Ich dachte, wenn die zugrunde liegende Liste eine DataTable ist, muss das Ereignis BindingSource.AddingNew nicht verwendet werden.

M.E. hast du eine zu tiefe hierarchische Binding-Struktur: BindingSource → BindingSource → DataSet.

Du mußt schon auf eine DataTable oder ein anderes konkrete Datenobjekt binden. Oder ist "Tage"der Name einer DataTable aus dem DataSet Data.DataSet?

Am besten, du testest es umgekehrt, indem du ersteinmal direkt an an eine DataTable bindest und wenn das einwandfrei funktioniert, dann schaltest du die BindingSource(s) dazwischen.

Ja, "Tage" ist eine DataTable aus dem DataSet. Ich habe die Hierarchie so wie empfohlen angelegt und ändern/löschen funktioniert ja auch. Nur das bei BindingSource.AddNew ein Datensatz mit leeren Eigenschaften (jeweils DBNull) angelegt wird und die Datenbindung nicht funktioniert.

Ohne Hierarchie habe ich auch schon probiert, funktioniert ebenfalls nicht. Ohne BindingSource muss ich bei der DataTable halt mit NewRow eine neuen Datensatz erzeugen, die Eigenschaften "manuell" beschreiben und der Table hinzufügen. Dies funktioniert natürlich. Auch mit BindingSource habe ich die Eigenschaften "manuell" beschrieben und dann gespeichert. Auch dies funktioniert.

Ich hätte es nur gerne mit dem DataBinding umgesetzt, denn wozu ist diese Methode denn da? Mit BindingSource.AddNew wird exakt das Gleiche in der zugrunde liegenden Table ausgelöst (NewRow).

Das sehr gute Tutorial hat mich in diesem Punkt nicht weitergebracht.