title: WPF - MVVM: ComboBox value after SelectionChanged
body: <p>I am new to C# and MVVM, and I've spent all day trying to get the value of a <code>ComboBox</code> to my ViewModel on <code>SelectionChanged</code>. I have managed to figure it out using either <code>CallMethodAction</code> or <code>InvokeCommandAction</code> with the resources:</p>
  
  <ul>
  <li><code>System.Windows.Interactivity.dll</code></li>
  <li><code>Microsoft.Expression.Interactions.dll</code></li>
  </ul>
  
  <p>My problem is that both these methods return the value of the <code>ComboBox</code> before it has changed. Could anyone explain how to get the value <em>after</em> the change?</p>
  
  <p>I have spent hours searching through SO and Google for a solution, so I wonder if others are too. Any advice will be appreciated!</p>
  
  <p>My code is below:</p>
  
  <p><strong>MainWindow.xaml</strong></p>
  
  <pre><code>&lt;Window x:Class="SelectionChange.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
          xmlns:si="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
          xmlns:vm="clr-namespace:SelectionChange"
          Title="MainWindow" Width="300" Height="300"&gt;
      &lt;Window.DataContext&gt;
          &lt;vm:ViewModel /&gt;
      &lt;/Window.DataContext&gt;
      &lt;Grid&gt;
          &lt;ComboBox Name="SelectBox" VerticalAlignment="Top" SelectedIndex="0"&gt;
              &lt;i:Interaction.Triggers&gt;
                  &lt;i:EventTrigger EventName="SelectionChanged"&gt;
                      &lt;si:CallMethodAction MethodName="SelectionChanged" TargetObject="{Binding}" /&gt;
                      &lt;!--&lt;i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=SelectBox, Path=Text}" /&gt;--&gt;
                  &lt;/i:EventTrigger&gt;
              &lt;/i:Interaction.Triggers&gt;
              &lt;ComboBoxItem Content="Item 1" /&gt;
              &lt;ComboBoxItem Content="Item 2" /&gt;
              &lt;ComboBoxItem Content="Item 3" /&gt;
          &lt;/ComboBox&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p><strong>ViewModel.cs</strong></p>
  
  <pre><code>namespace SelectionChange
  {
      using System;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Input;
  
      public class ViewModel
      {
          public ViewModel()
          {
              SelectionChangedCommand = new SelectionChangedCommand();
          }
  
          public ICommand SelectionChangedCommand
          {
              get;
              set;
          }
  
          public void SelectionChanged(object sender, EventArgs e)
          {
              ComboBox SelectBox = (ComboBox)sender;
              MessageBox.Show("Called SelectionChanged: " + SelectBox.Text);
          }
      }
  }
  </code></pre>
  
  <p><strong>SelectionChangedCommand.cs</strong></p>
  
  <pre><code>namespace SelectionChange
  {
      using System;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Input;
  
      public class SelectionChangedCommand : ICommand
      {
          public SelectionChangedCommand()
          {
          }
  
          public event EventHandler CanExecuteChanged;
  
          public bool CanExecute(object parameter)
          {
              return true;
          }
  
          public void Execute(object parameter)
          {
              MessageBox.Show("Executed SelectionChangedCommand: " + parameter);
          }
      }
  }
  </code></pre>
  
  <p><br><br><br>
  <strong>Edit: My Solution</strong></p>
  
  <p>It turns out I didn't understand <code>Binding</code> well enough and instead was trying to implement something simple in a rather complicated way! Instead of using dependencies, I have now achieved what I needed using regular bindings. As an example, I've bound a <code>TextBox</code> to the <code>SelectedIndex</code> of the <code>ComboBox</code>, which gets updated using <code>INotifyPropertyChanged</code>.</p>
  
  <p><img src="https://i.stack.imgur.com/n3fG5.jpg" alt="MainWindow.xaml Screenshot"> </p>
  
  <p><strong>MainWindow.xaml</strong></p>
  
  <pre><code>&lt;Window x:Class="SelectionChange.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:vm="clr-namespace:SelectionChange"
          Title="MainWindow" Width="300" Height="300"&gt;
      &lt;Window.DataContext&gt;
          &lt;vm:ViewModel /&gt;
      &lt;/Window.DataContext&gt;
      &lt;Grid&gt;
          &lt;Grid.ColumnDefinitions&gt;
              &lt;ColumnDefinition Width="Auto" /&gt;
              &lt;ColumnDefinition Width="*" /&gt;
          &lt;/Grid.ColumnDefinitions&gt;
  
          &lt;ComboBox SelectedItem="{Binding SelectedItem}" SelectedIndex="0" Grid.Column="0" VerticalAlignment="Top"&gt;
              &lt;ComboBoxItem Content="Item 1" /&gt;
              &lt;ComboBoxItem Content="Item 2" /&gt;
              &lt;ComboBoxItem Content="Item 3" /&gt;
          &lt;/ComboBox&gt;
  
          &lt;!-- TextBox to display the ComboBox's SelectedIndex --&gt;
          &lt;TextBox Text="{Binding SelectedIndex}" Grid.Column="1" VerticalAlignment="Top" /&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p><strong>ViewModel.cs</strong></p>
  
  <pre><code>namespace SelectionChange
  {
      using System;
      using System.ComponentModel;
      using System.Windows.Controls;
  
      public class ViewModel : INotifyPropertyChanged
      {
          public ViewModel()
          {   
          }
  
          // Property to store / retrieve ComboBox's SelectedIndex
          private int _SelectedIndex;
          public int SelectedIndex { get; set; }
  
          // Property to bind to ComboBox's SelectedItem
          private ComboBoxItem _SelectedItem;
          public ComboBoxItem SelectedItem
          {
              get { return _SelectedItem; }
              set
              {
                  _SelectedItem = value;
  
                  // SelectedItem's Content
                  string Content = (string)value.Content;
  
                  // SelectedItem's parent (i.e. the ComboBox)
                  ComboBox SelectBox = (ComboBox)value.Parent;
  
                  // ComboBox's SelectedIndex
                  int Index = SelectBox.SelectedIndex;
  
                  // Store the SelectedIndex in the property
                  SelectedIndex = Index;
  
                  // Raise PropertyChanged with the name of the stored property
                  RaisePropertyChanged("SelectedIndex");
              }
          }
  
          // INotifyPropertyChanged
          public event PropertyChangedEventHandler PropertyChanged;
          private void RaisePropertyChanged(string PropertyName)
          {
              if (PropertyChanged != null)
                  PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
          }
      }
  }
  </code></pre>