-2

I'm building a program with MVVM pattern I can handle selectionchanged event with method in xaml.cs file in non-MVVM way. but don't know how to do this in MVVM.

Currently all my ICommand properties are in viewmodel.cs file, and view code like below

<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10,0" HorizontalAlignment="Right">
    <Label Content="Ports" Margin="2" />
    <ComboBox IsReadOnly="True" AllowDrop="True" x:Name="ComboBox_SerialPort" MinWidth="60" Margin="5" 
            ItemsSource="{Binding SerialPortList}" SelectedValue="{Binding SelectedSerialPort}"
            SelectionChanged="{Binding Cmd_ComboBox_SerialDropDownSelectionChanged}" >
    </ComboBox>
</StackPanel>

Apparently directly binding ICommand property to SelectionChanged is not working. but there's no Command property in Combobox control. So how do I attach ICommand to control events

Thanks

X.Z
  • 1,018
  • 2
  • 11
  • 16
  • Does this answer your question? [WPF Binding UI events to commands in ViewModel](https://stackoverflow.com/questions/4897775/wpf-binding-ui-events-to-commands-in-viewmodel) – Rekshino Apr 04 '23 at 09:53
  • When the selection of the combobox changed you also have a change of the ViewModel property `SelectedSerialPort`. I would react to that change inside the ViewModel. – Sir Rufo Apr 04 '23 at 13:15
  • Code-behind is not relevant in terms of MVVM. MVVM is a design pattern and code-behind is a compiler feature. By definition, a design pattern *must* be compiler and language agnostic. MVVM is a architectural design pattern that doesn't care about class level design problems. Therefore it's absolutely fine to have code-behind event handlers. Avoiding them only adds unnecessary complexity to your code. There are scenarios where you can't avoid code-behind. In MVVM the relationship between classes and their responsibilities are important (on application level). – BionicCode Apr 04 '23 at 19:44
  • In other words, the only way to violate MVVM is to violate the mandatory dependency graph (*View ---> View Model ---> Model*) or class responsibilities in regards to the MVVM application component model (e.g. wrong responsibility is part of the wrong component, for example handling dialogs is part of the View Model or Model). – BionicCode Apr 04 '23 at 19:54
  • As an alternative to listening to the `SelectionChanged` event you can bind the `ComboBox.SelectedItem` or `ComboBox.SelectedValue` property and handle changes in the property setter. The disadvantages are: a) you can't execute long-running operations as property setter must return as fast as possible b) you can't execute async operations. c) you don't have access to the event args and the sender instance (although if you need those references in your view model, something crucial is wrong with your design). – BionicCode Apr 04 '23 at 19:54
  • @Rekshino I don't think there's a command property in native ComboBox control – X.Z Apr 06 '23 at 08:53
  • @BionicCode I was hoping to trigger a refresh-deivice-list action on dropboxopened event. – X.Z Apr 06 '23 at 11:27
  • Same as handling SelectionChangrd: either bind ComboBox.IsDropDownOpen to your view model or handle the event in code-behind and trigger the view model action from there. Because the drop down is a pure view related element it shouldn't be relevant to the view model whether it is open or closed. Therefore binding to the ComboBox.IsDropDownOpen property is not my recommendation. You should handle the event in code-behind instead. – BionicCode Apr 06 '23 at 11:42

2 Answers2

1

You could handle your selection changed logic in the setter of the SelectedSerialPort source property which will get set when you select a value in the ComboBox.

mm8
  • 163,881
  • 10
  • 57
  • 88
0

Option 1:

<ComboBox>
  <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
          <i:InvokeCommandAction Command="{Binding YourCommandName}"/>
     </i:EventTrigger>
  </i:Interaction.Triggers>
</Combobox>

Option 2:

<ComboBox SelectedValue="{Binding SelectedSerialPort, UpdateSourceTrigger=PropertyChanged}"/> 
MaxB
  • 260
  • 2
  • 13
  • 1
    Why are you voting down? This solution works perfectly fine for calling a method when the selected value has changed. – MaxB Apr 05 '23 at 08:48