绑定ICommand进入按下状态

时间:2012-07-24 07:47:33

标签: mvvm-light windows-runtime icommand

所以我有一个基本视图的Windows 8应用程序: 例如:

 <TextBox Text="{Binding UserName}"/>
 <PasswordBox Text="{Binding Password}"/>
 <Button Content="Sign In" Command="{Binding Login}"/>

实现了ICommand的视图模型。


public class LoginViewModel : ViewModelBase
{
    public ICommand Login { get; set; }
    //Other properties

    public LoginViewModel()
    {
       Login = ExecuteLogin;
    }

    public void ExecuteLogin()
    {
         //Logic
    }
}

一切正常。但是现在我想在用户按下密码框时触发ICommand,只是为了获得更好的用户体验。有人知道怎么做吗?

1 个答案:

答案 0 :(得分:3)

是的,你需要的是这堂课:

namespace SL
{
    public sealed class EnterKeyDown
    {
        #region Properties

        #region Command

        /// <summary>
        /// GetCommand
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static ICommand GetCommand(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(CommandProperty);
        }

        /// <summary>
        /// SetCommand
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        public static void SetCommand(DependencyObject obj, ICommand value)
        {
            obj.SetValue(CommandProperty, value);
        }

        /// <summary>
        /// DependencyProperty CommandProperty
        /// </summary>
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(EnterKeyDown), new PropertyMetadata(null, OnCommandChanged));

        #endregion Command

        #region CommandParameter

        /// <summary>
        /// GetCommandParameter
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static object GetCommandParameter(DependencyObject obj)
        {
            return (object)obj.GetValue(CommandParameterProperty);
        }

        /// <summary>
        /// SetCommandParameter
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        public static void SetCommandParameter(DependencyObject obj, object value)
        {
            obj.SetValue(CommandParameterProperty, value);
        }

        /// <summary>
        /// DependencyProperty CommandParameterProperty
        /// </summary>
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached("CommandParameter", typeof(object), typeof(EnterKeyDown), new PropertyMetadata(null, OnCommandParameterChanged));

        #endregion CommandParameter

        #region HasCommandParameter

        private static bool GetHasCommandParameter(DependencyObject obj)
        {
            return (bool)obj.GetValue(HasCommandParameterProperty);
        }

        private static void SetHasCommandParameter(DependencyObject obj, bool value)
        {
            obj.SetValue(HasCommandParameterProperty, value);
        }

        private static readonly DependencyProperty HasCommandParameterProperty =
            DependencyProperty.RegisterAttached("HasCommandParameter", typeof(bool), typeof(EnterKeyDown), new PropertyMetadata(false));

        #endregion HasCommandParameter

        #endregion Propreties

        #region Event Handling

        private static void OnCommandParameterChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            SetHasCommandParameter(o, true);
        }

        private static void OnCommandChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement element = o as FrameworkElement;
            if (element != null)
            {
                if (e.NewValue == null)
                {
                    element.KeyUp -= FrameworkElementKeyUp;
                }
                else if (e.OldValue == null)
                {
                    element.KeyUp += FrameworkElementKeyUp;
                }
            }
        }

        private static void FrameworkElementKeyUp(object sender, KeyRoutedEventArgs e)
        {
            if (e.Key == VirtualKey.Enter)
            {
                var o = sender as DependencyObject;
                var command = GetCommand(sender as DependencyObject);

                var element = e.OriginalSource as FrameworkElement;
                if (element != null)
                {
                    // If the command argument has been explicitly set (even to NULL) 
                    if (GetHasCommandParameter(o))
                    {
                        var commandParameter = GetCommandParameter(o);

                        // Execute the command 
                        if (command.CanExecute(commandParameter))
                        {
                            command.Execute(commandParameter);
                        }
                    }
                    else if (command.CanExecute(element.DataContext))
                    {
                        command.Execute(element.DataContext);
                    }
                }
            }
        }

        #endregion
    }
}

XAML命名空间:

xmlns:sl="clr-namespace:SL;"

XAML代码:

<TextBox sl:EnterKeyDown.Command="{Binding SearchClickCommand}"                              
          Text="{Binding Input, Mode=TwoWay, 
             NotifyOnValidationError=True, ValidatesOnDataErrors=True, 
             ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True}" />

<Button Content="Search"
        Command="{Binding SearchClickCommand}" />