{"id":55000105,"date":"2017-10-01T00:00:00","date_gmt":"2020-03-27T19:28:46","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=105"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Drag_and_Drop_mit_ListBoxElementen","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Drag_and_Drop_mit_ListBoxElementen\/","title":{"rendered":"Drag and Drop mit ListBox-Elementen"},"content":{"rendered":"<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/pic_105_001.png\" alt=\"F&uuml;r das Hin- und Herziehen von Eintr&auml;gen zweier Listenfelder w&auml;re Drag and Drop eine interessante Alternative.\" width=\"399,7285\" height=\"303,4209\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: F&uuml;r das Hin- und Herziehen von Eintr&auml;gen zweier Listenfelder w&auml;re Drag and Drop eine interessante Alternative.<\/span><\/b><\/p>\n<p><b>Im Artikel Drag and Drop-Grundlagen haben wir uns die grundlegenden Techniken f&uuml;r die Implementierung von Drag and Drop-Funktionen in WPF-Benutzeroberfl&auml;chen angesehen. Nun gehen wir einen Schritt weiter und wollen Drag and Drop f&uuml;r das Fenster namens Versendungen unserer Beispielanwendung Bestellverwaltung umsetzen. Hier geht es dann nicht nur um einfaches Bewegen von Elementen per Maus, sondern auch um die Anpassung der dahinter stehenden Daten beziehungsweise Tabellen.<\/b><\/p>\n<p>Wozu braucht man aber Drag and Drop so dringend In der Tat lassen sich die meisten T&auml;tigkeiten, die Sie damit ausf&uuml;hren k&ouml;nnen, auch auf andere Weise realisieren. Allerdings ist Drag and Drop und somit das einfache Ziehen von Elementen der Benutzeroberfl&auml;che mit der Maus doch ein sehr intuitiver Weg, um Aktionen durchzuf&uuml;hren. Ein Beispiel sind die beiden Listenfelder aus dem Artikel <b>m:n-Beziehung mit Listenfeld <\/b>(siehe Bild 1). Im Artikel haben wir Schaltfl&auml;chen bereitgestellt, mit denen ein oder alle Artikel von einem Listenfeld zum anderen &uuml;bertragen werden k&ouml;nnen. Nun wollen wir uns weiter vortasten und Drag and Drop-Funktionalit&auml;t zu diesem Fenster hinzuf&uuml;gen. Zuvor schauen wir uns das jedoch an einigen grundlegenden Beispielen an.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/pic_105_001.png\" alt=\"F&uuml;r das Hin- und Herziehen von Eintr&auml;gen zweier Listenfelder w&auml;re Drag and Drop eine interessante Alternative.\" width=\"399,7285\" height=\"303,4209\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: F&uuml;r das Hin- und Herziehen von Eintr&auml;gen zweier Listenfelder w&auml;re Drag and Drop eine interessante Alternative.<\/span><\/b><\/p>\n<h2>Drag and Drop mit Listenfeldern<\/h2>\n<p>Nun schauen wir uns an, wie wir Drag and Drop in unser Beispiel mit den Versendungen einbauen. In der Beispielanwendung <b>Bestellverwaltung_SQLite <\/b>f&uuml;gen wir dazu eine neue <b>Window<\/b>-Klasse namens <b>Versendungen_DragDrop <\/b>hinzu und kopieren den XAML-Code der Klasse <b>Versendungen <\/b>dort hinein. Passen Sie danach das <b>Window<\/b>-Element so an, dass die Klasse <b>Bestellverwaltung.Versendungen_DragDrop <\/b>referenziert wird und der Titel des Fensters angepasst ist:<\/p>\n<pre>&lt;Window x:Class=\"Bestellverwaltung.Versendungen_DragDrop\"\r\n         xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\r\n         xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\r\n         xmlns:d=\"http:\/\/schemas.microsoft.com\/expression\/blend\/2008\"\r\n         xmlns:mc=\"http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006\"\r\n         xmlns:local=\"clr-namespace:Bestellverwaltung\"\r\n         mc:Ignorable=\"d\"\r\n         Title=\"Versendungen Drag and Drop\" Height=\"300\" Width=\"400\"&gt;<\/pre>\n<p>Dann kopieren Sie auch den Code der Code behind-Klasse von <b>Versendungen.xaml.cs <\/b>in <b>Versendungen_DragDrop.xaml.cs<\/b>. &Auml;ndern Sie hier zun&auml;chst in der folgenden Zeile Versendungen in <b>Versendungen_DragDrop<\/b>:<\/p>\n<pre>public partial class Versendungen_DragDrop : Window, INotifyPropertyChanged {<\/pre>\n<p>Der gleiche Schritt ist auch nochmal in der ersten Zeile der Konstruktor-Methode n&ouml;tig:<\/p>\n<pre>public Versendungen_DragDrop() {<\/pre>\n<p>Danach k&ouml;nnen wir die Funktionen f&uuml;r das Drag and Drop hinzuf&uuml;gen.<\/p>\n<h2>Drag and Drop-Vorgang starten<\/h2>\n<p>Wir beginnen mit dem linken <b>ListBox<\/b>-Element. Hier legen wir gar nicht erst die Methode f&uuml;r das Ereignis <b>MouseDown <\/b>an, von dem wir dank der Experimente im Artikel <b>Drag and Drop-Grundlagen <\/b>schon wissen, dass es nicht feuert. Stattdessen legen wir direkt das entsprechende Tunneling-Ereignis <b>PreviewMouseDown <\/b>an:<\/p>\n<pre>&lt;ListBox x:Name=\"lstAusgewaehlteKunden\" Grid.Column=\"0\" Grid.Row=\"1\" Margin=\"5\"\r\n     ItemsSource=\"{Binding AusgewaehlteKunden}\"\r\n     DisplayMemberPath=\"Nachname\"\r\n     SelectedValuePath=\"ID\" MouseDoubleClick=\"lstAusgewaehlteKunden_MouseDoubleClick\"         PreviewMouseDown=\"lstAusgewaehlteKunden_PreviewMouseDown\"\/&gt;<\/pre>\n<p>Daf&uuml;r hinterlegen wir nun die folgende Ereignismethode:<\/p>\n<pre>private void lstAusgewaehlteKunden_PreviewMouseDown(object sender, MouseButtonEventArgs e) {\r\n     if (e.LeftButton == MouseButtonState.Pressed) {\r\n         DragDrop.DoDragDrop(lstAusgewaehlteKunden, lstAusgewaehlteKunden.SelectedItem, DragDropEffects.Copy);\r\n     }\r\n}<\/pre>\n<p>Wenn wir die Anwendung nun starten, das Fenster <b>Versendungen_DragDrop <\/b>aufrufen und einen der Eintr&auml;ge der linken List-Box ziehen wollen, erhalten wir den Fehler aus Bild 2.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/pic_105_001.png\" alt=\"Fehler beim Versuch, ein Element aus der linken ListBox zu ziehen\" width=\"649,559\" height=\"483,0497\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Fehler beim Versuch, ein Element aus der linken ListBox zu ziehen<\/span><\/b><\/p>\n<p>Da der Fehler nicht direkt an Ort und Stelle gemeldet wird, m&uuml;ssen wir eine Fehlerbehandlung hinzuf&uuml;gen:<\/p>\n<pre>private void lstAusgewaehlteKunden_PreviewMouseDown(object sender, MouseButtonEventArgs e) {\r\n     try {\r\n         if (e.LeftButton == MouseButtonState.Pressed) {\r\n             DragDrop.DoDragDrop(lstAusgewaehlteKunden, lstAusgewaehlteKunden.SelectedItem, DragDropEffects.Copy);\r\n         }\r\n     }\r\n     catch (System.Exception ex) {\r\n         MessageBox.Show(ex.Message);\r\n         throw;\r\n     }\r\n}<\/pre>\n<p>Dies liefert dann die Meldung aus Bild 3. Offensichtlich versuchen wir auf irgendeine Weise, ein Element des Typs <b>Null <\/b>zu ziehen. Welches das ist, erfahren wir per Debugging.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/pic_105_002.png\" alt=\"Der gleiche Fehler, diesmal mit Fehlerbehandlung\" width=\"424,7115\" height=\"333,843\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Der gleiche Fehler, diesmal mit Fehlerbehandlung<\/span><\/b><\/p>\n<p>Dazu setzen wir einen Haltepunkt in der ersten Zeile der Methode <b>lstAusgewaehlteKunden_PreviewMouseDown <\/b>und schauen uns den Inhalt der Parameter der Methode <b>DragDrop.DoDragDrop <\/b>an. Hier erfahren wir, dass die <b>SelectedItem<\/b>-Eigenschaft des <b>ListBox<\/b>-Elements den Wert <b>null <\/b>liefert (siehe Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_05\/pic_105_003.png\" alt=\"Debugging der fehlerhaften Stelle\" width=\"700\" height=\"82,86606\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Debugging der fehlerhaften Stelle<\/span><\/b><\/p>\n<p>Wir m&uuml;ssen also offensichtlich einen ganz anderen Weg w&auml;hlen, um beim Herunterdr&uuml;cken der Maustaste Zugriff auf das dabei &uuml;berfahrene Element zu bekommen. Dabei nutzen wir eine kleine Hilfsklasse, um das zu verschiebende Element zwischenzuspeichern:<\/p>\n<pre>public class DragDropData {\r\n     public object ActualData { get; set; }\r\n}<\/pre>\n<p>Dieses soll in der Eigenschaft <b>ActualData <\/b>das zu verschiebende Element speichern. Die Ereignismethode <b>lstAusgewaehlteKunden_PreviewMouseDown <\/b>&auml;ndern wir wie folgt ab:<\/p>\n<pre>private void lstAusgewaehlteKunden_PreviewMouseDown(object sender, MouseButtonEventArgs e) {\r\n     try {\r\n         if (e.LeftButton == MouseButtonState.Pressed) {\r\n             var item = (ListBoxItem)ItemsControl.ContainerFromElement(lst, (DependencyObject)e.OriginalSource);\r\n             Kunde kunde = (Kunde)item.Content;\r\n             DragDropData dragDropData = new DragDropData\r\n             {\r\n                 ActualData = kunde,\r\n             };\r\n             DragDrop.DoDragDrop(lst, dragDropData, DragDropEffects.Move);\r\n         }\r\n     }\r\n     catch (System.Exception ex) {\r\n         MessageBox.Show(ex.Message);\r\n         throw;\r\n     }\r\n}<\/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\/55000105\/\">\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\/55000105?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\/55000105\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"22c77db969\"\/>\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>Im Artikel Drag and Drop-Grundlagen haben wir uns die grundlegenden Techniken f&uuml;r die Implementierung von Drag and Drop-Funktionen in WPF-Benutzeroberfl&auml;chen angesehen. Nun gehen wir einen Schritt weiter und wollen Drag and Drop f&uuml;r das Fenster namens Versendungen unserer Beispielanwendung Bestellverwaltung umsetzen. Hier geht es dann nicht nur um einfaches Bewegen von Elementen per Maus, sondern auch um die Anpassung der dahinter stehenden Daten beziehungsweise Tabellen.<\/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":[662017,66052017,44000002,44000027,44000015],"tags":[],"yst_prominent_words":[],"class_list":["post-55000105","post","type-post","status-publish","format-standard","hentry","category-662017","category-66052017","category-Benutzeroberflaeche_mit_WPF","category-Excel_programmieren","category-WPFSteuerelemente"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000105","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=55000105"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000105\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000105"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000105"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}