如何实现WPF登陆界面的记住账号密码及水印功能 您所在的位置:网站首页 web账号密码登陆记住密码界面代码 如何实现WPF登陆界面的记住账号密码及水印功能

如何实现WPF登陆界面的记住账号密码及水印功能

2024-02-15 00:00| 来源: 网络整理| 查看: 265

在这里插入图片描述 刚开始学编程。学了三个月了,学的C#和.net(貌似有点坑),公司应该是让做b/s,socket和数据库比较难,暂时不怎么会,对WPF花的时间比较多一些(毕竟可视化效果看起来比价有成就感)(WPF的课程案例貌似不多,加油) 新手菜鸟,大神轻喷。我觉得几个有趣的地方,左上角的【HIM是画的,因为这样缩放清晰度一样,刺激。

图片那个是把一个TabControl控件翻转了180°

好了,接下来看如何记住账号密码功能。主要是两个文本框,一个是textbox,另一个是passwordbox,还有一个记住密码的勾选框

记住密码

可以将控件的值保存在窗口中,但是这样做之后缺乏灵活性,会将应用程序数据与UI界面混在一起,并不是一种好的设计。我们应该新建一个类,并将用户所做的选择保存在其中。 (1)新建一个类,将其命名为SaveOptions (2)我们要记住CheckBox,TextBox,PasswordBox的值,输入以下代码

using System; namespace DataEntity { [Serializable] public class SaveOptions { private bool _SaveUser = false; public bool SaveUser { get { }; set { }; } private string _SaveLoginID; public string SaveLoginID { get { }; set { }; } private string _SaveLoginPSW; public string SaveLoginPSW { get { }; set { }; } } }

(3)返回代码隐藏文件(我的是 登陆.xaml.cs),添加一个private字段来保存saveOptions实例;并在构造函数中添加以下代码。

using System.Windows; using System.IO; using System.Xml.Serialization; namespace CfyDWS { /// /// 登录.xaml 的交互逻辑 /// public partial class LoginWindow : Window { private SaveOptions saveOptions; public LoginWindow() { if (saveOptions == null) { //确定指定的文件是否存在 if (File.Exists("SaveOptions.xml")) { using (var stream = File.OpenRead("SaveOptions.xml")) { var serializer = new XmlSerializer(typeof(SaveOptions)); saveOptions = serializer.Deserialize(stream) as SaveOptions; } } else saveOptions = new SaveOptions(); } InitializeComponent(); } }

接下来创建动态绑定 (4)在InitializeComponent();这一行之前加上一下代码:

DataContext = saveOptions;

(5)转到SaveOptions类,对其进行修改

using System; using System.ComponentModel; namespace DataEntity { [Serializable] public class SaveOptions : INotifyPropertyChanged { private bool _SaveUser = false; public bool SaveUser { get { return _SaveUser; } set { _SaveUser = value; OnPropertyChanged(nameof(SaveUser)); } } private string _SaveLoginID; public string SaveLoginID { get { return _SaveLoginID; } set { _SaveLoginID = value; OnPropertyChanged(nameof(SaveLoginID)); } } private string _SaveLoginPSW; public string SaveLoginPSW { get { return _SaveLoginPSW; } set { _SaveLoginPSW = value; OnPropertyChanged(nameof(SaveLoginPSW)); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }

(6)返回登陆.xaml文件,选择CheckBox,然后添加IsChenk属性,如下所示:

IsChecked="{Binding Path=SaveUser}"

(7)同理绑定TextBoX控件的Text属性

Text="{Binding Path=SaveLoginID}"

(8)绑定PasswordBox的Password属性时会出现一个错误,PasswordBox的Password属性不是依赖项属性,无法绑定。 其原因是,出于安全考虑,对密码进行数据库不是一个很好的设计,因此应该避免。但是有时这种安全性是不必要的,那么不能绑定到Password属性就很麻烦了。在这种特殊情况下,您可以利用以下PasswordBoxHelper。代码如下

http://www.wpftutorial.net/PasswordBox.html

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; namespace CfyDWS { public static class PasswordBoxHelper { //通过调用PasswordHelper.Attach财产。附加财产PasswordHelper.Password提供PasswordBox控件的原始密码属性的可绑定副本。 public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordBoxHelper), new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged)); public static readonly DependencyProperty AttachProperty = DependencyProperty.RegisterAttached("Attach", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, Attach)); private static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), typeof(PasswordBoxHelper)); public static void SetAttach(DependencyObject dp, bool value) { dp.SetValue(AttachProperty, value); } public static bool GetAttach(DependencyObject dp) { return (bool)dp.GetValue(AttachProperty); } public static string GetPassword(DependencyObject dp) { return (string)dp.GetValue(PasswordProperty); } public static void SetPassword(DependencyObject dp, string value) { dp.SetValue(PasswordProperty, value); } private static bool GetIsUpdating(DependencyObject dp) { return (bool)dp.GetValue(IsUpdatingProperty); } private static void SetIsUpdating(DependencyObject dp, bool value) { dp.SetValue(IsUpdatingProperty, value); } private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; passwordBox.PasswordChanged -= PasswordChanged; if (!(bool)GetIsUpdating(passwordBox)) { passwordBox.Password = (string)e.NewValue; } passwordBox.PasswordChanged += PasswordChanged; } private static void Attach(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; if (passwordBox == null) return; if ((bool)e.OldValue) { passwordBox.PasswordChanged -= PasswordChanged; } if ((bool)e.NewValue) { passwordBox.PasswordChanged += PasswordChanged; } } private static void PasswordChanged(object sender, RoutedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; SetIsUpdating(passwordBox, true); SetPassword(passwordBox, passwordBox.Password); SetIsUpdating(passwordBox, false); } } }

查看登陆.xaml窗口,看到有名称空间CfyDWS的引用,没有的话自己手动添加,要引用CfyDWS名称空间下的PasswordBoxHelper类的方法。

然后修改PasswordBox的属性

这里说下看到的另一个方法,用TextBox替换PasswordBox,然后用TextDecorations属性画小黑点装饰TextBox,这种感觉窗口大小最好固定吧。而且小圆点的大小不好把握,也可能是我这里学的差。

https://blog.csdn.net/SANYUNI/article/details/52775898

(9)我把保存选项放在登陆按钮上了 这里我是当按下确定时 1.1 账号密码错误,未勾选记住密码 清空账号密码 1.2 账号密码错误,勾选记住密码 账号密码保存 1.3 账号密码正确,未勾选记住密码 清空账号密码,登录进入主窗口 1.4 账号密码正确,勾选记住密码 账号密码保存,登录进入主窗口 关于如何确定账号密码正确与如何进入主界面,参考引用如下

WPF 登陆界面判断输入的用户名和密码是否与数据库中保存的数据相同

https://blog.csdn.net/u010637394/article/details/43833139?utm_source=blogxgwz5

WPF:验证登录后关闭登录窗口,显示主窗口的解决方法

https://blog.csdn.net/Jacee0048/article/details/49952643?utm_source=blogxgwz3

这里主要看using()的那一段代码段,将using代码段写进一个void方法里

private void btn_login_Click(object sender, RoutedEventArgs e) { SqlConnectionStringBuilder connbuilder = new SqlConnectionStringBuilder(); connbuilder.DataSource = Environment.MachineName; //获取服务器名称,本机为Cheng-PC(data ource数据源,一般为机器名称或IP地址) connbuilder.IntegratedSecurity = true; //登录方式,true为 Windows 身份验证 connbuilder.InitialCatalog = "昌恒DWS系统"; //数据库名(Initial Catalog数据库或SQL Server实例的名称(与Database一样)) SqlConnection conn = new SqlConnection(connbuilder.ConnectionString); //创建一个SqlConnecting对象并且初始化连接字符串 conn.Open(); //打开数据库连接 string a = string.Format("select * from 账户管理 where login_ID='{0}' and login_PSW='{1}' ", txt_UserName.Text, txt_PSW.Password); //定义要执行的SQL语句(本处是查询语句) SqlCommand comm = new SqlCommand(a, conn); //创建SqlCommand的实例对象(string a表示要查询的文本,SqlConnecting conn表示到SQL Server实例的连接) SqlDataReader dr = comm.ExecuteReader(); //ExecuteReader(),读取数据,生成一个SqlDataReader对象并返回 if (txt_UserName.Text == "" || txt_PSW.Password == "") //判断输入是否为空 { MessageBox.Show("请填写用户名和密码"); SaveOptionsXml(); } else { if (dr.Read())//判断是否存在用户输入的用户名和密码 { MessageBox.Show("登陆成功"); // 显示主窗口; this.DialogResult = Convert.ToBoolean(1); SaveOptionsXml(); conn.Close(); //关闭数据库连接 this.Close(); } else { MessageBox.Show("用户名或密码有误"); SaveOptionsXml(); conn.Close(); //关闭数据库连接 } } private void SaveOptionsXml() { using (var stream = File.Open("SaveOptions.xml", FileMode.Create)) { if (LoginIDMemory.IsChecked == false) { saveOptions.SaveLoginID = ""; saveOptions.SaveLoginPSW = ""; } var serializer = new XmlSerializer(typeof(SaveOptions)); serializer.Serialize(stream, saveOptions); } } }

(10)查了半天实现了PasswordBox的水印功能(用的模板和样式)。参考如下

https://www.cnblogs.com/OhMonkey/p/6057076.html

然后查TextBox的水印功能,感觉很麻烦,试过把账号登录框TextBox换成PasswordBox,这样用一个模板样式就可以了。但是发现TextBox换成PasswordBox会问题,账号框输入的文本会显示为小圆点。后面找了半天还是换成TextBox了。 上面网页样式的TextBox样式前面缺了一个缺一段键名TxbBase的样式,补上去就可以直接用了

https://blog.csdn.net/c0411034/article/details/82467916

Style x:Key="TxbBase" TargetType="TextBox">

(11)新建一个PasswordBoxHelper类,代码如下(接口可以删掉或保留,我用的vs2017)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; namespace CfyDWS { public static class PasswordBoxHelper { //通过调用PasswordHelper.Attach财产。附加财产PasswordHelper.Password提供PasswordBox控件的原始密码属性的可绑定副本。 public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordBoxHelper), new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged)); public static readonly DependencyProperty AttachProperty = DependencyProperty.RegisterAttached("Attach", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, Attach)); private static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), typeof(PasswordBoxHelper)); public static void SetAttach(DependencyObject dp, bool value) { dp.SetValue(AttachProperty, value); } public static bool GetAttach(DependencyObject dp) { return (bool)dp.GetValue(AttachProperty); } public static string GetPassword(DependencyObject dp) { return (string)dp.GetValue(PasswordProperty); } public static void SetPassword(DependencyObject dp, string value) { dp.SetValue(PasswordProperty, value); } private static bool GetIsUpdating(DependencyObject dp) { return (bool)dp.GetValue(IsUpdatingProperty); } private static void SetIsUpdating(DependencyObject dp, bool value) { dp.SetValue(IsUpdatingProperty, value); } private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; passwordBox.PasswordChanged -= PasswordChanged; if (!(bool)GetIsUpdating(passwordBox)) { passwordBox.Password = (string)e.NewValue; } passwordBox.PasswordChanged += PasswordChanged; } private static void Attach(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; if (passwordBox == null) return; if ((bool)e.OldValue) { passwordBox.PasswordChanged -= PasswordChanged; } if ((bool)e.NewValue) { passwordBox.PasswordChanged += PasswordChanged; } } private static void PasswordChanged(object sender, RoutedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; SetIsUpdating(passwordBox, true); SetPassword(passwordBox, passwordBox.Password); SetIsUpdating(passwordBox, false); } } }

(12)PasswordBox的样式如下: 与参考的区别主要是

命名空间name我的是local,参考是Core样式触发器有所不同

用参考里面的这里会出现一个问题,就是我选择了记住账号密码,然后登陆退出,重新打开程序,会发现记住的账号密码和水印都存在。 应换成如下代码,(看(9)中的using代码块)因为我没有选择记住账号密码的话,账号密码文本框内容会清空。账号密码框文本为空的时候出现水印才合理。

完成代码如下

(13)TextBox样式如下: 文本框的颜色我设的黑色,水印设置为红色

(14)TextBox和PasswordBox空间完整代码如下:

效果如图

在这里插入图片描述 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有