WPF开发登录窗口之——添加文本输入框用户控件

1f62f28b48bc16f35499959238b591f1.png

WPF开发者QQ群: 340500857  | 微信群  目前人数太多,暂不开放

7a5c3816564e8c3f45e727981fa24ec3.png 

窗口开发完成后,接下来就是开发客户区中的输入框控件,但在开发之前,我们先开发一个输入框基类,然后通过继承的方式去实现文本输入框与密码输入框。

01

代码如下

一、添加类在“CustomControl”文件夹中添加“InputBoxBase.cs”,继承自“UserControl”:

sing System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
public class InputBoxBase : UserControl
{}

二、由于输入框基类无法直接将属性应用至控件对象上,所以需要使用抽象方法让派生类去实现为控件应用属性。一共需要三个方法:

与此同时,类也需要添加“abstract”修饰符。

/// <summary>应用文本</summary>
protected abstract void ApplyText();/// <summary>应用占位文本</summary>
protected abstract void ApplyPlaceHolder();/// <summary>应用图标</summary>
protected abstract void ApplyIcon(BitmapImage icon);

三、添加依赖项属我设计的输入框需要三个依赖项属性:文本、占位文本、图标。使用Visual Studio自带的代码片段功能,在编辑器中输入“propdp”后按两次“Tab”键可快速完成依赖项属性的添加。
添加文本依赖项属性:
在属性变更时,获取输入框对象,并应用文本。

public string Text
{get => (string)GetValue(TextProperty);set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty TextProperty =DependencyProperty.Register("Text", typeof(string), typeof(InputBoxBase), new PropertyMetadata("", OnTextChanged));
private static void OnTextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{InputBoxBase control = sender as InputBoxBase;control.ApplyText();
}

四、添加占位文本依赖项属性文本依赖项属性同理:

public string PlaceHolder
{get => (string)GetValue(PlaceHolderProperty);set => SetValue(PlaceHolderProperty, value);
}
public static readonly DependencyProperty PlaceHolderProperty =DependencyProperty.Register("PlaceHolder", typeof(string), typeof(InputBoxBase), new PropertyMetadata("", OnPlaceHolderChanged));
private static void OnPlaceHolderChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{InputBoxBase control = sender as InputBoxBase;control.ApplyPlaceHolder();
}

五、添加图标依赖项属性,如果路径为空,应用空图标;图标加载异常,也应用空图标:

public string Icon
{get => (string)GetValue(IconProperty);set => SetValue(IconProperty, value);
}
public static readonly DependencyProperty IconProperty =DependencyProperty.Register("Icon", typeof(string), typeof(InputBoxBase), new PropertyMetadata("", OnIconChanged));
private static void OnIconChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{InputBoxBase control = sender as InputBoxBase;if (control.Icon == "") control.ApplyIcon(null);else{try{control.ApplyIcon(new BitmapImage(new Uri("pack://application:,,,/" + control.Icon)));}catch (Exception ex){Console.WriteLine(ex.Message);control.ApplyIcon(null);}}
}

六、添加样式在开发控件之前,先要添加一个控件中用到的样式。

在“TextBoxStyle.xaml”中添加以下样式:

<Style x:Key="TextBoxStyle" TargetType="TextBox"><!-- 选中底色 --><Setter Property="SelectionBrush" Value="#4370F5"/><!-- 选中底色透明度 --><Setter Property="SelectionOpacity" Value="1"/><!-- 选中文本色 --><Setter Property="SelectionTextBrush" Value="White"/><!-- 文本色 --><Setter Property="Foreground" Value="Black"/><!-- 文本垂直居中 --><Setter Property="VerticalContentAlignment" Value="Center"/><!-- 模板 --><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="TextBox"><!-- 外观 --><Border x:Name="border" BorderBrush="#D9D9D9" BorderThickness="1" Background="Transparent"><ScrollViewer x:Name="PART_ContentHost" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/></Border><!-- 触发器 --><ControlTemplate.Triggers><!-- 禁用 --><Trigger Property="IsEnabled" Value="false"><Setter Property="Opacity" TargetName="border" Value="0.4"/></Trigger><!-- 鼠标悬停 --><Trigger Property="IsMouseOver" Value="true"><Setter Property="BorderBrush" TargetName="border" Value="#B4B4B4"/></Trigger><!-- 获取焦点 --><Trigger Property="IsKeyboardFocused" Value="true"><Setter Property="BorderBrush" TargetName="border" Value="#4370F5"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style>

七、创建用户控件在“CustomControl”文件夹中添加一个用户控件,

命名为“TextInputBox”:

3074cb9c0e6e39c71970266baaadbe35.png

打开“TextInputBox.xaml.cs”,修改继承为“InputBoxBase”:

namespace LoginWindow.CustomControl
{public partial class TextInputBox : InputBoxBase{public TextInputBox(){InitializeComponent();}}
}

同时修改“TextInputBox.xaml”的“UserControl”为“local:InputBoxBase”

并设置一个合适的大小:

<local:InputBoxBase x:Class="LoginWindow.CustomControl.TextInputBox"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:LoginWindow.CustomControl"mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="300"><Grid></Grid>
</local:InputBoxBase>

八、实现接口

protected override void ApplyText()
{TextBox01.Text = Text;
}protected override void ApplyPlaceHolder()
{Hint.Text = PlaceHolder;
}protected override void ApplyIcon(BitmapImage icon)
{ImageIcon.Source = icon;
}

九、控件布局

<Grid Background="Transparent"><!-- 提示文本 --><TextBlock x:Name="Hint" Foreground="#3F000000" FontFamily="NSimSun" FontSize="13" VerticalAlignment="Center" Padding="39,0"/><!-- 图标 --><Image x:Name="ImageIcon" HorizontalAlignment="Left" Width="16" VerticalAlignment="Center" Margin="12,0,0,0"/><!-- 文本框 --><TextBox x:Name="TextBox01" Style="{StaticResource TextBoxStyle}" Padding="36,0"/><!-- 清除文本按钮 --><Button x:Name="Clear" Width="40" Height="40" HorizontalAlignment="Right" Visibility="Hidden" Click="Clear_Click" Focusable="False"><Button.Template><ControlTemplate TargetType="Button"><Image Source="Image/Clear.png" Width="40"/></ControlTemplate></Button.Template></Button>
</Grid>

处理文本变更事件
当文本框内容变更时,需要将文本框的文本赋值给“Text”属性,并根据文本内容显示或隐藏占位文本与清除按钮。
为文本框添加事件处理:

<!-- 文本框 -->
<TextBox x:Name="TextBox01" Style="{StaticResource TextBoxStyle}" Padding="36,0" TextChanged="TextBox01_TextChanged"/>

编辑方法

private void TextBox01_TextChanged(object sender, TextChangedEventArgs e)
{Text = TextBox01.Text;// 显示或隐藏“清除按钮”与“占位文本”Clear.Visibility = Text == "" ? Visibility.Hidden : Visibility.Visible;Hint.Visibility = Text == "" ? Visibility.Visible : Visibility.Hidden;
}

最后放置控件

<Grid><StackPanel VerticalAlignment="Top" Margin="40,40,40,0"><!-- 邮箱输入框 --><cc:TextInputBox Height="40" PlaceHolder="邮箱" Icon="Assets/Mail.png"/></StackPanel>
</Grid>

b3eee26fd46577e99ef5ffed45bc310b.gif

后记

在运行过程中,我发现右上角的关闭按钮有些模糊,放大后的效果(左):

1e210de609b3c149280107fe4c683460.png

右侧为理想效果


最终发现是因为窗口中的“SnapsToDevicePixels”属性设置为“True”导致的,但如果直接设置为“False”,又会导致高Dpi下控件之间会产生缝隙。最后的解决方案是为关闭按钮设置了“SnapsToDevicePixels”属性。

源码地址如下

github:https://github.com/yanjinhuagood/WPFDevelopers.git

gitee:https://gitee.com/yanjinhua/WPFDevelopers.git

WPF开发者QQ群: 340500857 

blogs: https://www.cnblogs.com/yanjinhua

Github:https://github.com/yanjinhuagood

出处:https://www.cnblogs.com/yanjinhua

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载请著名作者 出处 https://github.com/yanjinhuagood

245007eddfb9020ecb936fdb79b6c631.png

扫一扫关注我们,

2c2efa17851cc3374636de1ea1ebc64f.gif

更多技能早知道!

3d4db493fbdfaa56a6507048468aae04.gif

点击阅读原文可跳转至源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSTL分割字符 fn:split()

2019独角兽企业重金招聘Python工程师标准>>> <% page language"java" contentType"text/html; charsetUTF-8"%> <% taglib uri"http://java.sun.com/jsp/jstl/core" prefix"c"%> <% taglib uri"http:/…

女友的前男友教我该怎么照顾她......

1 总觉得不太对劲&#xff1f;▼2 这回复真神&#xff01;&#xff08;via.机智得赵老师&#xff09;▼3 奇怪的知识又增加了......▼4 卖茶小妹真的与时俱进...&#xff08;via.外卖小哥金城武&#xff09;▼5 超大容量花露水没见过吧&#xff1f;&#xff01;▼6 别人在…

浅谈.Net异步编程的前世今生----EAP篇

前言在上一篇博文中&#xff0c;我们提到了APM模型实现异步编程的模式&#xff0c;通过使用APM模型&#xff0c;可以简化.Net中编写异步程序的方式&#xff0c;但APM模型本身依然存在一些缺点&#xff0c;如无法得知操作进度&#xff0c;不能取消异步操作等。针对这些缺点&…

CentOS 5 CentOS 6 启动流程及关键步骤

CentOS 5 CentOS 6 启动流程及关键步骤1、加电自检&#xff1a;当打开主机电源时&#xff0c;主机会唤醒cpu&#xff0c;使其运行CMOS中的BIOS&#xff0c;BIOS检查必要的硬件是否存在&#xff08;内存、硬盘等&#xff09;BIOS其实是一个小型系统&#xff0c;可以完成一些像检…

建议给予导师决定硕博士能否毕业的自主权?教育部:将充分采纳!

全世界只有3.14 % 的人关注了爆炸吧知识本文来源&#xff1a;教育部 近日&#xff0c;教育部官网公布了《对十三届全国人大三次会议第9546号建议的答复》。针对人大代表提出的关于完善高校研究生科研成果评价标准的建议&#xff0c;教育部作出回应&#xff0c;并透露了对加强研…

浅谈.Net异步编程的前世今生----APM篇

前言在.Net程序开发过程中&#xff0c;我们经常会遇到如下场景&#xff1a;编写WinForm程序客户端&#xff0c;需要查询数据库获取数据&#xff0c;于是我们根据需求写好了代码后&#xff0c;点击查询&#xff0c;发现界面卡死&#xff0c;无法响应。经过调试&#xff0c;发现查…

浅谈.Net异步编程的前世今生----TPL篇

前言我们在此前已经介绍了APM模型和EAP模型&#xff0c;以及它们的优缺点。在EAP模型中&#xff0c;可以实时得知异步操作的进度&#xff0c;以及支持取消操作。但是组合多个异步操作仍需大量工作&#xff0c;编写大量代码方可完成。因此&#xff0c;在.Net Framework 4.0中&am…

Google:推荐几款好用的Chrome浏览器插件

1、Clear Cache 0.3.3.2 一键清空浏览器缓存数据。 https://chrome.google.com/webstore/detail/clear-cache/cppjkneekbjaeellbfkmgnhonkkjfpdn 2、Pig Toolbox 1.0.6.4 双击关闭页签&#xff0c;鼠标手势&#xff0c;手势动作轮&#xff0c;摇臂&#xff0c;超级拖拽&#xf…

豆瓣8.7!BBC这部成人社会禁片,曝光了行业内不能说的秘密

全世界只有3.14 % 的人关注了爆炸吧知识不知道生活中的你是否也会这样&#xff1f;平时即便不买东西&#xff0c;没事也会打开淘宝看看。但凡遇上双11、618各种促销节&#xff0c;总觉得不买好像就亏了&#xff0c;每每忍不住手痒&#xff0c;交了一堆智商税之后又开始后悔。如…

Lync-用户-电话号码-更新

1. 更新-用户-手机号 2. 服务器-更新-地址簿 3. 客户端-更改-注册表-<只操作一次!> 在命令提示符中输入如下命令&#xff1a; Reg Add HKLM\Software\Policies\Microsoft\Communicator /v GalDownloadInitialDelay /t REG_DWORD /d 0 /f 4. 客户端-删除-用户信息 退出-Ly…

豆瓣评分9分+,6部经典趣味数学纪录片!

全世界只有3.14 % 的人关注了爆炸吧知识数学是研究数量、结构、变化以及空间模型等概念的一门学科。透过抽象化和逻辑推理的使用&#xff0c;由计数、计算、量度和对物体形状及运动的观察中产生。数学家们拓展这些概念&#xff0c;为了公式化新的猜想以及从合适选定的公理及定义…

C# Hook原理及EasyHook简易教程

前言在说C# Hook之前&#xff0c;我们先来说说什么是Hook技术。相信大家都接触过外挂&#xff0c;不管是修改游戏客户端的也好&#xff0c;盗取密码的也罢&#xff0c;它们都是如何实现的呢&#xff1f;实际上&#xff0c;Windows平台是基于事件驱动机制的&#xff0c;整个系统…

squid 服务器的应用

实验名称&#xff1a;squid 服务器的应用 实验目标&#xff1a; 任务一&#xff1a;实现正向代理 任务二&#xff1a;实现透明代理 任务三&#xff1a;实现反向代理 提示1、在启动squid服务程序之前需要先确认Linux主机具有完整的域名&#xff0c;如果没有可以在hosts文件中进行…

有的人走着走着就散了!

1 有的人走着走着就走了上坡路▼2 没有感情的甩绳机器▼3 大男孩们陪小朋友踢球到底谁玩的比较开心▼4 给我妈妈演示一下我在肚子里的时候是怎么踹你的▼5 狗子&#xff1a;谢谢您嘞&#xff0c;我这是耳朵不是抹布&#xff01;▼6 从没想到会在这种情况下和你相遇▼7 所…

官宣 .NET 6 RC (Release Candidate) 2

我们很高兴发布 .NET 6 RC(Release Candidate) 2。它是生产环境中支持的两个“go live”候选版本中的第二个。在过去的几个月里&#xff0c;团队一直专注于质量的改进。这个版本中有很多的新特性&#xff0c;但在接近尾声时我们才会把他们完全整合在一起。该团队目前正在验证端…

SQL Server索引进阶第十篇:索引的内部结构

索引设计是数据库设计中比较重要的一个环节&#xff0c;对数据库的性能其中至关重要的作用&#xff0c;但是索引的设计却又不是那么容易的事情&#xff0c;性能也不是那么轻易就获取到的&#xff0c;很多的技术人员因为不恰当的创建索引&#xff0c;最后使得其效果适得其反&…

JDK安装及java环境配置_JDK安装及Java环境变量配置

2.点击Accept License Agreement&#xff0c;下载适合自己电脑版本的JDK.由于我的电脑是windows10 64位专业版。点击红色下载按钮。保存位置自己决定&#xff0c;只要自己安装时能找到就行。3.找到安装文件&#xff0c;双击。4.下一步&#xff0c;这里会让你选择安装目录。注意…

33张你没看过的酷炫化学动图, 秒懂化学反应原理!

化学的神奇魅力可是不是随便说说的&#xff0c;神奇起来让人叹为观止。下面就让腾远君带领大家看看传说中的37张神图&#xff0c;了解化学之美吧。1 . 硫氰酸汞分解&#xff08;“法老之蛇”&#xff09;原理&#xff1a;硫氰酸汞受热分解&#xff0c;部分产物燃烧。2Hg(SCN)2→…

从编译器层面理解C#中的闭包的这个坑!

前言在公众号上看到一篇文章《正确使用和理解C#中的闭包》&#xff0c;里面提到了闭包的一个坑&#xff1a;当捕获的外部变量为for循环的迭代变量时&#xff0c;C#认为变量i是定义在循环体外的。所以&#xff0c;当添加委托集合的for循环执行完时&#xff0c;i的值已经变为3了&…

C# 使用 HelpProvider 控件调用帮助文件

HelpProvider控件可以将帮助文件(.htm文件或.chm文件)与 Windows 应用程序相关联&#xff0c;为特定对话框或对话框中的特定控件提供区分上下文的帮助&#xff0c;打开帮助文件到特定部分。如目录、索引或搜索功能的主页。如图1 所示为 HelpProvider 控件。图1 HelpProvider…