silverlight 学习笔记 (五): MVVM Light Toolkits 之 RealCommand
在MVVM模式中我們在設計ViewModel時需要定義大量的事件處理程序,這些事件處理程序可以通過在View中綁定進行觸發,具體時間參考前面所講。ViewModel中的需要將事件定義為公開的繼承ICammand的屬性如下:
public ICommand QueryCommand { get; private set; }
ICommand接口提供了兩個方法(Execute、CanExecute)和一個事件(CanExecuteChanged),Execute執行事件實際的處理函數,CanExecute表示是否執行事件,CanExecuteChanged事件則是通知CanExecute狀態的改變。
在MVVM light toolkits 包中一個很重要的功能就是提供了對ICommand的封裝,讓我們在實現ViewModel中的事件處理變動更方便了,下面重點說下RelayCommand方法的應用。
1、如何在ViewModel中觸發一個不帶任何參數的事件
首先在ViewModel中定義一個事件屬性,并在構造函數中定義為該事件指定處理函數。然后在View中通過綁定ViewModel的事件屬性,這樣就能夠實現對事件的觸發了。需要說明的是在silverlight中只有實現了ICommandSource的控件才能實現Command的綁定,否則可以通過Silverlight中行為模式(InvokeCommandAction)進行觸發。
public MainViewModel()//構造函數 { NoParamCommand=new RelayCommand(ShowMessage); CanExecuteCommand= new RelayCommand(ShowMessage, () => CanExcute); } public RelayCommand NoParamCommand { get; private set; }private void ShowMessage() { MessageBox.Show("this is test "); }View中的按鈕事件綁定
<Button Content="NoParamMessage" HorizontalAlignment="Left" Height="26" Margin="43,56,0,0" VerticalAlignment="Top" Width="107" Command="{Binding Main.NoParamCommand, Mode=OneWay}"/>也可用行為模式綁定(最好在Blend中設計)
<Button Content="NoParamMessage" HorizontalAlignment="Left" Height="26" Margin="43,56,0,0" VerticalAlignment="Top" Width="107"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{Binding Main.NoParamCommand, Mode=OneWay}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>
2、如何觸發一個帶參數的事件
方法基本同上,不同的是需要在事件屬性使用一個帶參數的泛型定義
public RelayCommand<string> ParamCommand { get; private set; } public MainViewModel() { NoParamCommand=new RelayCommand(ShowMessage); CanExecuteCommand= new RelayCommand(ShowMessage, () => CanExcute); ParamCommand=new RelayCommand<string>(ShowParamMessage); } private void ShowParamMessage(string msg) { MessageBox.Show(msg); }3、如何在事件處理函數上攜帶事件源及事件源參數,比如我們一個TextBox控件在TextChanged事件
private void textBox1_TextChanged(object sender, TextChangedEventArgs e) { }我們希望在ViewModel中定義的事件處理函數能夠攜帶 sender和事件參數 e,這樣做在實際項目中還是有很大意義的。這就需要使用自定義事件了,本人從網上找到一段代碼 public class EventInformation<TEventArgsType> { public object Sender { get; set; } public TEventArgsType EventArgs { get; set; } public object CommandArgument { get; set; } } public class MapEventToCommand : MapEventToCommandBase<EventArgs> { } public class MapRoutedEventToCommand : MapEventToCommandBase<RoutedEventArgs> { } public abstract class MapEventToCommandBase<TEventArgsType> : TriggerAction<FrameworkElement> where TEventArgsType : EventArgs { public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(MapEventToCommandBase<TEventArgsType>), new PropertyMetadata(null, OnCommandPropertyChanged)); public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(MapEventToCommandBase<TEventArgsType>), new PropertyMetadata(null, OnCommandParameterPropertyChanged)); private static void OnCommandParameterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var invokeCommand = d as MapEventToCommand; if (invokeCommand != null) { invokeCommand.SetValue(CommandParameterProperty, e.NewValue); } } private static void OnCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var invokeCommand = d as MapEventToCommand; if (invokeCommand != null) { invokeCommand.SetValue(CommandProperty, e.NewValue); } } protected override void Invoke(object parameter) { if (this.Command == null) { return; } var eventInfo = new EventInformation<TEventArgsType> { EventArgs = parameter as TEventArgsType, Sender = this.AssociatedObject, CommandArgument = GetValue(CommandParameterProperty) }; if (this.Command.CanExecute(eventInfo)) { this.Command.Execute(eventInfo); } } public ICommand Command { get { return (ICommand)base.GetValue(CommandProperty); } set { base.SetValue(CommandProperty, value); } } public object CommandParameter { get { return base.GetValue(CommandParameterProperty); } set { base.SetValue(CommandParameterProperty, value); } } }
該事件的使用方法 public MainViewModel() { NoParamCommand=new RelayCommand(ShowMessage); CanExecuteCommand= new RelayCommand(ShowMessage, () => CanExcute); ParamCommand=new RelayCommand<string>(ShowParamMessage); EventParamCommand = new RelayCommand<EventInformation<RoutedEventArgs>>(ShowEventParamMessage); }
public RelayCommand<EventInformation<RoutedEventArgs>> EventParamCommand { get; private set; } private void ShowEventParamMessage(EventInformation<RoutedEventArgs> ei) { string msg = ""; msg += "事件源:" + (ei.Sender as TextBox).Text; msg += "事件參數:" + ei.EventArgs.GetType().ToString(); msg += "綁定參數:" + ei.CommandArgument.ToString(); MessageBox.Show(msg); }View中的綁定使用的是一樣自定義的行為 <TextBox Height="23" HorizontalAlignment="Left" Margin="166,174,0,0" x:Name="textBox1" VerticalAlignment="Top" Width="120" > <i:Interaction.Triggers> <i:EventTrigger EventName="TextChanged"> <MvvmLight3_ViewModel:MapRoutedEventToCommand Command="{Binding Main.EventParamCommand, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=textBox}"/> </i:EventTrigger> </i:Interaction.Triggers> </TextBox>
4、如何有條件定義事件執行或不執行
其實很簡單,ICommand有一個參數canExcute,只需要對該參數進行設置即可,需要注意的是該參數設置后要觸發一個事件RaiseCanExecuteChanged
?private bool _canExcute=false; public bool CanExcute { get { return _canExcute; } set { _canExcute = value; RaisePropertyChanged("CanExcute"); CanExecuteCommand.RaiseCanExecuteChanged(); } } public RelayCommand CanExecuteCommand { get; private set; } public MainViewModel() { NoParamCommand=new RelayCommand(ShowMessage); CanExecuteCommand= new RelayCommand(ShowMessage, () => CanExcute); ParamCommand=new RelayCommand<string>(ShowParamMessage); EventParamCommand = new RelayCommand<EventInformation<RoutedEventArgs>>(ShowEventParamMessage); }
可以將CanExcute綁定到一個控件上來控制事件是否執行,只要該屬性發生變化都將觸發RaiseCanExecuteChanged,RaiseCanExecuteChanged會根據canExcute參數值覺得是否可執行,有點類似于控件的Enable,但其應用范圍可考慮在實際項目中有條件觸發。
以上是RelayCommand的應用,相對比較簡單,在MVVM light toolkits 中還有Message沒開始學習,都連續幾天沒好好睡覺了,累死了!!!
轉載于:https://www.cnblogs.com/oldkingsir/archive/2011/09/08/2365632.html
總結
以上是生活随笔為你收集整理的silverlight 学习笔记 (五): MVVM Light Toolkits 之 RealCommand的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql的用户和密码
- 下一篇: EXAM6