• silverlight绑定回车登录经典方法


    silverlight回车登录的实现

     

    浅谈Silverlight应用之回车登录最佳实践

    对于一个应用系统来说,登录是最最基本的功能,也是最简单的功能。本文就Silverlight应用的登录表单来谈谈怎样做到最佳实践,这也是我学习Silverlight的些许沉淀。

    想必会有朋友觉得这么简单的功能不值得小题大做,其实非也。

    首先来看下我专门为此文准备的这个Silverlight Demo的登录表单:

    Login-Form

    一个登录表单无非就是几个文本框加一个登录按钮或取消按钮而已。而我们都知道对于系统的登录除了可以单击登录按钮登录之外,还需要使用回车键进行登录,这基本是每一个登录表单都具备的功能,缺一不可,如果不提供Enter键登录那就大大降低了用户体验。

    而本文所探讨的则是在Silverlight应用中如何去做Enter键登录。可能做ASP.NET开发的朋友很清楚,ASP.NET中登录表单的是不需要专门写代码来控制Enter键登录的,至于纯HTML的Form等等我就不啰嗦了。对于上面这个登录表单,先看下该表单的XAML构成(只贴出重心代码):

    1. <SPAN><SPAN style="COLOR: #000000; FONT-WEIGHT: bold"><TextBlock</SPAN> <SPAN>Text</SPAN>=<SPAN>"用户名:"</SPAN></SPAN>  
    2. <SPAN>     <SPAN>Grid.Row</SPAN>=<SPAN>"0"</SPAN></SPAN>  
    3. <SPAN>     <SPAN>Grid.Column</SPAN>=<SPAN>"0"</SPAN></SPAN>  
    4. <SPAN>     <SPAN>Margin</SPAN>=<SPAN>"10 20 5 0"</SPAN></SPAN>  
    5. <SPAN>     <SPAN>VerticalAlignment</SPAN>=<SPAN>"Center"</SPAN></SPAN>  
    6. <SPAN>     <SPAN>HorizontalAlignment</SPAN>=<SPAN>"Right"</SPAN> <SPAN style="COLOR: #000000; FONT-WEIGHT: bold">/></SPAN></SPAN>  
    7. <SPAN><SPAN style="COLOR: #000000; FONT-WEIGHT: bold"><TextBox</SPAN> <SPAN>x:Name</SPAN>=<SPAN>"userNameBox"</SPAN></SPAN>  
    8. <SPAN>     <SPAN>Grid.Row</SPAN>=<SPAN>"0"</SPAN></SPAN>  
    9. <SPAN>     <SPAN>Grid.Column</SPAN>=<SPAN>"1"</SPAN></SPAN>  
    10. <SPAN>     <SPAN>Margin</SPAN>=<SPAN>"0 20 0 0"</SPAN></SPAN>  
    11. <SPAN>     <SPAN>Width</SPAN>=<SPAN>"220"</SPAN></SPAN>  
    12. <SPAN>     <SPAN>Height</SPAN>=<SPAN>"26"</SPAN></SPAN>  
    13. <SPAN>     <SPAN>Text</SPAN>=<SPAN>"{Binding Path=UserName,Mode=TwoWay,NotifyOnValidationError=TrueValidatesOnExceptions=True}"</SPAN></SPAN>  
    14. <SPAN>     <SPAN>TextChanged</SPAN>=<SPAN>"userNameBox_TextChanged"</SPAN> <SPAN>SelectionChanged</SPAN>=<SPAN>"userNameBox_SelectionChanged"</SPAN> <SPAN style="COLOR: #000000; FONT-WEIGHT: bold">/></SPAN></SPAN>  
    15. <SPAN><SPAN style="COLOR: #000000; FONT-WEIGHT: bold"><TextBlock</SPAN> <SPAN>Text</SPAN>=<SPAN>"密码:"</SPAN></SPAN>  
    16. <SPAN>     <SPAN>Grid.Row</SPAN>=<SPAN>"1"</SPAN></SPAN>  
    17. <SPAN>     <SPAN>Grid.Column</SPAN>=<SPAN>"0"</SPAN></SPAN>  
    18. <SPAN>     <SPAN>Margin</SPAN>=<SPAN>"10 0 5 0"</SPAN></SPAN>  
    19. <SPAN>     <SPAN>VerticalAlignment</SPAN>=<SPAN>"Center"</SPAN></SPAN>  
    20. <SPAN>     <SPAN>HorizontalAlignment</SPAN>=<SPAN>"Right"</SPAN> <SPAN style="COLOR: #000000; FONT-WEIGHT: bold">/></SPAN></SPAN>  
    21. <SPAN><SPAN style="COLOR: #000000; FONT-WEIGHT: bold"><PasswordBox</SPAN> <SPAN>x:Name</SPAN>=<SPAN>"userPwdBox"</SPAN></SPAN>  
    22. <SPAN>     <SPAN>Grid.Row</SPAN>=<SPAN>"1"</SPAN></SPAN>  
    23. <SPAN>     <SPAN>Grid.Column</SPAN>=<SPAN>"1"</SPAN></SPAN>  
    24. <SPAN>     <SPAN>Width</SPAN>=<SPAN>"220"</SPAN></SPAN>  
    25. <SPAN>     <SPAN>Height</SPAN>=<SPAN>"26"</SPAN></SPAN>  
    26. <SPAN>     <SPAN>Password</SPAN>=<SPAN>"{Binding Path=UserPwd,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}"</SPAN></SPAN>  
    27. <SPAN>     <SPAN>PasswordChanged</SPAN>=<SPAN>"userPwdBox_PasswordChanged"</SPAN> <SPAN style="COLOR: #000000; FONT-WEIGHT: bold">/></SPAN></SPAN>  
    28. <SPAN><SPAN style="COLOR: #000000; FONT-WEIGHT: bold"><Button</SPAN> <SPAN>x:Name</SPAN>=<SPAN>"loginBtn"</SPAN></SPAN>  
    29. <SPAN>     <SPAN>Content</SPAN>=<SPAN>"登录"</SPAN></SPAN>  
    30. <SPAN>     <SPAN>Grid.Row</SPAN>=<SPAN>"2"</SPAN></SPAN>  
    31. <SPAN>     <SPAN>Grid.ColumnSpan</SPAN>=<SPAN>"2"</SPAN></SPAN>  
    32. <SPAN>     <SPAN>HorizontalAlignment</SPAN>=<SPAN>"Right"</SPAN></SPAN>  
    33. <SPAN>     <SPAN>Width</SPAN>=<SPAN>"120"</SPAN></SPAN>  
    34. <SPAN>     <SPAN>Height</SPAN>=<SPAN>"30"</SPAN></SPAN>  
    35. <SPAN>     <SPAN>Margin</SPAN>=<SPAN>"0 0 30 0"</SPAN></SPAN>  
    36. <SPAN>     <SPAN>Click</SPAN>=<SPAN>"loginBtn_Click"</SPAN> <SPAN style="COLOR: #000000; FONT-WEIGHT: bold">/></SPAN></SPAN>  
    <TextBlock Text="用户名:"
         Grid.Row="0"
         Grid.Column="0"
         Margin="10 20 5 0"
         VerticalAlignment="Center"
         HorizontalAlignment="Right" />
    <TextBox x:Name="userNameBox"
         Grid.Row="0"
         Grid.Column="1"
         Margin="0 20 0 0"
         Width="220"
         Height="26"
         Text="{Binding Path=UserName,Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True}"
         TextChanged="userNameBox_TextChanged" SelectionChanged="userNameBox_SelectionChanged" />
    <TextBlock Text="密码:"
         Grid.Row="1"
         Grid.Column="0"
         Margin="10 0 5 0"
         VerticalAlignment="Center"
         HorizontalAlignment="Right" />
    <PasswordBox x:Name="userPwdBox"
         Grid.Row="1"
         Grid.Column="1"
         Width="220"
         Height="26"
         Password="{Binding Path=UserPwd,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}"
         PasswordChanged="userPwdBox_PasswordChanged" />
    <Button x:Name="loginBtn"
         Content="登录"
         Grid.Row="2"
         Grid.ColumnSpan="2"
         HorizontalAlignment="Right"
         Width="120"
         Height="30"
         Margin="0 0 30 0"
         Click="loginBtn_Click" />

    首先,为登录按钮添加Click事件,实现单击登录按钮进行登录。

            private void loginBtn_Click(object sender, RoutedEventArgs e)
            {
                UpdateBindingExpression(userNameBox, TextBox.TextProperty);
                UpdateBindingExpression(userPwdBox, PasswordBox.PasswordProperty);
     
                if (!loginValidation.HasErrors)
                {
                    // 登录验证...
                }
            }

    详细的逻辑代码我就省略了。这样我们就能登录到系统了,接下来就是本文要谈的重点了。因为现在我们是不能通过输入用户名和密码后敲Enter键登录的,我想大家最容易想到的方法便是为userPwd这个PassWordBox添加KeyDown事件:

    <PasswordBox x:Name="userPwdBox"
         Grid.Row="1"
         Grid.Column="1"
         Width="220"
         Height="26"
         Password="{Binding Path=UserPwd,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}"
         PasswordChanged="userPwdBox_PasswordChanged"
         KeyDown="userPwdBox_KeyDown" />

    然后再把上面那个登录按钮的代码Ctrl+C、Ctrl+V到userPwdBox_KeyDown方法体中,最后在添加点判断敲击的是不是Enter键的代码。这样当然可以,因为实现了文本框的Enter键登录。但这样是不是最佳的解决方案呢?当然不是,那么接下来就来看看本文所说的最佳实践。

    先谈谈思路吧,从上面的分析知道,既然是基本相同的代码,那我们应该让文本框在敲下Enter键的时候去触发登录按钮的方法,那么就可以不必再写同样的代码了。这一点应该是很容易想到的,那么怎样实现就需要我们对Silverlight的进一步的了解了。

    在Silverlight 3中,Behaviour和Trigger绝对是让大家比较喜欢的东西了。它们允许你以声明方式将操作关联到事件或属性的值。但之前,行为和触发器需要我们安装上 Microsoft Expression Blend SDK ,然后添加System.Windows.Interactivity.dll 程序集的引用。

    目前,我们可以使用三种类型的行为: Behavour、 TriggerAction 和 TargetedTriggerAction。在这里,我们使用TargetedTriggerAction<T>泛型类,它表示操作时可以面向一个完全不同的对象,而不受其关联的对象的影响。 它允许我们将触发器关联从一个对象到另一个对象,操作完全不同的元素。所以这里就特别适合了。

    新建一个TextBoxEnterBehaviour类,继承自泛型类TargetedTriggerAction<T>,泛型类型为ButtonBase,这里使用ButtonBase是因为它表示所有按钮控件的基类,例如 Button、RepeatButton 和 HyperlinkButton,更加方便我们扩展。TextBoxEnterBehaviour类的详细实现如下:

        public class TextBoxEnterBehaviour : TargetedTriggerAction<ButtonBase>
        {
            private AutomationPeer peer;
     
            private ButtonBase targetedButton;
     
            /// <summary>
            /// 在附加TargetedTriggerAction到关联对象后发生
            /// </summary>
            protected override void OnAttached()
            {
                base.OnAttached();
     
                targetedButton = this.Target;
                if (null == targetedButton)
                {
                    return;
                }
                this.peer = FrameworkElementAutomationPeer.FromElement(targetedButton);
                if (this.peer == null)
                {
                    this.peer = FrameworkElementAutomationPeer.CreatePeerForElement(targetedButton);
                }
            }
     
            /// <summary>
            /// 关联的Button改变后发生
            /// </summary>
            /// <param name="oldTarget"></param>
            /// <param name="newTarget"></param>
     
            protected override void OnTargetChanged(ButtonBase oldTarget, ButtonBase newTarget)
            {
                base.OnTargetChanged(oldTarget, newTarget);
     
                targetedButton = newTarget;
                if (null == targetedButton)
                {
                    return;
                }
                this.peer = FrameworkElementAutomationPeer.FromElement(targetedButton);
                if (this.peer == null)
                {
                    this.peer = FrameworkElementAutomationPeer.CreatePeerForElement(targetedButton);
                }
            }
     
            /// <summary>
            /// 激活targeted Button并启动targeted Button的单个明确操作
            /// </summary>
            /// <param name="parameter"></param>
     
            protected override void Invoke(object parameter)
            {
                KeyEventArgs keyEventArgs = parameter as KeyEventArgs;
                if (null != keyEventArgs && keyEventArgs.Key == Key.Enter)
                {
                    if (null != this.peer && this.peer.IsEnabled())
                    {
                        IInvokeProvider invokeProvider = this.peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
                        invokeProvider.Invoke();
                    }
                }
            }
        }

    然后为userPwdBox添加触发器。首先在该登录表单的XAML中添加如下声明:

    xmlns:interaction="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:behaviour="clr-namespace:SLDemo" (这个为TextBoxEnterBehaviour类所在命名空间)

    然后修改userPwdBox为如下代码:

    <PasswordBox x:Name="userPwdBox"
         Grid.Row="1"
         Grid.Column="1"
         Width="220"
         Height="26"
         Password="{Binding Path=UserPwd,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnExceptions=True}"
         PasswordChanged="userPwdBox_PasswordChanged">
      <interaction:Interaction.Triggers>
        <interaction:EventTrigger EventName="KeyDown">
            <behaviour:TextBoxEnterBehaviour TargetName="loginBtn" />  (TargetName为关联的登录按钮的Name属性值)
        </interaction:EventTrigger>
      </interaction:Interaction.Triggers>
    </PasswordBox>

    这样便通过很好的方法实现了Silverlight应用中的文本框回车登录。因为这样真正避免了重复代码

  • 相关阅读:
    动态封杀与解封IP
    潜谈IT从业人员在传统IT和互联网之间的择业问题(下)-互联网公司
    潜谈IT从业人员在传统IT和互联网之间的择业问题(上)-传统乙方形公司
    博主2000年真实遇鬼记-仅作记录以供后人参考
    异步请求引发的Chrome死锁
    jboss规则引擎KIE Drools 6.3.0 Final 教程(3)
    jboss规则引擎KIE Drools 6.3.0 Final 教程(2)
    jboss规则引擎KIE Drools 6.3.0 Final 教程(1)
    商品搜索引擎---推荐系统设计
    大道理很多人都懂,只是坚持不下去(浅谈坚持)
  • 原文地址:https://www.cnblogs.com/loyung/p/3106440.html
Copyright © 2020-2023  润新知