• silverlighter下MVVM模式中利用Behavior和TargetedTriggerAction实现文本框的一些特效


      在silverlight一般开发模式中,给文本框添加一些事件是轻而易举的,然而MVVM开发模式中,想要给文本框添加一些事件并非那么容易,因为MVVM模式中,只有ICommand接口,而且也只有Button中才有Command属性,通过ViewModel可以将方法绑定到Button上面,却无法绑定到文本框和其他一些控件。、

      Behavior的出现解决了这一难题,下面就来说一下具体的实现方法:

      实例一:在用户登录窗口,用户点击Reset按钮后,让用户名输入框自动获取焦点。

      首先要先将ViewModel绑定到我们的控件上面,我们一步一步来做,第一步先写Model,下面是Model的代码:

      

    using System;
    using System.Net;
    using System.Runtime.Serialization;
    using System.ComponentModel;
    
    namespace BookModel
    {
       [DataContract]
       public class UserModel : INotifyPropertyChanged
       {
          public event PropertyChangedEventHandler PropertyChanged;
    
          private string userName = String.Empty;
          private string passWord = String.Empty;
    
          [DataMember]
          public string UserName
          {
             get { return userName; }
             set { userName = value; OnPropertyChanged("UserName"); }
          }
    
          [DataMember]
          public string PassWord
          {
             get { return passWord; }
             set { passWord = value; OnPropertyChanged("PassWord"); }
          }
    
          /// <summary>
          /// Call the event PropertyChanged.
          /// </summary>
          /// <param name="PropertyName"></param>
          public void OnPropertyChanged(string PropertyName)
          {
             if (PropertyChanged != null)
             {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
             }
          }
       }
    }

      写完了Model,下一步就是写ViewModel了,在ViewModel中引用Model的命名控件,下面是ViewModel的代码,例子比较简单,就不多解释了。

      

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using BookModel;
    using System.Windows.Browser;
    
    namespace BookViewModel
    {
       public class VM_User
       {
          /// <summary>
          /// In the Constructors create the instance of User.
          /// </summary>
          public VM_User()
          {
             user = new UserModel();
             user.UserName = "Jack";
          }
    
          public UserModel user { get; set; }
          public LoginCommand Login
          {
             get { return new LoginCommand(); }
          }
          public ResteCommand Reset
          {
             get { return new ResteCommand(); }
          }
       }
    
       /// <summary>
       /// Login Button's method
       /// </summary>
       public class LoginCommand:ICommand
       {
          public bool CanExecute(object parameter)
          {
             return true;
          }
    
          public void Execute(object parameter)
          {
             VM_User VMUser = parameter as VM_User;
             if (VMUser.user.UserName.Equals("admin") && VMUser.user.PassWord.Equals("123"))
             {
                MessageBox.Show("Login success!", "System Info", MessageBoxButton.OK);
             }
             else
             {
                MessageBox.Show("Login failed!", "System Info", MessageBoxButton.OK);
             }
          }
    
          public event EventHandler CanExecuteChanged;
       }
    
       /// <summary>
       /// Reset buttom's method
       /// </summary>
       public class ResteCommand : ICommand
       {
          public bool CanExecute(object parameter)
          {
             return true;
          }
    
          public void Execute(object parameter)
          {
             VM_User VMUser = parameter as VM_User;
             VMUser.user.UserName = "";
             VMUser.user.PassWord = "";
          }
          public event EventHandler CanExecuteChanged;
       }
    }
    View Code

      这里就不连接数据库了,那样代码量太大,也不方便大家查看。这里只做一个简单的验证,至此MVVM中的M和VM就都建好了,下面写前端的显示层,添加两个TextBlock和两个TextBox,两个按钮。用作登录用,分别为用户名,密码,登录和重置。

      下面是绑定代码:

      

    <UserControl x:Class="BookLibrary.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BookViewModel;assembly=BookViewModel"
        mc:Ignorable="d"
        d:DesignHeight="600" d:DesignWidth="1000" 
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
    
       <UserControl.Resources>
          <local:VM_User x:Key="User" />
       </UserControl.Resources>
        <Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Source={StaticResource User}}" Loaded="LayoutRoot_Loaded">
          <telerik:RadBusyIndicator Name="BusyIndicator">
             <Border>
                <Border.Background>
                   <LinearGradientBrush EndPoint="0.5 1" StartPoint="0.5 0">
                      <GradientStop Color="#0369a9" Offset="0" />
                      <GradientStop Color="#046daf" Offset="0.5" />
                      <GradientStop Color="#2fa2e5" Offset="1" />
                   </LinearGradientBrush>
                </Border.Background>
                <Border VerticalAlignment="Center" HorizontalAlignment="Center">
                   <Border.Effect>
                      <DropShadowEffect BlurRadius="10" Opacity="0.4"/>
                   </Border.Effect>
                   <Border.Background>
                      <RadialGradientBrush>
                         <GradientStop Color="#0B7AC1" Offset="0" />
                         <GradientStop Color="#1182c7" Offset="1" />
                      </RadialGradientBrush>
                   </Border.Background>
                   <Grid>
                      <Grid.RowDefinitions>
                         <RowDefinition Height="60"/>
                         <RowDefinition Height="15"/>
                         <RowDefinition Height="45"/>
                         <RowDefinition Height="45"/>
                         <RowDefinition Height="60"/>
                      </Grid.RowDefinitions>
                      <Grid.ColumnDefinitions>
                         <ColumnDefinition Width="185"/>
                         <ColumnDefinition Width="90"/>
                         <ColumnDefinition Width="160"/>
                         <ColumnDefinition Width="100"/>
                      </Grid.ColumnDefinitions>
                      <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" 
                                 Grid.Row="0" Grid.Column="0" Margin="20,0,0,0" FontWeight="Bold"   
                                 Text="School System |" FontSize="16" Foreground="White"/>
                      <TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" 
                                 VerticalAlignment="Center" Text="User Login" FontSize="14"
                                 Foreground="#b4e6ec"/>
                      <Image Source="Images/LoginPicture.png" Grid.Row="1" Grid.Column="0" Grid.RowSpan="3" />
                      <TextBlock FontSize="14" Grid.Row="2" Grid.Column="1" Text="UserName:" 
                                 Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" />
                      <TextBlock FontSize="14" Grid.Row="3" Grid.Column="1" Text="PassWord:" 
                                 Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" />
                      <TextBox Name="txtName"  Text="{Binding user.UserName,Mode=TwoWay}" HorizontalAlignment="Left" FontSize="14" Grid.Row="2" Grid.Column="2" Width="150" Height="26" />
                      <PasswordBox Password="{Binding user.PassWord,Mode=TwoWay}" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="2" Width="150" Height="26" />
                      <Button Command="{Binding Login}" CommandParameter="{Binding}" HorizontalAlignment="Left" Width="80" Height="26" Grid.Row="2" Grid.Column="3" Content="Login" Click="Button_Click_1" />
                      <Button Command="{Binding Reset}" CommandParameter="{Binding}" HorizontalAlignment="Left" Width="80" Height="26" Grid.Row="3" Grid.Column="3" Content="Reset" Click="Button_Click" />
                      <CheckBox HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,10,0,0" Grid.Row="4" Grid.Column="2" Content="Save State" Foreground="White" />
    
                   </Grid>
                </Border>
             </Border>
          </telerik:RadBusyIndicator>
    
       </Grid>
    </UserControl>

      这个时候,就实现登录和重置功能了,但是重置的时候用户名文本框并不会获得焦点,下面我们来讲实现方法:

      第一种方法:TargetedTriggerAction绑定

      先写一个类,叫做TextBoxGetFocusBahavior,代码如下:

      

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Interactivity;
    
    namespace BookLibrary
    {
       public class TextBoxGetFocusBahavior:TargetedTriggerAction<TextBox>
       {
          public void GotFocusAction()
          {
    
          }
          protected override void Invoke(object parameter)
          {
             TextBox targetTextBox = Target;
             targetTextBox.SelectAll();
          }
       }
    }
    View Code

      然后在前台绑定,绑定方法如下:

      

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    <TextBox Height="23" Name="textBox" HorizontalAlignment="Left" Margin="36,28,0,0" VerticalAlignment="Top" Width="198"> <i:Interaction.Triggers> <i:EventTrigger EventName="GotFocus"> <local:TextBoxGetFocusBahavior TargetName="textBox" /> </i:EventTrigger> </i:Interaction.Triggers> </TextBox>

      注意我标红的地方,就是要引入命名空间。

      第二种方法Behavior方法,和上面基本一样,不过我感觉这种方法比较灵活,推荐使用这种方法。新加一个类,AutoSetFocusBehavior,代码如下:

      

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Interactivity;
    
    namespace BookLibrary
    {
       public class AutoSetFocusBehavior:Behavior<TextBox>
       {
          protected override void OnAttached()
          {
             base.OnAttached();
             AssociatedObject.TextChanged += OnTextChanged;
          }
    
          public void OnTextChanged(object sender, EventArgs e)
          {
             if(AssociatedObject.Text.Equals(""))
                AssociatedObject.Focus();
          }
       }
    }
    View Code

      这里前端绑定方法为:

      

     <TextBox Text="{Binding user.UserName}" x:Name="txtName" Height="27" HorizontalAlignment="Left" Margin="36,76,0,0" VerticalAlignment="Top" Width="332">
             <i:Interaction.Behaviors>
                <local:AutoSetFocusBehavior />
             </i:Interaction.Behaviors>
          </TextBox>

      注意,同样要引入上面的命名空间。

      其实,说了这么多,就是给TextBox加了个OnTextChanged事件,当内容被清空时,判断内容是否为空,为空则设置焦点。

      希望这篇文章能给大家一点帮助。不足之处,还请赐教。

  • 相关阅读:
    五、生产者消费者模型_ThreadLocal
    四、多线程基础-线程池的创建和使用
    spring根据beanName获取bean
    spring容器的功能扩展
    机甲大师S1机器人编程学习,Windows 10 安装Scratch和简单实例学习
    如何建设高可用系统
    详解Condition的await和signal等待/通知机制
    从源码角度彻底理解ReentrantLock(重入锁)
    MySQL 分库分表及其平滑扩容方案
    机甲大师S1机器人编程学习
  • 原文地址:https://www.cnblogs.com/yunfeifei/p/3746280.html
Copyright © 2020-2023  润新知