2013-03-07 3 views
3

В среде MVVM/WPF я хочу вызвать команду (ComputeCommand) в ViewModel, когда событие ListView поднято. Как это можно сделать, либо в XAML, либо в C#?Как я могу вызвать команду в ViewModel в SelectionChanged из ListView?

Вот мой класс команд. Я пробовал MainViewModel.Instance.MyCommand.Execute(); в коде, но он этого не принимает.

public class ComputeCommand : ICommand 
{ 
    public ComputeCommand(Action updateReport) 
    { 
     _executeMethod = updateReport; 
    } 

    Action _executeMethod; 

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

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     _executeMethod.Invoke(); 
    } 
}  

ответ

2

Я действительно рекомендую использовать рамки MVVM как MVVM Light, так что вы можете сделать что-то вроде этого:

XAML:

xmlns:MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras" 
xmlns:Custom="clr-namespace:System.Windows.Interactivity; assembly=System.Windows.Interactivity" 

<ListBox> 
... 
    <Custom:Interaction.Triggers> 
      <Custom:EventTrigger EventName="SelectionChanged "> 
      <MvvmLight_Command:EventToCommand PassEventArgsToCommand="False" Command="{Binding Path=ComputeCommand}"/> 
      </Custom:EventTrigger> 
    </Custom:Interaction.Triggers> 

</Listbox> 

ViewModel:

public RelayCommand ComputeCommand{ get; private set; } 

Это IMO элегантный способ сохранить ваши события проводки в чистоте и порядке.

0

Сначала вы должны определить привязку для Command, поэтому функция, которая должна быть выполнена на invokation команды.

Это может быть сделано в XAML, как:

<CommandBinding Command="name_of_the_namespace:ComputeCommand" Executed="ComputeCommandHandler" /> 

После, вы можете, например, в каком-то классе инициализации команды, как:

public class AppCommands { 
    public static readonly ICommand ComputeCommand = 
      new RoutedCommand("ComputeCommand", typeof(AppCommands)); 
} 

и после того, как можно использовать например:

AppCommands.ComputeCommand.Execute(sender); 

Когда вы имеете дело с WPF, s o MVVM шаблону, вам нужно написать гораздо больше обычного кода, но воспользоваться его гибкостью.

+0

И где добавить ?? где-нибудь или внутри ? – gsmida

+0

Tigran

2

Чтобы ответить на ваш вопрос - вам не хватает параметра. Этот вызов должен работать:

MainViewModel.Instance.MyCommand.Execute(null); 

Однако, вам не нужен ICommand для того, этот интерфейс служит иной цели.

Что вам нужно либо обрабатывать SelectionChanged на вид сбоку

var vm = DataContext as YourViewModelType; 
if (vm != null) 
{ 
    vm.Compute(); //some public method, declared in your viewmodel 
} 

или обрабатывать его на ViewModel стороне от привязки к IsSelected свойству контейнера элемента

+0

Я пробовал решения, но никто не работал:/Я использую MVVM, потому что у меня есть данные для обновления на экране в момент выполнения – gsmida

+0

Что вы подразумеваете под «none work» ? Они не смогли скомпилировать? Не удалось выполнить? С исключением? Или что? –

+0

XamlParseException on SelectionChanged = "{Binding MyCommand}" – gsmida

1

В целом: для вызова команды, когда событие управления поднято, вы можете использовать EventTriggers.

<ListView> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="SelectionChanged" > 
      <i:InvokeCommandAction Command="{Binding CommandToBindTo}" CommandParameter="{Binding CommandParameterToBindTo}" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
</ListView> 

Чтобы сделать это, вам нужно ссылаться на System.Windows.Interactivity.dll в вашем XAML:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

Это, как говорится, вы должны использовать рамки MVMM, например, MVVM для упрощения реализации команд в целом.В конечном итоге он не подлежит поддержке, чтобы иметь один класс для каждой команды, в которой вы нуждаетесь. Структура, такая как MVVMLight или PRISM, предоставляет DelegateCommands, которые позволяют вам создавать новые команды от делегатов (методы на вашем ViewModel) напрямую.

Смежные вопросы