{"id":55000027,"date":"2016-04-01T00:00:00","date_gmt":"2020-03-27T19:17:51","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=27"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Bindung_zwischen_Steuerelementen","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Bindung_zwischen_Steuerelementen\/","title":{"rendered":"Bindung zwischen Steuerelementen"},"content":{"rendered":"<p><b>Unter VBA waren die M&ouml;glichkeiten der Datenbindung &uuml;berschaubar: Formulare, Berichte und einige Steuerelemente wiesen entsprechende Eigenschaften auf, die an Tabellen, Abfragen oder auch Wertlisten oder Felder gekn&uuml;pft werden konnten. Unter WPF und C# sieht es ganz anders aus. Hier stehen Objekte im Vordergrund. Dieser Artikel zeigt daher zun&auml;chst, wie Sie Elemente wie Steuerelemente an die Eigenschaften anderer Elemente binden.<\/b><\/p>\n<h2>Einf&uuml;hrung<\/h2>\n<p>Wenn Sie zuvor mit Access programmiert haben und dieses Magazin lesen, um zu erfahren, wie das, was Sie zuvor mit Access erledigt haben, mit C#\/WPF gelingt, wollen Sie vermutlich nur eins: Daten aus Tabellen oder Abfragen in Fenstern und Steuerelementen anzeigen und diese zum Bearbeiten bereitstellen. Beim Thema Datenbindung ist WPF\/C# allerdings etwas breiter aufgestellt, da es nicht nur auf Datenquellen wie Tabellen oder Abfragen fixiert ist, sondern prim&auml;r auf Objekte als Datenlieferant.<\/p>\n<p>Daher r&auml;umen wir das Feld etwas weiter auf und beginnen nicht gleich damit, die Daten per Fenster und Steuerelementen bereitzustellen. Zun&auml;chst einmal schauen wir uns an, wie Sie verschiedene Elemente aneinander binden k&ouml;nnen. Davon abgesehen haben Sie ja in vorhergehenden Artikeln der Kategorie <b>Datenzugriffstechnik <\/b>bereits einige Beispiele erhalten, wie dies gelingt. Grunds&auml;tzlich dient die Bindung aber dazu, nicht nur die Eigenschaften eines Elements an ein anderes Element zu binden, sondern die gebundenen Daten k&ouml;nnen auch aus Quellen wie einer XML-Datei, Auflistungen oder Datenbanken stammen.<\/p>\n<h2>Von Textfeld zu Textfeld<\/h2>\n<p>Im ersten Beispiel wollen wir schlicht und einfach, dass ein Textfeld den Inhalt eines anderen Textfeldes anzeigt. Unter Access\/VBA haben Sie dazu das <b>Nach Aktualisierung<\/b>-Ereignis genutzt &#8211; oder auch das <b>Bei &Auml;nderung<\/b>-Ereignis. Das Erste hat beispielsweise auf die Eingabe- oder Tabulatortaste reagiert, Letzteres auf jede einzelne &Auml;nderung des Inhalts. Etwas eleganter konnten Sie dies erledigen, wenn Sie das erste Textfeld gleich der Eigenschaft <b>Steuerelementinhalt <\/b>des zweiten Textfeldes zugewiesen haben. Damit war noch nicht einmal mehr Code notwendig, um den Inhalt des ersten Textfeldes nach &Auml;nderungen in das zweite Textfeld zu &uuml;bertragen.<\/p>\n<p>Unter WPF\/C# wollen wir uns gleich um die zweite Variante k&uuml;mmern, also das zweite Textfeld an das erste Textfeld binden. Dazu f&uuml;gen Sie einem Fenster eines neuen Projekts zwei Textfelder namens <b>txtFeld1 <\/b>und <b>txtFeld2 <\/b>hinzu:<\/p>\n<pre>&lt;Window x:Class=\"Datenbindung.MainWindow\" ... Title=\"MainWindow\" Height=\"350\" Width=\"525\"&gt;\r\n     &lt;Grid&gt;\r\n         &lt;Label x:Name=\"lbl1\" ... \/&gt;\r\n         &lt;Label x:Name=\"lbl2\" ... \/&gt;\r\n         &lt;TextBox x:Name=\"txtFeld1\" ... \/&gt;\r\n         &lt;TextBox x:Name=\"txtFeld2\" ... \/&gt;\r\n     &lt;\/Grid&gt;\r\n&lt;\/Window&gt;<\/pre>\n<p>Damit k&ouml;nnen Sie nun den Inhalt der beiden Textfelder beliebig &auml;ndern &#8211; es tut sich nichts. Dies &auml;ndern wir, indem wir die Methode <b>MainWindow <\/b>im C#-Modul des Fensters wie folgt um vier Zeilen erweitern:<\/p>\n<pre>public MainWindow() {\r\n     InitializeComponent();\r\n     Binding binding = new Binding();\r\n     binding.ElementName = \"txtFeld1\";\r\n     binding.Path = new PropertyPath(\"Text\");\r\n     txtFeld2.SetBinding(TextBox.TextProperty, binding);\r\n}<\/pre>\n<p>Diese vier Zeilen binden das zweite Feld so an das erste Feld, dass dieses immer den Inhalt des ersten Feldes anzeigt (siehe Bild 1). In diesem Fall werden &Auml;nderungen am Text des ersten Textfeldes direkt in das zweite Textfeld &uuml;bertragen. &Auml;nderungen am zweiten Textfeld landen erst nach dem Verlassen im ersten Textfeld &#8211; wie Sie dieses Verhalten &auml;ndern, erfahren Sie weiter unten.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_02\/pic_27_001.png\" alt=\"Das untere Textfeld ist an das obere Textfeld gebunden.\" width=\"425\" height=\"171,6545\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Das untere Textfeld ist an das obere Textfeld gebunden.<\/span><\/b><\/p>\n<p>Schauen wir uns die vier Zeilen im Detail an. Die erste Zeile erzeugt ein neues Objekt des Typs <b>Binding<\/b>:<\/p>\n<pre>Binding binding = new Binding();<\/pre>\n<p>Die zweite Zeile weist der Eigenschaft <b>ElementName <\/b>des <b>Binding<\/b>-Objekts den Namen des ersten Textfelds <b>txtFeld1 <\/b>zu:<\/p>\n<pre>binding.ElementName = \"txtFeld1\";<\/pre>\n<p>Im Gegensatz zu Access\/VBA, wo sich der Steuerelementinhalt eines Steuerelements immer auf den Steuerelementinhalt des angegebenen Quellsteuerelements bezogen hat, k&ouml;nnen Sie unter WPF alle Eigenschaften des mit Source angegebenen Objekts als Quellwert nutzen. In diesem Fall ist dies die Eigenschaft <b>Text<\/b>, die wir als neues <b>PropertyPath<\/b>-Objekt der Eigenschaft <b>Path <\/b>des <b>Binding<\/b>-Objekts zuweisen:<\/p>\n<pre>binding.Path = new PropertyPath(\"Text\");<\/pre>\n<p>Schlie&szlig;lich m&uuml;ssen wir noch festlegen, welches Steuerelement das neue <b>Binding<\/b>-Objekt nutzen soll und welches die Zieleigenschaft ist. Dies erledigen wir mit der Methode <b>SetBinding <\/b>wie in der folgenden Anweisung. Der erste Parameter ist die Zieleigenschaft, hier <b>TextProperty<\/b>, der zweite das <b>Binding<\/b>-Objekt:<\/p>\n<pre>txtFeld2.SetBinding(TextBox.TextProperty, binding);<\/pre>\n<h2>Die Binding-Klasse und die Dependency Property<\/h2>\n<p>Die hier verwendete <b>Binding<\/b>-Klasse legt also fest, wie die Bindung zwischen einer Komponente wie etwa einem Steuerelement und der Datenquelle, hier die Eigenschaft eines Steuerelements, erfolgt. Dabei haben wir hier bereits die folgenden Eigenschaften genutzt:<\/p>\n<ul>\n<li><b>ElementName<\/b>: Name des als Datenquelle verwendeten Steuerelements<\/li>\n<li><b>Path<\/b>: Eigenschaft, aus der die Daten stammen<\/li>\n<\/ul>\n<p>Mit dem ersten Parameter der <b>SetBinding<\/b>-Methode haben wir oberfl&auml;chlich betrachtet einfach die Eigenschaft des Objekts <b>txtFeld2 <\/b>festgelegt, das gebunden werden soll. Aber warum geben wir dann nicht den Namen der Eigenschaft, also <b>Text<\/b>, sondern <b>TextBox.TextProperty <\/b>als Parameter an Weil dieser Parameter eine sogenannte <b>Dependency Property<\/b>, zu Deutsch Abh&auml;ngigkeitseigenschaft, erwartet.<\/p>\n<p>Diese Dependency Properties haben die in Zusammenhang mit dem Binding interessante Eigenschaft, Automatismen f&uuml;r die Benachrichtigung &uuml;ber &Auml;nderungen bereitzustellen &#8211; in diesem Fall f&uuml;r den Zweck, &Auml;nderungen am Quellwert an das Ziel zu &uuml;bergeben und nach Wunsch auch umgekehrt. F&uuml;r Access-Nutzer ist das in etwa mit der Synchronisierung von Haupt- und Unterformular &uuml;ber die beiden Eigenschaften <b>Verkn&uuml;pfen von <\/b>und <b>Verkn&uuml;pfen nach <\/b>vergleichbar &#8211; tr&auml;gt man dort die Feldnamen der verkn&uuml;pften Felder der beiden Tabellen aus Haupt- und Unterformular ein, zeigt das Unterformular automatisch die zum aktuellen Datensatz im Hauptformular passenden Datens&auml;tze des Unterformulars an.<\/p>\n<h2>Weitere Eigenschaften der Binding-Klasse<\/h2>\n<p>Die <b>Binding<\/b>-Klasse liefert noch weitere interessante Eigenschaften:<\/p>\n<ul>\n<li><b>Converter<\/b>: Gibt einen m&ouml;glichen Konverter f&uuml;r die zu bindenden Daten an.<\/li>\n<li><b>FallbackValue<\/b>: Wert, den das Ziel annehmen soll, falls das gebundene Objekt oder die Eigenschaft den Wert <b>Null <\/b>liefert.<\/li>\n<li><b>IsAsync<\/b>: Legt mit <b>True <\/b>fest, dass die Bindung asynchron hergestellt wird.<\/li>\n<li><b>Mode<\/b>: Legt fest, wie die Bindung hergestellt wird. M&ouml;gliche Werte: <b>Default <\/b>(&uuml;bernimmt den Standardwert f&uuml;r die jeweilige Dependency Property), <b>OneTime <\/b>(nur einmalige Aktualisierung), <b>OneWay <\/b>(&auml;ndert nur von der Quelle zum Ziel, aber nicht umgekehrt), <b>OneWayToSource <\/b>(&auml;ndert nur vom Ziel zur Quelle), <b>TwoWay <\/b>(&auml;ndert von der Quelle zum Ziel und umgekehrt)<\/li>\n<li><b>Source<\/b>: Quellobjekt der Datenbindung<\/li>\n<li><b>TargetNullValue<\/b>: Wert, falls das gebundene Element keinen Wert liefert, also nicht vorhanden ist (siehe weiter unten)<\/li>\n<li><b>UpdateSourceTrigger<\/b>: Gibt an, wie die Quelle in Abh&auml;ngigkeit vom Inhalt des Ziels ge&auml;ndert werden soll. In unserem Beispiel &auml;ndert sich der Inhalt der Quelle, sobald das ge&auml;nderte Zieltextfeld den Fokus verliert. Dies entspricht der Einstellung <b>LostFocus<\/b>. Wenn Sie den Wert <b>PropertyChanged <\/b>verwenden, wird auch die Quelle nach der Eingabe eines jeden Zeichens in das Zieltextfeld ge&auml;ndert (siehe Beispiel 5).<\/li>\n<\/ul>\n<h2>Textfelder binden per XAML<\/h2>\n<p>Das Ganze l&auml;sst sich per XAML noch einfacher abbilden. Hierzu f&uuml;gen wir dem Formular zwei weitere Textfelder namens <b>txtFeld3 <\/b>und <b>txtFeld4<\/b> hinzu. F&uuml;r das zweite &auml;ndern Sie das Attribut <b>Text<\/b>, das ja zuvor eine Zeichenkette enthielt, wie folgt (siehe Beispiel 2 im Beispielprojekt):<\/p>\n<pre>&lt;TextBox x:Name=\"txtFeld4\" ... \r\n     Text=\"{Binding ElementName=txtFeld3, Path=Text}\"\/&gt;<\/pre>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000027\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/data\/wp\/v2\/posts\/55000027?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000027\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"9fac6dd15a\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Unter VBA waren die M&ouml;glichkeiten der Datenbindung &uuml;berschaubar: Formulare, Berichte und einige Steuerelemente wiesen entsprechende Eigenschaften auf, die an Tabellen, Abfragen oder auch Wertlisten oder Felder gekn&uuml;pft werden konnten. Unter WPF und C# sieht es ganz anders aus. Hier stehen Objekte im Vordergrund. Dieser Artikel zeigt daher zun&auml;chst, wie Sie Elemente wie Steuerelemente an die Eigenschaften anderer Elemente binden.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66022016,662016,44000023,44000028,44000003],"tags":[],"yst_prominent_words":[66062041,66062043,66062096],"class_list":["post-55000027","post","type-post","status-publish","format-standard","hentry","category-66022016","category-662016","category-PowerApps","category-Word_programmieren","category-WPFGrundlagen"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000027","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000027"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000027\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000027"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000027"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000027"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000027"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}