【问题标题】:PasswordBox validation on text change instead of Lose FocusPasswordBox 验证文本更改而不是失去焦点
【发布时间】:2012-01-25 15:55:08
【问题描述】:

框架:Silverlight 4

我有一个简单的ChildWindow,用户名TextBox,密码PasswordBox。我已将事件处理程序附加到窗口的 KeyDown 事件。

private void onKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Escape)
        cancelButtonClick(null, null);

    if (e.Key == Key.Enter)
        okButtonClick(null, null);
}

我想要实现的是,当用户按下键盘上的 Enter 键时,程序的行为就像用户单击了 OK 按钮一样。

问题是验证。

Silverlight 的 PasswordBox 的默认行为是在控件失去焦点时执行验证。我的 PasswordBox 绑定到一些 User 对象。当我单击 Enter 按钮时,将调用事件处理程序,进而调用 okButtonClick(null, null)。问题是此时PasswordBox还没有失去焦点,所以PasswordBox绑定的user.Password属性还是空的。

我尝试将btnOK.Focus() 放在okButtonClick(null, null) 之前,但无济于事。

如何设置绑定,以便控件在每次文本更改时而不是在LostFocus 事件上更新绑定?实现我需要的正确方法是什么?

【问题讨论】:

  • 您是否考虑过使用您的 PasswordBox 创建一个以双向模式绑定的 DependencyProperty?因此,当您触发“onKeyDown”事件时,您可以在方法中使用某种验证。
  • 我不太清楚你的意思。 PasswordBox 的 Password 属性已经绑定到我的用户对象(显然是在 TwoWay 模式下),但除非 PasswordBox 失去焦点,否则不会分配该值。我可以在我的 onKeyDown 处理程序中手动设置值,但这会使绑定在这种情况下毫无用处,因为自动进行此类更改是首先使用绑定的动机。

标签: silverlight validation binding focus keydown


【解决方案1】:

将PasswordChanged 事件用于Passwordbox。
Textbox 具有TextboxChanged 事件。

【讨论】:

    【解决方案2】:

    我已经通过绊倒upon this solution解决了这个问题。

    它基本上使用附加属性来订阅 TextChanged/PasswordChnaged 事件,然后在事件中更新绑定源。在根据我的需要调整the solution 之后,这就是我得到的(它完美地工作):

    public class BindingHelper
    {
        public static readonly DependencyProperty RefreshOnChangeProperty =
            DependencyProperty.RegisterAttached("RefreshOnChange", typeof(bool), typeof(BindingHelper),
            new PropertyMetadata(false, OnRefreshOnChangeChanged));
    
        public static void SetRefreshOnChange(DependencyObject o, bool value)
        {
            o.SetValue(RefreshOnChangeProperty, value);
        }
    
        public static bool GetRefreshOnChange(DependencyObject o)
        {
            return (bool)o.GetValue(RefreshOnChangeProperty);
        }
    
        private static void OnRefreshOnChangeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if ((obj as TextBox) != null)
            {
                if ((bool)e.NewValue)
                    (obj as TextBox).TextChanged += textBox_TextChanged;
                else
                    (obj as TextBox).TextChanged -= textBox_TextChanged;
            }
    
            if ((obj as PasswordBox) != null)
            {
                if ((bool)e.NewValue)
                    (obj as PasswordBox).PasswordChanged += passwordBox_PasswordChanged;
                else
                    (obj as PasswordBox).PasswordChanged -= passwordBox_PasswordChanged;
            }
        }
    
        static void passwordBox_PasswordChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox passwordBox = sender as PasswordBox;
            if (passwordBox != null)
            {
                BindingExpression binding = passwordBox.GetBindingExpression(PasswordBox.PasswordProperty);
                if (binding != null)
                    binding.UpdateSource();
            }
        }
    
        static void textBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox != null)
            {
                BindingExpression binding = textBox.GetBindingExpression(TextBox.TextProperty);
                if (binding != null)
                    binding.UpdateSource();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多