一、前言

今天分享一下如何实现带递增递减按钮的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的更多相关文章

  1. WPF开发随笔收录-仿安卓Toast

    一.前言 在项目中,经常需要用到消息提醒功能,在以前接触安卓开发那会使用过Toast,于是打算在WPF上也来模仿一个,话不多说,撸起袖子干起来! 二.正文 1.首先新建一个工程,工程的目录如下 2.编 ...

  2. WPF开发随笔收录-ScrollViewer滑块太小解决方案

    一.前言 在WPF开发过程中,ScrollViewer是一个很常使用到的控件,在自己工作的项目中,收到一个反馈就是当ScrollViewer里面的内容太长时,滚动条的滑块就会变得很小,然后导致点击起来 ...

  3. WPF开发随笔收录-DrawingVisual绘制高性能曲线图

    一.前言 项目中涉及到了心率监测,而且数据量达到了百万级别,通过WPF实现大数据曲线图时,尝试过最基础的Canvas来实现,但是性能堪忧,而且全部画出来也不实际.同时也尝试过找第三方的开源库,但是因为 ...

  4. WPF开发随笔收录-唯一标识符GUID

    一.前言 该系列博客用于记录本人在WPF开发过程中遇到的各种知识点 二.正文 1.在工作的项目中,软件需要用到在线升级功能,由于第一次弄,在下载服务端的文件到本地时,文件的名称我选择直接生成为固定的格 ...

  5. WPF开发随笔收录-心电图曲线绘制

    一.前言 项目中之前涉及到胎儿心率图曲线的绘制,最近项目中还需要添加心电曲线和血样曲线的绘制功能.今天就来分享一下心电曲线的绘制方式: 二.正文 1.胎儿心率曲线的绘制是通过DrawingVisual ...

  6. WPF开发随笔收录-获取软件当前目录的坑

    一.唠唠叨叨 软件开发过程中,经常需要使用到获取exe当前目录这个功能,前同事在实现这个需求时使用的是Directory.GetCurrentDirectory()这个方法,但再最近的测试中,突然发现 ...

  7. WPF开发随笔收录-DataAnnotations实现数据校验(MVVM架构下)

    一.前言 在自己的项目中挺多地方需要涉及到数据验证的,初期的实现方式都是通过点击确定后再逐个验证数据是否符合要求,但这种方式会让后台代码变得很多很乱.于是就开始在网上需求好的解决方式,刚好看到了一个大 ...

  8. WPF开发随笔收录-报警闪烁效果实现

    一.前言 工作中目前经手的项目是医疗相关的监护软件,所以会涉及到一些报警效果的实现,今天在这里就简单分享一下实现方式 二.正文 1.实现的方式比较的简单,就是通过一个Border控件,然后搭配Data ...

  9. WPF开发随笔收录-本地日志LogUtil类

    一.前言 生活中的日志是记录你生活的点点滴滴,让它把你内心的世界表露出来,更好的诠释自己的内心世界.而在开发者眼中的日志是我们排除问题的第一手资料,项目中的程序上线之后,一旦发生异常,第一件事就是先去 ...

随机推荐

  1. asp.net core启动源码以及监听,到处理请求响应的过程

    摘要 asp.net core发布至今已经将近6年了,很多人对于这一块还是有些陌生,或者说没接触过:接触过的,对于asp.net core整个启动过程,监听过程,以及请求过程,响应过程也是一知半解,可 ...

  2. go interface{}使用

    先上代码 func In(haystack []interface{}, needle interface{}) (bool, error) { sVal := reflect.ValueOf(hay ...

  3. Element修改弹窗类组件的层级

    前情 Element,一套为开发者.设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库,在项目中我们就使用了它,非常nice 坑位 在使用Element组件的时候,一切都十分顺利,但是在使用弹 ...

  4. 为什么HttpContextAccessor要这么设计?

    前言 周五在群里面有小伙伴问,ASP.NET Core这个HttpContextAccessor为什么改成了这个样子? 在印象中,这已经是第三次遇到有小伙伴问这个问题了,特意来写一篇记录,来回答一下这 ...

  5. netty系列之:netty中的核心解码器json

    目录 简介 java中对json的支持 netty对json的解码 总结 简介 程序和程序之间的数据传输方式有很多,可以通过二进制协议来传输,比较流行的像是thrift协议或者google的proto ...

  6. 4.18-token验证

    在postman编写的每一个叫测试用例,既然收测试用例,那么就会有结果对比 API测试断言tests(判断一个接口测试用例是否成功,或者说是通过,是根据断言的三个条件都成立的情况下得到的结果) 协议状 ...

  7. 初次接触Java感受

    认真开始研究了idea后端开发环境 感触很深,突然觉得自己不能再一天的颓废下去,认真找点事情做一做,毕竟自己还是一张白纸,趁着自己年纪轻轻 经过一周的摸索自己努力了还不够,心里多么渴望自己身边的人能够 ...

  8. 团队Beta5

    队名:观光队 链接 组长博客 作业博客 组员实践情况 王耀鑫 **过去两天完成了哪些任务 ** 文字/口头描述 学习 展示GitHub当日代码/文档签入记录 无 接下来的计划 无 **还剩下哪些任务 ...

  9. ceph日常运维管理

    点击关注上方"开源Linux", 后台回复"读书",有我为您特别筛选书籍资料~ 相关阅读: ceph分布式存储简介 常见问题 nearfull osd(s) o ...

  10. 新鲜出炉:appium2.0+ 单点触控和多点触控新的解决方案

    在 appium2.0 之前,在移动端设备上的触屏操作,单手指触屏和多手指触屏分别是由 TouchAction 类,Multiaction 类实现的. 在 appium2.0 之后,这 2 个方法将会 ...