在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(""))
{
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;
}
}

  这里就不连接数据库了,那样代码量太大,也不方便大家查看。这里只做一个简单的验证,至此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="" d:DesignWidth=""
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="" />
<GradientStop Color="#046daf" Offset="0.5" />
<GradientStop Color="#2fa2e5" Offset="" />
</LinearGradientBrush>
</Border.Background>
<Border VerticalAlignment="Center" HorizontalAlignment="Center">
<Border.Effect>
<DropShadowEffect BlurRadius="" Opacity="0.4"/>
</Border.Effect>
<Border.Background>
<RadialGradientBrush>
<GradientStop Color="#0B7AC1" Offset="" />
<GradientStop Color="#1182c7" Offset="" />
</RadialGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=""/>
<RowDefinition Height=""/>
<RowDefinition Height=""/>
<RowDefinition Height=""/>
<RowDefinition Height=""/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=""/>
<ColumnDefinition Width=""/>
<ColumnDefinition Width=""/>
<ColumnDefinition Width=""/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left"
Grid.Row="" Grid.Column="" Margin="20,0,0,0" FontWeight="Bold"
Text="School System |" FontSize="" Foreground="White"/>
<TextBlock Grid.Row="" Grid.Column="" HorizontalAlignment="Left"
VerticalAlignment="Center" Text="User Login" FontSize=""
Foreground="#b4e6ec"/>
<Image Source="Images/LoginPicture.png" Grid.Row="" Grid.Column="" Grid.RowSpan="" />
<TextBlock FontSize="" Grid.Row="" Grid.Column="" Text="UserName:"
Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBlock FontSize="" Grid.Row="" Grid.Column="" Text="PassWord:"
Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBox Name="txtName" Text="{Binding user.UserName,Mode=TwoWay}" HorizontalAlignment="Left" FontSize="" Grid.Row="" Grid.Column="" Width="" Height="" />
<PasswordBox Password="{Binding user.PassWord,Mode=TwoWay}" HorizontalAlignment="Left" Grid.Row="" Grid.Column="" Width="" Height="" />
<Button Command="{Binding Login}" CommandParameter="{Binding}" HorizontalAlignment="Left" Width="" Height="" Grid.Row="" Grid.Column="" Content="Login" Click="Button_Click_1" />
<Button Command="{Binding Reset}" CommandParameter="{Binding}" HorizontalAlignment="Left" Width="" Height="" Grid.Row="" Grid.Column="" Content="Reset" Click="Button_Click" />
<CheckBox HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,10,0,0" Grid.Row="" Grid.Column="" 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();
}
}
}

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

  

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<TextBox Height="" Name="textBox" HorizontalAlignment="Left" Margin="36,28,0,0" VerticalAlignment="Top" Width="">
<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();
}
}
}

  这里前端绑定方法为:

  

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

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

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

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

silverlighter下MVVM模式中利用Behavior和TargetedTriggerAction实现文本框的一些特效的更多相关文章

  1. [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦

    [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...

  2. Messenger在MVVM模式中的应用

    Messenger在MVVM模式中的应用 Messenger在MVVM中应用的前提 我们知道在MVVM架构中,系统平台的Silverlight客户端界面开发和业务逻辑已经被分开,XAML是SL的主要部 ...

  3. 在MVVM模式中,按钮Click事件的绑定方法

    在MVVM模式中,我们将Button的方法写到ViewModel中,然后绑定到前端界面.通常的做法是写一个类,继承ICommand接口,然而如果按钮比较多的话,就需要写很多的类,对于后期维护造成很大的 ...

  4. “Win10 UAP 开发系列”之 在MVVM模式中控制ListView滚动位置

    这个扩展属性从WP8.1就开始用了,主要是为了解决MVVM模式中无法直接控制ListView滚动位置的问题.比如在VM中刷新了数据,需要将View中的ListView滚动到顶部,ListView只有一 ...

  5. WPF MVVM模式中,通过命令实现窗体拖动、跳转以及显隐控制

    原文:WPF MVVM模式中,通过命令实现窗体拖动.跳转以及显隐控制 在WPF中使用MVVM模式,可以让我们的程序实现界面与功能的分离,方便开发,易于维护.但是,很多初学者会在使用MVVM的过程中遇到 ...

  6. WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参

    原文:WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参 ContextMenu无论定义在.cs或.xaml文件中,都不继承父级的DataC ...

  7. js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符

    js中对arry数组的各种操作小结   最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...

  8. Jquery获取下拉选择节点名称值赋给textbox文本框 获取 父节点的栏目名称编号

    <label for="parentNode" style="float:left" >父级栏目:</label> <select ...

  9. HTML中让表单input等文本框为只读不可编辑但可以获取value值的方法;让文本域前面的内容显示在左上角,居中

      HTML中让表单input等文本框为只读不可编辑的方法 有时候,我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如使input text的内容,中国两个字不可以修改   有时候,我们希望 ...

随机推荐

  1. [python] os.path说明

    os.path - Common pathname manipulations操作 This module implements some useful functions on pathnames. ...

  2. OpenCV linux cmake添加使用

    安装好opencv之后: 只需要添加一下,就可以方便的使用opencv了,find_package opencv 会寻找FindOpenCV.cmake find_package(OpenCV REQ ...

  3. Thinkphp去掉index.php

    1.httpd.conf配置文件中 #LoadModule rewrite_module modules/mod_rewrite.so 把前面的警号去掉2.AllowOverride None 将No ...

  4. centos 如何清理/dev/vda1系统盘

    df-h检查一台服务器磁盘使用空间,发现磁盘已经使用了100% 思路是: 1.cd /usr 2.du -sh * 看哪个目录占用空间大 3.重复前两步,根据实际情况删除或者移走 4.日志的话可以运行 ...

  5. python ImportError: DLL load failed: %1 不是有效的 Win32 应用程序

    导入的时候报出了 ImportError 在windows上安装python 的模块后,导入模块时报 python ImportError: DLL load failed: %1 不是有效的 Win ...

  6. MVC 单元测试

    1.新建mvc项目 添加controller 添加action 或者方法 public ActionResult Index(string str) { ViewBag.Teststr = str; ...

  7. java连接Oracle数据库

    Oracle数据库先创建一个表和添加一些数据 1.先在Oracle数据库中创建一个student表: create table student ( id ) not null primary key, ...

  8. 用栈解决Largest Rectangle问题

    一问题描述 Given n non-negative integers representing the histogram's bar height where the width of each ...

  9. 开发框架Data Abstract和Hydra发布版本Winter 2013

    Data Abstract Winter 2013即Data Abstract Version 7.0.73 (Build .1111),Winter 2013版对Data Abstract继续做了以 ...

  10. UE4动作流程总结

    右键新窗口打开看大图