WPF开发随笔收录-带递增递减按钮TextBox
一、前言
今天分享一下如何实现带递增递减按钮的TextBox控件
二、正文
1、之前的博客分享了一篇自定义XamlIcon控件的文章,这次就直接在那个项目的基础上实现今天这个自定义控件
2、首先添加两个图标资源,一个增加的按钮,一个减小的按钮,具体过程可以参考我之前写的文章
3、接着新增一个自定义控件,如图所示那个

4、添加后,项目中还会生成一个Themes文件夹,里面还有一个Generic.xaml的文件,这个文件可以用来写控件样式的,里面会自动生成一个最基础的控件样式,而那个NumberTextBox是用来后后台逻辑的

5、先来把控件的样式编写一下,如下,样式具体细节就不在描述,就是在里面添加了两个自定义的XamlIcon控件来作为递增和递减按钮,然后还添加了一个TextBlock来做提示文本
<Style TargetType="{x:Type ctls:NumberTextBox}">
<Setter Property="Cursor" Value="IBeam" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Foreground" Value="#555" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctls:NumberTextBox}">
<Border
Name="Border"
Background="White"
BorderBrush="#AAA"
BorderThickness="1"
CornerRadius="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<ScrollViewer
x:Name="PART_ContentHost"
Margin="6,0,0,0"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
<TextBlock
x:Name="Hint"
Margin="6,0,0,0"
VerticalAlignment="{Binding ElementName=PART_ContentHost, Path=VerticalAlignment}"
Foreground="#c9ccd7"
Text="{TemplateBinding Tag}"
Visibility="Collapsed" />
<Border
Grid.Column="1"
Background="Transparent"
BorderBrush="#eee"
BorderThickness="1,0,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ctls:XamlIcon
x:Name="InButton"
VerticalAlignment="Center"
Cursor="Hand"
Icon="angle_up" />
<Rectangle
Grid.Row="1"
Height="1"
Fill="#eee" />
<ctls:XamlIcon
x:Name="DeButton"
Grid.Row="2"
VerticalAlignment="Center"
Cursor="Hand"
Icon="angle_down" />
</Grid>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter TargetName="Hint" Property="Visibility" Value="{x:Static Visibility.Visible}" />
</Trigger>
<Trigger Property="Text" Value="">
<Setter TargetName="Hint" Property="Visibility" Value="{x:Static Visibility.Visible}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
6、接着就是编写后台部分代码,后台部分代码也比较简单,这里简单的添加了两个依赖属性,一个是递进值,一个是最小值。然后就是在OnApplyTemplate的重载中去给样式那里添加的两个控件添加鼠标点击事件。就先这样基础的实现先,复杂的功能后续在增加进去,比如限制只能输入数字之类的,今天主要先介绍实现的大致方法。
public class NumberTextBox : TextBox
{
public int Step
{
get { return (int)GetValue(StepProperty); }
set { SetValue(StepProperty, value); }
} public static readonly DependencyProperty StepProperty =
DependencyProperty.Register("Step", typeof(int), typeof(NumberTextBox), new PropertyMetadata(1)); public int Minimum
{
get { return (int)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum", typeof(int), typeof(NumberTextBox), new PropertyMetadata(0)); static NumberTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumberTextBox), new FrameworkPropertyMetadata(typeof(NumberTextBox)));
} public NumberTextBox()
{
InputMethod.SetIsInputMethodEnabled(this, false);
} public override void OnApplyTemplate()
{
base.OnApplyTemplate();
XamlIcon DeButton = (XamlIcon)this.Template.FindName("DeButton", this);
XamlIcon InButton = (XamlIcon)this.Template.FindName("InButton", this); DeButton.MouseLeftButtonDown += DeButton_MouseLeftButtonDown;
InButton.MouseLeftButtonDown += InButton_MouseLeftButtonDown;
} private void DeButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (!String.IsNullOrEmpty(this.Text))
{
this.Text = int.Parse(this.Text) - Step < Minimum ? Minimum + "" : int.Parse(this.Text) - Step + "";
this.SelectionStart = this.Text.Length;
}
else
{
this.Text = Minimum + "";
this.SelectionStart = this.Text.Length;
}
} private void InButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (!String.IsNullOrEmpty(this.Text))
{
this.Text = int.Parse(this.Text) + Step + "";
this.SelectionStart = this.Text.Length;
}
else
{
this.Text = Minimum + "";
this.SelectionStart = this.Text.Length;
}
}
}
7、测试控件功能,主界面添加自定义好的控件,如下
<Window x:Class="XamlIconDemo.MainWindow"
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:ctls="clr-namespace:XamlIconDemo.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:XamlIconDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ctls:NumberTextBox
Width="200"
Height="40"
FontSize="22"
Minimum="0"
Step="5"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Tag="请输入数字..."/>
</Grid>
</Window>
8、实现效果如下,基础功能已经算实现了,但还不完善,有需要的可以自己完善完善,今天的分享就到这了

WPF开发随笔收录-带递增递减按钮TextBox的更多相关文章
- WPF开发随笔收录-仿安卓Toast
一.前言 在项目中,经常需要用到消息提醒功能,在以前接触安卓开发那会使用过Toast,于是打算在WPF上也来模仿一个,话不多说,撸起袖子干起来! 二.正文 1.首先新建一个工程,工程的目录如下 2.编 ...
- WPF开发随笔收录-ScrollViewer滑块太小解决方案
一.前言 在WPF开发过程中,ScrollViewer是一个很常使用到的控件,在自己工作的项目中,收到一个反馈就是当ScrollViewer里面的内容太长时,滚动条的滑块就会变得很小,然后导致点击起来 ...
- WPF开发随笔收录-DrawingVisual绘制高性能曲线图
一.前言 项目中涉及到了心率监测,而且数据量达到了百万级别,通过WPF实现大数据曲线图时,尝试过最基础的Canvas来实现,但是性能堪忧,而且全部画出来也不实际.同时也尝试过找第三方的开源库,但是因为 ...
- WPF开发随笔收录-唯一标识符GUID
一.前言 该系列博客用于记录本人在WPF开发过程中遇到的各种知识点 二.正文 1.在工作的项目中,软件需要用到在线升级功能,由于第一次弄,在下载服务端的文件到本地时,文件的名称我选择直接生成为固定的格 ...
- WPF开发随笔收录-心电图曲线绘制
一.前言 项目中之前涉及到胎儿心率图曲线的绘制,最近项目中还需要添加心电曲线和血样曲线的绘制功能.今天就来分享一下心电曲线的绘制方式: 二.正文 1.胎儿心率曲线的绘制是通过DrawingVisual ...
- WPF开发随笔收录-获取软件当前目录的坑
一.唠唠叨叨 软件开发过程中,经常需要使用到获取exe当前目录这个功能,前同事在实现这个需求时使用的是Directory.GetCurrentDirectory()这个方法,但再最近的测试中,突然发现 ...
- WPF开发随笔收录-DataAnnotations实现数据校验(MVVM架构下)
一.前言 在自己的项目中挺多地方需要涉及到数据验证的,初期的实现方式都是通过点击确定后再逐个验证数据是否符合要求,但这种方式会让后台代码变得很多很乱.于是就开始在网上需求好的解决方式,刚好看到了一个大 ...
- WPF开发随笔收录-报警闪烁效果实现
一.前言 工作中目前经手的项目是医疗相关的监护软件,所以会涉及到一些报警效果的实现,今天在这里就简单分享一下实现方式 二.正文 1.实现的方式比较的简单,就是通过一个Border控件,然后搭配Data ...
- WPF开发随笔收录-本地日志LogUtil类
一.前言 生活中的日志是记录你生活的点点滴滴,让它把你内心的世界表露出来,更好的诠释自己的内心世界.而在开发者眼中的日志是我们排除问题的第一手资料,项目中的程序上线之后,一旦发生异常,第一件事就是先去 ...
随机推荐
- Solon 1.6.36 发布,更现代感的应用开发框架
相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...
- gin框架使用【4.请求参数】
GET url: http://127.0.0.1:8080/users?id=1&name=卷毛狒狒 package mainimport ( "github.com/gin-go ...
- mongodb 数据块的迁移流程介绍
1. 基本概念 1.1 Chunk(数据块) 表示特定服务器上面,连续范围的分片键值所包含的一组数据,是一个逻辑概念. 例如,某数据块记录如下: { "_id" : "c ...
- springboot:使用异步注解@Async的前世今生
在前边的文章中,和小伙伴一起认识了异步执行的好处,以及如何进行异步开发,对,就是使用@Async注解,在使用异步注解@Async的过程中也存在一些坑,不过通过正确的打开方式也可以很好的避免,今天想和大 ...
- Windows平台安装SQLite3数据库
Windows平台安装SQLite3数据库 话不多说,开始! 访问SQLite官网下载资源 在搜索引擎中键入SQLite3关键字寻找官网入口或直接点击此处前往SQLite官网,官网界面如下: 点击页面 ...
- 关于Spring-JDBC测试类的简单封装
关于Spring-JDBC测试类的简单封装 1.简单封装 /** * Created with IntelliJ IDEA. * * @Author: Suhai * @Date: 2022/04/0 ...
- C++基础-1-内存管理(全局区、堆区、栈区)
1. 内存管理 1.1 全局区 1 #include<iostream> 2 using namespace std; 3 4 // 全局变量 5 int g_a = 10; 6 int ...
- 忽略https域名校验不通过
curl curl 报错: curl: (51) Unable to communicate securely with peer: requested domain name does not ma ...
- python之模块(os、sys、json、subprocess)
目录 os模块 sys模块 json模块 subprocess模块 os模块 os模块主要是与操作系统打交道. 导入os模块 import os 创建单层文件夹,路径必须要存在 os.mkdir(路径 ...
- Fail2ban 配置详解 动作配置
### # 包含配置 ### [INCLUDES] before = iptables-common.conf ### # 定义动作 ### [Definition] actionstart = &l ...