{"id":2969,"date":"2022-10-22T20:50:54","date_gmt":"2022-10-22T18:50:54","guid":{"rendered":"https:\/\/ekiwi.de\/?p=2969"},"modified":"2022-10-22T20:57:55","modified_gmt":"2022-10-22T18:57:55","slug":"c-xaml-binding-mit-mehreren-properties","status":"publish","type":"post","link":"https:\/\/ekiwi.de\/index.php\/2969\/c-xaml-binding-mit-mehreren-properties\/","title":{"rendered":"C#\/XAML: Binding mit mehreren Properties"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Inhalt<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/ekiwi.de\/index.php\/2969\/c-xaml-binding-mit-mehreren-properties\/#ViewModel\" >ViewModel<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/ekiwi.de\/index.php\/2969\/c-xaml-binding-mit-mehreren-properties\/#Multibinding_in_XAML-Datei\" >Multibinding in XAML-Datei<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/ekiwi.de\/index.php\/2969\/c-xaml-binding-mit-mehreren-properties\/#Converter-Klasse\" >Converter-Klasse<\/a><\/li><\/ul><\/nav><\/div>\n<p>Wer unter Visual Studio mit C# programmiert und <abbr title=\"Windows Presentation Foundation\">WPF<\/abbr>-Projekte bearbeitet, kommt ums Binding innerhalb der <abbr title=\"Extensible Application Markup Language\">XAML<\/abbr>-Dateien nicht drumherum. Binding ist auch eine feine, praktische Sache, doch stellt es einen auch immer wieder vor H\u00fcrden und scheint oftmals erstmal aufwendiger als CodeBehind zu benutzen. Eine Problemstellung ist, wenn man ein Binding mit mehreren Properties machen m\u00f6chte. Das hei\u00dft man m\u00f6chte verschiedene Eigenschaften an ein Element oder eine Element-Eigenschaft binden.<\/p>\n<p>Nehmen wir als Beispiel eine Textbox und deren Eigenschaft &#8222;<em>IsEnabled<\/em>&#8222;. Ob die Textbox &#8222;enabled&#8220; ist, soll mehreren anderen UI-Elementen abh\u00e4ngen. Und zwar einmal davon, ob in einem GridView mindestens 1 Eintrag vorhanden ist oder ob eine von zwei Checkboxen angew\u00e4hlt ist.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"ViewModel\"><\/span>ViewModel<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Die Eintr\u00e4ge des GridView werden im ViewModel als eine <em>ObservableCollection<\/em> repr\u00e4sentiert. Und die Checkboxes sind im ViewModel an zwei boolsche Werte (<em>CheckWeekMo<\/em> und <em>CheckWeekTue<\/em>) gebunden.<\/p>\n<pre><code><span style=\"color: #0000ff;\">public bool<\/span> CheckWeekMo\r\n{\r\n    <span style=\"color: #0000ff;\">get<\/span> =&gt; _checkWeekMo;\r\n    <span style=\"color: #0000ff;\">set<\/span> =&gt; <span style=\"color: #993366;\">Set<\/span>(() =&gt; CheckWeekMo, <span style=\"color: #0000ff;\">ref<\/span> _checkWeekMo, <span style=\"color: #0000ff;\">value<\/span>);\r\n}\r\n<span style=\"color: #0000ff;\">public bool<\/span> CheckWeekTue\r\n{\r\n    <span style=\"color: #0000ff;\">get<\/span> =&gt; _checkWeekTue;\r\n    <span style=\"color: #0000ff;\">set<\/span> =&gt; <span style=\"color: #993366;\">Set<\/span>(() =&gt; CheckWeekTue, <span style=\"color: #0000ff;\">ref<\/span> _checkWeekTue, <span style=\"color: #0000ff;\">value<\/span>);\r\n}\r\n\r\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #33cccc;\">ObservableCollection<\/span>&lt;<span style=\"color: #33cccc;\">MyObject<\/span>&gt; CalendarExceptionDates\r\n{\r\n    <span style=\"color: #0000ff;\">get<\/span> =&gt; _calendarExceptionDates;\r\n    <span style=\"color: #0000ff;\">set<\/span> =&gt; <span style=\"color: #993366;\">Set<\/span>(() =&gt; CalendarExceptionDates, <span style=\"color: #0000ff;\">ref<\/span> _calendarExceptionDates, <span style=\"color: #0000ff;\">value<\/span>);\r\n}<\/code><\/pre>\n<p><em>Zum Verst\u00e4ndnis<\/em>: Falls jemanden die Properties etwas ungew\u00f6hnlich erscheinen. Hier wurde die <em>GalaSoft.MvvMLight<\/em>-Bibliothek verwendet f\u00fcr eine Vereinfachung der <em>PropertyChanged<\/em>-Anweisung.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Multibinding_in_XAML-Datei\"><\/span>Multibinding in XAML-Datei<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Nun sollen diese Eigenschaften auch dar\u00fcber entscheiden, ob eine Textbox <em>enabled<\/em> oder <em>disabled<\/em> ist. Dazu nutzt man in der XAML-Datei das <strong>Multibinding<\/strong>. Das sieht dann wie folgt aus:<\/p>\n<pre><code><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">TextBox <\/span><span style=\"color: #ff0000;\">x<span style=\"color: #0000ff;\">:<\/span>Name<\/span><span style=\"color: #0000ff;\">=\"TextMyText\"<\/span> <span style=\"color: #ff0000;\">Text<\/span><span style=\"color: #0000ff;\">=\"{<\/span><span style=\"color: #800000;\">Binding<\/span> <span style=\"color: #ff0000;\">SomeText<\/span><span style=\"color: #0000ff;\">}\"<\/span>\r\n    <span style=\"color: #ff0000;\">MinWidth<\/span><span style=\"color: #0000ff;\">=\"180\"<\/span> <span style=\"color: #ff0000;\">HorizontalAlignment<\/span><span style=\"color: #0000ff;\">=\"Left\"<\/span> <span style=\"color: #ff0000;\">Margin<\/span><span style=\"color: #0000ff;\">=\"2,2,2,2\"<\/span> <span style=\"color: #ff0000;\">Height<\/span><span style=\"color: #0000ff;\">=\"Auto\"&gt;<\/span>\r\n    <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">TextBox.IsEnabled<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\r\n        <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">MultiBinding<\/span> <span style=\"color: #ff0000;\">Converter<\/span><span style=\"color: #0000ff;\">=\"{<\/span><span style=\"color: #800000;\">StaticResource<\/span> <span style=\"color: #ff0000;\">EnableConverter<\/span><span style=\"color: #0000ff;\">}\"&gt;<\/span>\r\n            <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">Binding<\/span> <span style=\"color: #ff0000;\">Path<\/span><span style=\"color: #0000ff;\">=\"CalendarExceptionDates.Count\"\/&gt;<\/span>\r\n            &lt;<span style=\"color: #800000;\">Binding<\/span> <span style=\"color: #ff0000;\">Path<\/span><span style=\"color: #0000ff;\">=\"CheckWeekMo\"\/&gt;<\/span>\r\n            &lt;<span style=\"color: #800000;\">Binding<\/span> <span style=\"color: #ff0000;\">Path<\/span><span style=\"color: #0000ff;\">=\"CheckWeekTue\"\/&gt;<\/span>\r\n        <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #800000;\">MultiBinding<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\r\n    <span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #800000;\">TextBox.IsEnabled<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\r\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #800000;\">TextBox<\/span><span style=\"color: #0000ff;\">&gt;\r\n<\/span><\/code><\/pre>\n<p>Von der <em>ObersavableCollection<\/em> \u00fcbergeben wir hier das Property <em>Count<\/em>, weil wir ja wissen m\u00f6chten, ob das GridView mindestens einen Eintrag enth\u00e4lt.<\/p>\n<p>Wie man sieht ben\u00f6tigt man in diesem Fall einen <strong>Converter<\/strong>, der aus einer gew\u00fcnschten Kombination dieser Eigenschaften true oder false zur\u00fcckgibt, um die Textbox zu <a href=\"https:\/\/ekiwi-blog.de\/22208\/netzwerkadapter-aktivieren-und-deaktivieren\/\">aktivieren oder eben zu deaktivieren<\/a>. Der Konverter muss auch noch in den Resourcen der <em>xaml<\/em>-Datei definiert werden.<\/p>\n<pre><code><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">Window.Resources<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\r\n    &lt;<span style=\"color: #993300;\">local<span style=\"color: #0000ff;\">:<\/span>EnableConverter<\/span> <span style=\"color: #ff0000;\">x<\/span><span style=\"color: #0000ff;\">:<\/span><span style=\"color: #ff0000;\">Key<\/span><span style=\"color: #0000ff;\">=\"EnableConverter\"\/&gt;<\/span>\r\n<span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #993300;\">\/Window.Resources<\/span><span style=\"color: #0000ff;\">&gt;\r\n<\/span><\/code><\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Converter-Klasse\"><\/span>Converter-Klasse<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Jetzt muss man nur noch die passende Converter-Class erstellen. In unserem Beispiel hei\u00dft die Klasse &#8222;<em>EnableConverter<\/em>&#8222;. Diese Klasse erbt Ihre Methoden von der Interface-Klasse <strong><em>IMultiValueConverter<\/em> <\/strong>bzw. muss deren Methoden-Definitionen implementieren.<\/p>\n<p>Die einzelnen Properties werden in der <em>Convert<\/em>-Methode als <strong><em>object[]<\/em>-Array<\/strong> \u00fcbergeben. Beim Zugriff auf das jeweilige Element im Array muss man diesen dann in den jeweiligen Datentyp konvertieren. Die Reihenfolge der Properties in dem Array entspricht genau der, wie sie im MultiBinding in der XAML-Datei definiert ist. Gibt es hier Abweichungen, so f\u00fchrt das zu einem Fehler in der Ausf\u00fchrung.<\/p>\n<pre><code><span style=\"color: #0000ff;\">public class<\/span> <span style=\"color: #008080;\">EnableConverter : IMultiValueConverter<\/span>\r\n{\r\n    <span style=\"color: #0000ff;\">public object<\/span> <span style=\"color: #993300;\">Convert<\/span>(<span style=\"color: #0000ff;\">object<\/span>[] values, <span style=\"color: #008080;\">Type<\/span> targetType, <span style=\"color: #0000ff;\">object<\/span> parameter, <span style=\"color: #008080;\">CultureInfo<\/span> culture)\r\n    {\r\n        <span style=\"color: #0000ff;\">int<\/span> i = (<span style=\"color: #0000ff;\">int<\/span>)values[0];\r\n        <span style=\"color: #0000ff;\">bool<\/span> mo = (<span style=\"color: #0000ff;\">bool<\/span>)values[1];\r\n        <span style=\"color: #0000ff;\">bool<\/span> tu = (<span style=\"color: #0000ff;\">bool<\/span>)values[2];\r\n        <span style=\"color: #800080;\">if<\/span> ((i &gt; 0) || mo || tu)\r\n        {\r\n            <span style=\"color: #800080;\">return <\/span><span style=\"color: #0000ff;\">true<\/span>;\r\n        }\r\n        <span style=\"color: #800080;\">else<\/span>\r\n        {\r\n                <span style=\"color: #800080;\">return <\/span><span style=\"color: #0000ff;\">false<\/span>;\r\n        }\r\n    }\r\n\r\n    <span style=\"color: #0000ff;\">public object<\/span>[] <span style=\"color: #993300;\">ConvertBack<\/span>(<span style=\"color: #0000ff;\">object<\/span> value, <span style=\"color: #008080;\">Type<\/span>[] targetTypes, <span style=\"color: #0000ff;\">object<\/span> parameter, <span style=\"color: #008080;\">CultureInfo<\/span> culture)\r\n    {\r\n        <span style=\"color: #800080;\">return <\/span>(<span style=\"color: #0000ff;\">object<\/span>[])value;\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>Die ConvertBack-Methode ist in diesem Fall nicht entscheidend bzw. wird nicht ben\u00f6tigt, weil das Binding nur in eine Richtung geht (OneWay).<\/p>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>Wer unter Visual Studio mit C# programmiert und WPF-Projekte bearbeitet, kommt ums Binding innerhalb der XAML-Dateien nicht drumherum. Binding ist<\/p>\n","protected":false},"author":2,"featured_media":1011,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[13],"tags":[809,190,292,136,80,191,808,682],"class_list":["post-2969","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programmierung","tag-binding","tag-c","tag-code","tag-programmieren","tag-programmierung","tag-visual-studio","tag-wpf","tag-xaml"],"_links":{"self":[{"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/posts\/2969","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/comments?post=2969"}],"version-history":[{"count":0,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/posts\/2969\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/media\/1011"}],"wp:attachment":[{"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/media?parent=2969"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/categories?post=2969"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/tags?post=2969"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}