登录数据绑定
1.首先在LoginViewModel 登录逻辑处理类中,创建登录要绑定属性和命令
public class LoginViewModel : BindableBase, IDialogAware
{public LoginViewModel(){ExecuteCommand = new DelegateCommand<string>(Execure);}public string Title { get; set; } = "ToDo"; //设置窗口标题public event Action<IDialogResult> RequestClose;public DelegateCommand<string> ExecuteCommand { get; private set; }private string account;/// <summary>/// 账户/// </summary>public string Account{get { return account; }set { account = value; RaisePropertyChanged(); }}private string passWord;/// <summary>/// 密码/// </summary>public string PassWord{get { return passWord; }set { passWord = value; RaisePropertyChanged(); }}public bool CanCloseDialog(){return true;}public void OnDialogClosed(){}public void OnDialogOpened(IDialogParameters parameters){}private void Execure(string obj){switch (obj){case "Login":Login();break;case "LoginOut":LoginOut();break;}}void Login(){}void LoginOut(){}
}
2.属性和命令创建完成后,在前端LoginView.xaml 中,需要对登录按钮和输入框进行绑定后台对应的属性以及命令(进行数据绑定)
由于密码文本输入框是 PasswordBox,并且不支持数据绑定。需要创建一个密码附加属性类,通过绑定附加属性类间接的让 PasswordBox 支持数据绑定。
2.1 创建密码框附加属性类(PassWordExtensions)
- 快速创建附加属性模板的命令:在PassWordExtensions 类中输入 propa 回车即可
- 然后就是按需进行修改,如下示例。是为密码框创建一个附加属性的修改。并且在整个附加属性类中,定义完成一些属性后,例如把GetMyProperty修改成GetPassWord。主要目的是对附加属性类里面的 PropertyMetadata 添加一个回调函数,并且在回调函数中进行对逻辑处理。当前定义的回调函数是一个密码框属性变更函数(OnPassWordPropertyChanged)。
public class PassWordExtensions{public static string GetPassWord(DependencyObject obj){return (string)obj.GetValue(PassWordProperty);}public static void SetPassWord(DependencyObject obj, string value){obj.SetValue(PassWordProperty, value);}// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...public static readonly DependencyProperty PassWordProperty =DependencyProperty.RegisterAttached("PassWord", typeof(string), typeof(PassWordExtensions), new PropertyMetadata(string.Empty,OnPassWordPropertyChanged));/// <summary>/// 密码属性变更回调函数/// </summary>/// <param name="sender">依赖对象</param>/// <param name="e">事件接收对象</param>/// <returns></returns>private static void OnPassWordPropertyChanged(DependencyObject sender,DependencyPropertyChangedEventArgs e){var oldPassword= sender as PasswordBox;//取到属性变更的依赖对象string newPassWord=(string)e.NewValue;//获取到密码框的新值if (oldPassword != null && oldPassword.Password != newPassWord){oldPassword.Password = newPassWord;//把新值重新赋给Password}}}
- 密码附加属性类创建完成,还需要创建一个行为类(PassWordBehavior),继承自Behavior。目的是让创建的密码附加属性类和密码文本框之间进行绑定。
- 需要重写2个方法 OnAttached和OnDetaching
/// <summary>/// 行为类/// </summary>public class PassWordBehavior: Behavior<PasswordBox>{protected override void OnAttached(){base.OnAttached();//拿到密码改变事件进行处理AssociatedObject.PasswordChanged += AssociatedObject_PasswordChanged;}private void AssociatedObject_PasswordChanged(object sender, RoutedEventArgs e){//在这个值改变的事件中,处理对应的业务逻辑var passwordBox= sender as PasswordBox;var newPassWord= PassWordExtensions.GetPassWord(passwordBox); //获取到密码的值if(passwordBox!=null && passwordBox.Password!= newPassWord){PassWordExtensions.SetPassWord(passwordBox, passwordBox.Password); //给指定的依懒对象设置新的密码值}}protected override void OnDetaching(){base.OnDetaching();AssociatedObject.PasswordChanged -= AssociatedObject_PasswordChanged; //注销事件}}
2.2 密码输入框 (PasswordBox) 中绑定附加属性类
- 在LoginView.xaml 中,引入附加属性类的命名空间 xmlns:pass="clr-namespace:MyToDo.Extensions"
- 引入附加属性类命名空间后,使用 pass:PassWordExtensions.PassWord 方式进行密码框数据绑定。
- 引入behaviors 命名空间,添加密码行为,把当前密码框跟附加属性类的行为类进行关联。 xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
<PasswordBox Margin="0,10" md:HintAssist.Hint="请输入密码" DockPanel.Dock="Top"pass:PassWordExtensions.PassWord="{Binding PassWord,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"><!--添加密码行为--><i:Interaction.Behaviors><pass:PassWordBehavior/></i:Interaction.Behaviors> </PasswordBox>
- 密码绑定属性的时候,需要添加绑定的类型,Mode="TwoWay",即双向绑定。以及更新属性的时机:UpdateSourceTrigger=PropertyChanged
3. LoginView.xaml 完整示例代码
<UserControl x:Class="MyToDo.Views.Dialog.LoginView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:MyToDo.Views.Dialog"xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"xmlns:prism="http://prismlibrary.com/"xmlns:pass="clr-namespace:MyToDo.Extensions"xmlns:i="http://schemas.microsoft.com/xaml/behaviors"mc:Ignorable="d" Height="350" Width="600"><!--修改外观样式--><prism:Dialog.WindowStyle><Style TargetType="Window"><Setter Property="Width" Value="600"/><Setter Property="Height" Value="350"/><Setter Property="SizeToContent" Value="WidthAndHeight"/> <!--设置当前窗口大小--><Setter Property="ResizeMode" Value="NoResize"/> <!--不允许调整窗口大小--><Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen"/> <!--窗口启动位置--></Style></prism:Dialog.WindowStyle><Grid Background="White"><!--界面分左右两列--><Grid.ColumnDefinitions><ColumnDefinition Width="1.5*"/><ColumnDefinition/></Grid.ColumnDefinitions><Image Source="/Images/login.png" Margin="50"/><DockPanel Grid.Column="1" VerticalAlignment="Center" Margin="15"><TextBlock Text="欢迎使用" FontSize="22" FontWeight="Bold" Margin="0,10" DockPanel.Dock="Top"/><TextBox Margin="0,10" md:HintAssist.Hint="请输入账号" DockPanel.Dock="Top"Text="{Binding Account}"/><PasswordBox Margin="0,10" md:HintAssist.Hint="请输入密码" DockPanel.Dock="Top"pass:PassWordExtensions.PassWord="{Binding PassWord,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"><!--添加密码行为--><i:Interaction.Behaviors><pass:PassWordBehavior/></i:Interaction.Behaviors></PasswordBox><Button Content="登录系统" DockPanel.Dock="Top" Command="{Binding ExecuteCommand}" CommandParameter="Login"/><DockPanel LastChildFill="False" Margin="0,10"><TextBlock Text="注册账户"/><TextBlock Text="忘记密码?" DockPanel.Dock="Right"/></DockPanel></DockPanel></Grid>
</UserControl>