myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: WPF und XAML » Wie mit MVVM auf ComboBox SelectionChanged-Event reagieren?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Wie mit MVVM auf ComboBox SelectionChanged-Event reagieren?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
GeneVorph GeneVorph ist männlich
myCSharp.de-Mitglied

Dabei seit: 09.02.2015
Beiträge: 118
Entwicklungsumgebung: Visual Studio 2013


GeneVorph ist offline

Wie mit MVVM auf ComboBox SelectionChanged-Event reagieren?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

ich glaube, es ist nur ein kleiner Denkfehler, der mich gerade vom Weiterkommen abhält, aber ich bekommes es alleine nicht hin.

Einer ObservableCollection vom Typ int soll immer das in einer ComboBox ausgewählte Element hinzugefügt werden.

Das Problem: die ComboBox befindet sich auf einem UserControl, das dynamisch hinzugefügt wird. Ich müsste also, nach allem was ich zu wissen glaube, im ViewModel des UserControls auf den SelectionChange reagieren. Da ich gerade versuche MVVM zu lernen, soll der CodeBehind unangetastet bleiben.

Die einzige Methode, die ich mir nun vorstellen kann, ist im XAML-Code auf das "SelectionChanged"-Event zu reagieren, mit Hilfe eines Event-Triggers. Sieht bei mir so aus:

XML-Code:
<UserControl x:Class="UserControlTest.PathControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"            <!-- stimmt das hier?--
>

             xmlns:local="clr-namespace:UserControlTest"
             mc:Ignorable="d"
             d:DesignHeight="60" d:DesignWidth="800">


    <StackPanel Orientation="Horizontal">

        <ComboBox x:Name="combo" Margin="10" MinWidth="60" VerticalAlignment="Center" ItemsSource="{Binding AvailableNumbers}" SelectedIndex="{Binding TheIndex}" SelectedItem="{Binding TheValue, Mode=TwoWay}">
            <d:Interaction.Triggers EventName="SelectionChanged">
                <d:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="SelectedItem" />
            </d:Interaction.Triggers>
        </ComboBox>

        <TextBox Margin="10" MinWidth="120" Text="{Binding TheText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    </StackPanel>
</UserControl>

Das Command (SelectionChangedCommand) stelle ich im ViewModel des UserControls bereit. Wenn ich ein Item aus der ComboBox auswähle, kann ich im Debugger jedoch sehen, das dieses Command nie ausgeführt wird.
Ich vermute derzeit zwei Fehler: die Deklaration des Namespace für Interactions (s. Kommentar im XAML-Code), bzw. ein fehlender Schritt in der UserControl ViewModel-Klasse?

viele Grüße
Vorph
19.01.2020 19:13 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Papst Papst ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.09.2014
Beiträge: 268
Entwicklungsumgebung: VS2017
Herkunft: Kassel


Papst ist online

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Der Namespace "d" ist meines Wissens immer vordefiniert, den solltest du nicht ändern. Generell hat dieser Einfluss auf den Designer (im Originalzustand).

Du suchst diesen hier:
 http://schemas.microsoft.com/expression/2010/interactivity

An sich sollte der Designer dir bereits sagen, dass im Namespace d kein Interaction enthalten ist.

Gefunden durch Google:  https://stackoverflow.com/questions/1048...ands-via-events

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Papst am 19.01.2020 22:13.

19.01.2020 22:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
GeneVorph GeneVorph ist männlich
myCSharp.de-Mitglied

Dabei seit: 09.02.2015
Beiträge: 118
Entwicklungsumgebung: Visual Studio 2013

Themenstarter Thema begonnen von GeneVorph

GeneVorph ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Papst,

vielen Dank erstmal. Der von dir verlinkte Post auf StackOverflow war mein Ausgangspunkt; zwar motzt der Compiler nicht, wenn ich d: schreibe, aber du hast natürlich Recht.

Ich habe außerdem herausgefunden, dass man sich die Library für Interativity über NuGet-Konsole holen kann. Jedoch - ich bin derzeit etwas ratlos WAS ich genau in die Anweisung für die Event.Trigger schreiben muss

XML-Code:
<i:Interaction.Triggers>
    <i:EventTrigger>
        <!-- ??? -->
    </i:EventTrigger>
</i:Interaction.Triggers>

[Im code, den ich zuvor gepostet habe, wird noch eine Klasse InvokeCommandAction aufgerufen - die aber bei mir gar nicht existiert geschockt kann also auch nicht funktionieren.] --> EDIT: Blödsinn gelabert - bitte ignorieren!

Wie gesagt, Fehlermeldungen bekomme ich keine und das Ganze wird auch kompiliert.

Ich bin derzeit leider nicht an einem PC mit meinem Projekt; muss also leider bis morgen warten. Frage mich aber, wass ich nun anstelle der Fragezeichen ansprechen soll? Setter?

Gruß
Vorph

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von GeneVorph am 19.01.2020 22:47.

19.01.2020 22:44 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
KroaX KroaX ist männlich
myCSharp.de-Mitglied

avatar-4080.jpg


Dabei seit: 31.08.2009
Beiträge: 293
Herkunft: Köln


KroaX ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das magische Suchwort für dich lautet wohl EventToCommand. Unter diesem Begriff versteckt sich am häufigsten was du tun möchtest. Jedes gängige MVVM Framework hat dazu eine fertige Implementierung mitsamt der Einbindung der notwendigen Abhängigkeiten.

 https://stackoverflow.com/questions/5868...-way-or-snippet

Das hier ist ein Beispiel mit MVVM Light. Eventuell ziehst du ja in Betracht ein bestehendes MVVM Framework zu nutzen anstatt selbst eines zu schreiben.
19.01.2020 23:42 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.383
Herkunft: Leipzig


MrSparkle ist online

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wenn der Benutzer einen Wert in der ComboBox auswählt, wird durch das Binding die Eigenschaft TheValue im ViewModel geändert. Wenn du dort im Setter auf die Änderung reagierst, brauchst du kein Event, kein Command und kein Package.
20.01.2020 10:32 Beiträge des Benutzers | zu Buddylist hinzufügen
GeneVorph GeneVorph ist männlich
myCSharp.de-Mitglied

Dabei seit: 09.02.2015
Beiträge: 118
Entwicklungsumgebung: Visual Studio 2013

Themenstarter Thema begonnen von GeneVorph

GeneVorph ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

vielen Dank für die Infos - ich hab's hinbekommen! Hier der Code, wie er hätte sein müssen, damit es funktioniert:

In der View des UserControls

XML-Code:
<UserControl x:Class="UserControlTest.PathControl"
             <!-- ...--
>

             <!--diesen Namespace einfügen-->
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             <!-- ...-->

    <StackPanel Orientation="Horizontal">
        <ComboBox x:Name="combo" Margin="10" MinWidth="60" VerticalAlignment="Center" ItemsSource="{Binding AvailableNumbers}" SelectedIndex="{Binding TheIndex}" SelectedItem="{Binding TheValue, Mode=TwoWay}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ComboBox>
        <TextBox Margin="10" MinWidth="120" Text="{Binding TheText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    </StackPanel>

    <!-- -->
</UserControl>

Im ViewModel des UserControls wird dann einfach das SelectionChangedCommand angemeldet - fertig. Danke für das Zauberwort, KroaX - tatsächlich fehlt mir manchmal das Vokabular verwundert

Aber:

Zitat:
Wenn der Benutzer einen Wert in der ComboBox auswählt, wird durch das Binding die Eigenschaft TheValue im ViewModel geändert. Wenn du dort im Setter auf die Änderung reagierst, brauchst du kein Event, kein Command und kein Package.

Ich frage mich ja, warum ich da nicht gleich draufgekommen bin! Ich überlege, ob das nicht sogar sauberer ist; denn tatsächlich brauche ich ja nur den geänderten Wert! Die View selbst interssiert sich in meinem Fall gar nicht mehr dafür, was mit dem Wert passiert; so vom Gefühl her würde ich sagen, dass man vlt. auf das SelectionChanged-Event nur dann mit einem EventToCommand reagieren sollte, wenn dadurch eine Relevanz für die View gegeben ist (veränderte Darstellungsoptionen, etc). Da ich hier aber aus dem Bauch raus argumentiere, kann und will ich dafür nicht die Hand ins Feuer legen. Es würde mich aber schon interessieren, wie sich das verhält, oder ob es schlicht Wurscht ist.

Nochmals Danke, macht's gut,
Vorph
20.01.2020 16:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
KroaX KroaX ist männlich
myCSharp.de-Mitglied

avatar-4080.jpg


Dabei seit: 31.08.2009
Beiträge: 293
Herkunft: Köln


KroaX ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Ich frage mich ja, warum ich da nicht gleich draufgekommen bin! Ich überlege, ob das nicht sogar sauberer ist; denn tatsächlich brauche ich ja nur den geänderten Wert! Die View selbst interssiert sich in meinem Fall gar nicht mehr dafür, was mit dem Wert passiert; so vom Gefühl her würde ich sagen, dass man vlt. auf das SelectionChanged-Event nur dann mit einem EventToCommand reagieren sollte, wenn dadurch eine Relevanz für die View gegeben ist (veränderte Darstellungsoptionen, etc). Da ich hier aber aus dem Bauch raus argumentiere, kann und will ich dafür nicht die Hand ins Feuer legen. Es würde mich aber schon interessieren, wie sich das verhält, oder ob es schlicht Wurscht ist.

Nochmals Danke, macht's gut,
Vorph

Am saubersten ist das was am ehesten deinem Usecase entspricht. Wenn du eine Aktion nur auslösen möchtest wenn der Benutzer über die UI eine Änderung an der Combobox vollzieht wäre es möglicherweise sauberer es über ein EventToCommand zu lösen.

Bedenke nämlich: Eine Änderung am Property innerhalb deines ViewModels würde dieselbe Bedeutung haben wie die Benutzerinteraktion aus der UI. Und manchmal möchte man dazwischen unterscheiden können.
20.01.2020 16:17 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 4 Monate.
Der letzte Beitrag ist älter als 4 Monate.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 04.06.2020 18:33