Mvvm-Light Silverlight, используя EventToCommand с Combobox

Я подключил ComboBox SelectedItemChangeEvent к ICommand в моей модели просмотра. Кажется, что все работает нормально, но я не знаю, как получить SelectedItem из ComboxBox. Я думаю, мне нужно использовать CommandParameter EventToCommand - я привязываю это к чему-то в моей модели ViewModel, у которой есть выбранный элемент ComboBox? Я пробовал это:

<ComboBox 
  Width="422"
  Height="24"
  DisplayMemberPath="Name"
  ItemsSource="{Binding CategoryTypes}"
  SelectedItem="{Binding SelectedCategory}"
  >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <MvvmLight:EventToCommand 
              Command="{Binding SelectCategoryCommand,Mode=TwoWay}"
              CommandParameter="{Binding SelectedCategory, Mode=TwoWay}"
              MustToggleIsEnabledValue="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ComboBox>

и, на мой взгляд, модель:

public ICommand SelectCategoryCommand
{
    get
    {
        return new SelectCategoryCommand(this);
    }
}

public CategoryType SelectedCategory
{
    get; set;
}

и ICommand

public class SelectCategoryCommand : ICommand
{
    private RowViewModel _rowViewModel;

    public SelectCategoryCommand(RowViewModel rowViewModel)
    {
        _rowViewModel = rowViewModel;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        CategoryType categoryType = (CategoryType) parameter;
    }

}

Однако параметр в методе Execute для ICommand всегда равен нулю. Я довольно неопытен с SilverLight, поэтому я думаю, что мне действительно не хватает чего-то очевидного здесь. Может ли кто-нибудь помочь? Спасибо заранее!

Ответы

Ответ 1

После некоторого копания я обнаружил, что очень просто передать фактический SelectionChangedEventArgs как параметр ICommand execute:

Просто установите PassEventArgsToCommand="True"

<ComboBox Width="422"
          Height="24"
          DisplayMemberPath="Name"
          ItemsSource="{Binding CategoryTypes}"
          SelectedItem="{Binding SelectedCategory}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <MvvmLight:EventToCommand Command="{Binding SelectCategoryCommand,Mode=TwoWay}"
                                      MustToggleIsEnabledValue="True" 
                                      PassEventArgsToCommand="True"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ComboBox>

И затем в методе Execute сделайте что-то вроде:

public void Execute(object parameter)
{
    SelectionChangedEventArgs e = (SelectionChangedEventArgs)parameter;
    CategoryType categoryType = (CategoryType)e.AddedItems[0];
}

Ответ 2

Вы можете попробовать добавить CommandParameter и передать список в свой relayCommand

Что-то подобное описано в нижней части этой страницы, но с помощью datagrid:   http://mvvmlight.codeplex.com/ Код с этой страницы выглядит следующим образом:

<sdk:DataGrid x:Name="MyDataGrid" ItemsSource="{Binding Items}">
   <i:Interaction.Triggers> 
   <i:EventTrigger EventName="SelectionChanged">  
   <cmd:EventToCommand  Command="{Binding SelectionChangedCommand}"
                        CommandParameter="{Binding SelectedItems, ElementName=MyDataGrid}" />
   </i:EventTrigger>
   </i:Interaction.Triggers>
</sdk:DataGrid>

Если вы это сделаете, ваш relayCommand должен будет иметь дело с параметрами, входящими в систему. Что-то вроде этого в вашей модели ViewModel:

public RelayCommand<IList> SelectionChangedCommand{    get;    private set;}

...

SelectionChangedCommand = new RelayCommand<IList>(
    items =>
    {
        if (items == null)
        {
            NumberOfItemsSelected = 0;
            return;
        }
        //Do something here with the records selected that were passed as parameters in the list
        //example:  NumberOfItemsSelected = items.Count;
    });