36

For those doing pure MVVM, how do you handle a ComboBox SelectionChanged event without reverting to code behind?

I tried e.g. AttachedBehaviors but Event="SelectedChanged" is not supported:

<ComboBox>
    <ComboBoxItem Content="Test1">
        <c:CommandBehaviorCollection.Behaviors>
            <c:BehaviorBinding Event="SelectionChanged" 
                               Command="{Binding SelectedChanged}"
                               CommandParameter="MainBorder123"/>
        </c:CommandBehaviorCollection.Behaviors>
    </ComboBoxItem>
    <ComboBoxItem Content="Test2"/>
    <ComboBoxItem Content="Test3"/>
</ComboBox>
Edward Tanguay
  • 189,012
  • 314
  • 712
  • 1,047

3 Answers3

85

This post is quite old, but since I got the same issue. Here is how I solved it (using framework 4.0) : the idea is to use System.Windows.Interactivity.

In the XAML :

<ComboBox ItemsSource="{Binding Items}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ComboBox>

Then you just need to implement the SelectionChangedCommand in your viewmodel.

markmnl
  • 11,116
  • 8
  • 73
  • 109
fabien
  • 2,041
  • 1
  • 16
  • 19
  • Also there is `CallMethodAction` if you don't need a `Command` though it does require adding ref to `Microsoft.Expression.Interactions.dll` – markmnl Mar 19 '14 at 07:18
  • 3
    and how would you bind the `SelectedItem` or `SelectedValue` of the `ComboBox` here without giving it a name? – Maslow Jan 20 '17 at 20:25
  • 1
    @Maslow or anybody else looking to pass the selected item as a parameter: use binding, see [here](https://stackoverflow.com/a/34668511/63209). In my case, I named the `ComboBox`, e.g., "MyCombo", and then the binding was a simple `{Binding ElementName=MyCombo, Path=SelectedItem}`. – Paul Oct 10 '17 at 17:50
  • 5
    After adding a reference to ``System.Windows.Interactivity`` you need to add this namespace to the XAML header: ``xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"``. – Beauty Jul 10 '18 at 10:16
  • 4
    for .net core, you will need this nuget: `https://github.com/Microsoft/XamlBehaviorsWpf`. Add the following into your window layout xml to the `` -> `xmlns:i="http://schemas.microsoft.com/xaml/behaviors"` More on this: [here](https://devblogs.microsoft.com/dotnet/open-sourcing-xaml-behaviors-for-wpf/) – S0und Jan 23 '20 at 11:23
26

I'm not sure if what you're after is possible, but the way I do it is to simply bind the SelectedItem to a property on view model. Then within the property setter, I call any custom code that I want to happen i.e. setting other properties based on rule. If I need the selected item to be bound to an object aswell (for other bound controls to update) I set this in the setter too and send out a notification.

HAdes
  • 16,713
  • 22
  • 58
  • 74
  • I think this way makes the most sense, and it's working well for me so far. Thanks for posting this. – Aphex Jul 14 '11 at 21:15
  • 9
    I find this to be an incredibly painful way to do it. For simple applications, doing this instead of a command is easy. But it quickly becomes unwieldy. Properties should hold data, not perform actions. It breaks async, and makes it more difficult to debug as Visual Studio will step over property setters/ getters by default. – Richard June Oct 19 '16 at 19:54
3

You would use a data trigger to trigger an event on a different UI element such as "enable / disable, or visible /invisible"

If you want the selected element to show the object data in other UI elements then you would use data binding and set the datacontext of the UI data display elements to be bound to the currently selected item in the combo box.

Peter
  • 1,776
  • 13
  • 20
  • ok, I could do that if all I want to do is change the XAML, but what if I want to e.g. use a comboxbox to execute code that does something that XAML cannot do, e.g. load a new resource file and attach it to the current window? or e.g. change some data in the database, etc. – Edward Tanguay Jun 04 '09 at 13:58
  • Then you could use a binding your View Model to the combo box SelectionChanged. I'm not sure where you would look for an example but Karl Shifflet and Josh Smith are the two main blogs I go to for MVVM help the links to their blogs are below. http://karlshifflett.wordpress.com/2009/06/03/troubleshooting-silverlight-3-broken-bindings/ http://joshsmithonwpf.wordpress.com/2009/05/20/device-specific-interaction-logic-in-an-mvvm-application/ Sorry I can't help more on the specifics, i'm fairly new to WPF and MVVM myself. – Peter Jun 05 '09 at 15:58
  • oops forgot to mention Karl Shifflet has been doing a lot of WPF Line OF Business events, look on his blog for them, they contain some excellent powerpoint examples and code samples also. – Peter Jun 05 '09 at 16:01