Monday, January 9, 2012

Execute Command on ComboBox Selection changed

If you are developing WPF application MVVM way you might have noticed that Button Provide a Command property that can be set to a ICommand instance and the command will be executed when button is clicked. There is no inbuilt way to set a Command that can be executed when ComboBox selection is changed. I have coded a behaviour that can be used to achieve this. Below is the code for the behaviour.

using System.Windows.Input;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
public class SelectionChangedBehaviour
{
 
public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand),
  typeof(SelectionChangedBehaviour), new PropertyMetadata(PropertyChangedCallback));

  public static void PropertyChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
  {
   
Selector selector = (Selector)depObj;
    if (selector != null)
    {
      selector.SelectionChanged +=
new SelectionChangedEventHandler(SelectionChanged);
    }
  }


 
public static ICommand GetCommand(UIElement element)
  {
   
return (ICommand)element.GetValue(CommandProperty);
  }

 
public static void SetCommand(UIElement element, ICommand command)
  {
    element.SetValue(CommandProperty, command);
  }

  private static void SelectionChanged(object sender, SelectionChangedEventArgs e)
  {
   
Selector selector = (Selector)sender;
    if (selector != null)
    {
     
ICommand command = selector.GetValue(CommandProperty) as ICommand;
      if (command != null)
      {
        command.Execute(selector.SelectedItem);
      }
    }
  }
}


Set the command in xaml as shown below:

<ComboBox SelectionChangedBehaviour.Command="{Binding CommandImpl}">ComboBox>

This can be used for ListBox and ListView as well.

18 comments:

  1. Naveen,

    your code helped me a lot. I was looking for exactly this, to bind a selection changed event on a combobox to a custom command I wrote on a RichTextBox.

    Thanks.

    ReplyDelete
  2. Thank you! it helped

    ReplyDelete
  3. I am getting CommandConverter cannot convert from System.String Error in the XAML . Any ideas?






    ICommand _modeSelectChanged;
    public ICommand ModeSelectChanged
    {
    get
    {
    if (_modeSelectChanged == null)
    {
    _modeSelectChanged = new DelegateCommand(
    this.OnModeSelectChangedCommandExecute,
    this.OnModeSelectChangedCommandCanExecute);
    }

    return _modeSelectChanged;
    }
    }

    private bool OnModeSelectChangedCommandCanExecute(object obj)
    {

    return true;
    }

    private void OnModeSelectChangedCommandExecute(object obj)
    {

    }

    ReplyDelete
  4. Above post would not show my XAML, here is the text, don't think this blogger likes the less than symbols so have removed in this post

    ComboBox Name="ResampleCombo" Grid.Column="4" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=ResampleMode}" Behave:SelectionChangedBehaviour.Command="ModeSelectChanged">

    ReplyDelete
  5. Ok I sorted it . I needed

    Behave:SelectionChangedBehaviour.Command="{Binding ModeSelectChanged}"

    ReplyDelete
  6. Sorry, I missed the {Binding } construct in xaml. I have updated the post now. Thanks for sharing it.

    ReplyDelete
  7. Does anybody have an idea why:

    new PropertyMetadata(PropertyChangedCallback)

    doesn't work in VB.NET?

    ReplyDelete
  8. Hi,
    I did the same for ComboBoxItem, but it not works when itemssource binding. Because the base type for command is ComboBoxItem but my items are simple models. Any idea?

    ReplyDelete
  9. Can you please explain how to use this? Where do you place this class? If I just type the provided XAML code it will not recognize the SelectionChangedBehaviour.

    ReplyDelete
  10. Naveen,

    Can you PLEASE put a correct XAML example in this post. The XAML you have above is NOT in correct syntax.

    Thank you.

    ReplyDelete
  11. Awesome, this is an approved set of code this works very well in combination with my custom command handler; granted there are a few things that have to be coded correctly in order for things to fully comply yet if you know what you're doing it should be a breeze, great work Naveen!!!

    ReplyDelete
  12. I get "Behave" is not supported by WPF .. any idea ?

    ReplyDelete
  13. Thanks a lot, it helped a lot.

    ReplyDelete
  14. Tis is a long shot as this is an old blog.... but could you perhaps explain how the SelectionChangedBehaviour class can be associated with a a specific ComboBox in CODE BEHIND? I have created a UserControl with 3 comboboxes in it and I want each of them to be bound to the SelectionChangedBehaviour.Command call-back

    ReplyDelete

Type based templating

            <DataTemplate DataType="{x:Type vm:SampleViewModel}">                 <DataTemplate.Resources>       ...