2013-03-07 38 views
3

在MVVM/WPF環境中,當引發ListView的SelectionChanged事件時,我想調用ViewModel上的命令(ComputeCommand)。這怎麼可能在XAML或C#中完成?如何調用ListView的SelectionChanged上的ViewModel上的命令?

這是我的命令類。我在代碼隱藏中嘗試過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> 

視圖模型:

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在模式中,你需要編寫更多的代碼,但是它的靈活性會讓你受益匪淺。

+0

何處添加?任何地方或內部? – gsmida 2013-03-07 09:28:20

+0

Tigran 2013-03-07 09:37:03

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 
} 

或通過結合項容器的IsSelected屬性來處理它在視圖模型側

+0

我已經嘗試過解決方案,但沒有工作:/我使用MVVM,因爲我有一些數據在執行時在屏幕上更新 – gsmida 2013-03-07 09:35:24

+0

你是什麼意思的「沒有工作」 ?他們沒有編譯?無法執行?有例外嗎?或者是什麼? – 2013-03-07 10:00:45

+0

SelectionChanged =「{Binding MyCommand}」上的XamlParseException「 – gsmida 2013-03-07 10:09:36

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上的方法)創建新命令。

相關問題