我如今作一個系統登陸功能,要求在PasswordBox上輸完密碼後回車,可以響應Enter事件,並執行ViewModel中對應的方法。若是登陸成功則隱藏當前窗口顯示主窗體,登陸失敗則焦點返回到用戶名TextBox中,並全選文字,方便用戶再從新輸入。數組
這個在咱們製造業自動化流程控制中,作防呆功能是很明顯的,由於沒有人爲去參與。ide
若是像Winform同樣的開發模式,就相對很簡單了,如今是要在ViewModel,對一個初學者來講就相對地困難多了,那怎麼辦呢?測試
自定義一個Command,支持多參數對象數組,把控件,事件傳到ViewModel中。 this
// ----------------------------------------------------------------------- // <copyright file="InteractiveCommand.cs" company=""> // TODO: Update copyright text. // </copyright> // ----------------------------------------------------------------------- namespace TLAgent.SecurityManager.WPF { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Input; using System.Windows.Interactivity; using System.Reflection; /// <summary> /// TODO: Update summary. /// </summary> public class InteractiveCommand : TriggerAction<DependencyObject> { protected override void Invoke(object parameter) { if (base.AssociatedObject != null) { ICommand command = this.ResolveCommand(); object[] tempObj = { parameter, CommandParameter }; if ((command != null) && command.CanExecute(tempObj)) { command.Execute(tempObj); } } } public object CommandParameter { get { return GetValue(CommandParameterProperty); } set { SetValue(CommandParameterProperty, value); } } public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register ("CommandParameter", typeof(object), typeof(InteractiveCommand), new PropertyMetadata(null, OnCommandParameterChanged)); private static void OnCommandParameterChanged (DependencyObject sender, DependencyPropertyChangedEventArgs e) { InteractiveCommand ic = sender as InteractiveCommand; if (ic != null) { ic.SynchronizeElementState(); } } private void SynchronizeElementState() { ICommand command = Command; if (command != null) { FrameworkElement associatedObject = AssociatedObject as FrameworkElement; if (associatedObject != null) { associatedObject.IsEnabled = command.CanExecute(CommandParameter); } } } private ICommand ResolveCommand() { ICommand command = null; if (this.Command != null) { return this.Command; } if (base.AssociatedObject != null) { foreach (PropertyInfo info in base.AssociatedObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (typeof(ICommand).IsAssignableFrom(info.PropertyType) && string.Equals(info.Name, this.CommandName, StringComparison.Ordinal)) { command = (ICommand)info.GetValue(base.AssociatedObject, null); } } } return command; } private string commandName; public string CommandName { get { base.ReadPreamble(); return this.commandName; } set { if (this.CommandName != value) { base.WritePreamble(); this.commandName = value; base.WritePostscript(); } } } #region Command public ICommand Command { get { return (ICommand)GetValue(CommandProperty); } set { SetValue(CommandProperty, value); } } public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(InteractiveCommand), new UIPropertyMetadata(null)); #endregion } }
2. 在XAML中作綁定,把EventName定爲」KeyDown「,請參考以下代碼:spa
<PasswordBox x:Name="txtPassword" Height="23" Helper:PasswordBoxHelper.Attach="True" Helper:PasswordBoxHelper.Password="{Binding Path=AuthUser.Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="101,92,0,0" VerticalAlignment="Top" Width="178" TabIndex="2"> <i:Interaction.Triggers> <i:EventTrigger EventName="KeyDown"> <Helper:InteractiveCommand Command="{Binding EnterLoginCommand}" CommandName="EnterLoginCommand" CommandParameter="{Binding ElementName=txtUserName}"/> </i:EventTrigger> </i:Interaction.Triggers> </PasswordBox>
3. 後臺的Command聲明爲DelegateCommand<object[]><object[]><object[]><object[]> _CommandWithEventArgs,並實例化,同時綁定一個帶參數object[]的用戶驗證方法:設計
public ICommand EnterLoginCommand { get { return _CommandWithEventArgs ?? (_CommandWithEventArgs = new DelegateCommand<object[]>(CheckUser)); } }
綁定的方法爲CheckUser,以下3d
private void CheckUser(object[] objs) { KeyEventArgs e = objs[0] as KeyEventArgs; if (e.Key == Key.Enter) { object obj = objs[1]; VerifyUser(obj); } } private void VerifyUser(object objParam) { if (AuthUser.UserName != null && AuthUser.Password != null) { if (AuthUser.UserName.ToUpper().Equals("AGAN") && AuthUser.Password.Equals("123")) { IsVisibility = Visibility.Hidden; SplashScreen splashScreen = new SplashScreen("Images/SplashScreen.JPG"); splashScreen.Show(true); MainWindow window = new MainWindow(); window.ShowDialog(); } else { MessageBox.Show(@"用戶名或密碼錯誤!"); TextBox txtUserName = (TextBox)objParam; txtUserName.Focus(); txtUserName.SelectAll(); } } else { MessageBox.Show(@"用戶名或密碼不能爲空!"); TextBox txtUserName = (TextBox)objParam;//轉換爲TextBox,即爲View層的txtUserName控件 txtUserName.Focus();//獲取焦點 txtUserName.SelectAll();//全選文本 } }
運行程序後,輸入用戶密碼,顯示如圖:code