Simple WPF: WPF自定义一个可以定义步长的SpinBox
最新内容优先发布于个人博客:小虎技术分享站,随后逐步搬运到博客园。
通过WPF的按钮、文本输入框实现了一个简单的SpinBox数字输入用户组件并可以通过数据绑定数值和步长。本文中介绍了通过Xaml代码实现自定义组件的布局,依赖属性的定义和使用等知识点。
完整代码见Github
组合Xaml组件实现基本的组件功能
SpinBox由一个文本输入框和两个箭头按钮组成,我们在Xaml 代码中先把基本的布局做好。其实可以发现自定义用户控件布局和普通的窗体布局的Xaml代码差不多,只不过Xaml的根标签从Window变成了UserControl 。
<UserControl x:Class="SpinBox.MySpinBox"
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:SpinBox"
mc:Ignorable="d"
d:DesignHeight="36" d:DesignWidth="92">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="txtBoxValue" Grid.Column="0"
TextAlignment="Center" VerticalContentAlignment="Center"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="5*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" x:Name="btnPlus">▲</Button>
<Button Grid.Row="1" x:Name="btnMinor">▼</Button>
</Grid>
</Grid>
</UserControl>

增加依赖属性
因为我们是WPF中制作的用户组件,因此希望输入的数值、步长的配置等可以在Xaml中实现。因此我们需要给我们新建的用户组件增加依赖属性。这里我们直接通过依赖属性值变化的回调函数来实现文本框信息的更新。
/// <summary>
/// SpinBox.xaml 的交互逻辑
/// </summary>
[ContentProperty("Value")]
public partial class MySpinBox : UserControl
{
/// <summary>
/// DepedencyProperty for Step
/// </summary>
public static readonly DependencyProperty StepProperty
= DependencyProperty.Register("Step", typeof(double),
typeof(MySpinBox), new PropertyMetadata(1.0));
/// <summary>
/// DepedencyProperty for Value
/// </summary>
public static readonly DependencyProperty ValueProperty
= DependencyProperty.Register("Value", typeof(double),
typeof(MySpinBox), new FrameworkPropertyMetadata(0.0,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
| FrameworkPropertyMetadataOptions.Journal
| FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnValueChanged))
);
public double Value
{
get => (double)GetValue(ValueProperty);
set
{
if (Value != value)
{
SetValue(ValueProperty, value);
}
}
}
public double Step
{
get => (double)GetValue(StepProperty);
set
{
if (Step != value)
{
SetValue(StepProperty, value);
}
}
}
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var spinBox = d as MySpinBox;
if (spinBox != null)
{
spinBox.txtBoxValue.Text = e.NewValue.ToString();
}
}
}
接下来我们在MainWindow.xaml中增加刚刚编写好的MySpinBox组件
<Window x:Class="SpinBox.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SpinBox"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:MySpinBox MaxHeight="64" MaxWidth="128" Step="2" Value="5"/>
</Grid>
</Window>

增加事件处理
我们在自定义组件中增加按钮组件的响应
<Button Grid.Row="0" x:Name="btnPlus" Click="btnPlus_Click">▲</Button>
<Button Grid.Row="1" x:Name="btnMinor" Click="btnMinor_Click">▼</Button>
在C#代码中增加对应的响应逻辑就能实现完整的效果
private void btnPlus_Click(object sender, RoutedEventArgs e)
{
Value += Step;
}
private void btnMinor_Click(object sender, RoutedEventArgs e)
{
Value -= Step;
}
最后需要说明下的是按钮的Unicode值得十六进制表示分别是0x25B2 和0x25BC 。Xaml本质是一种XML文本,因此在其中表示Unicode要使用XML对应的语法格式。
最终效果

Simple WPF: WPF自定义一个可以定义步长的SpinBox的更多相关文章
- [WPF 自定义控件]自定义一个“传统”的 Validation.ErrorTemplate
1. 什么是Validaion.ErrorTemplate 数据绑定模型允许您将与您Binding的对象相关联ValidationRules. 如果用户输入的值无效,你可能希望在应用程序 用户界面 ( ...
- 【WPF】自定义一个自删除的多功能ListBox
原文地址 https://www.cnblogs.com/younShieh/p/17008534.html 如果本文对你有所帮助,不妨点个关注和推荐呀,这是对笔者最大的支持~ 我需要一个ListBo ...
- WPF整理-自定义一个扩展标记(custom markup extension)
"Markup extensions are used to extend the capabilities of XAML, by providing declarativeoperati ...
- WPF 如何自定义一个弹框
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 简述: 手工以原生Grid的方式,自定义了一个仿弹窗效果,优点可以自定义,缺点需要自己实现以及维护整个弹窗的效 ...
- 在WPF中自定义你的绘制(五)
原文:在WPF中自定义你的绘制(五) 在WPF中自定义你的绘制(五) ...
- 在WPF中自定义你的绘制(四)
原文:在WPF中自定义你的绘制(四) 在WPF中自定义你的绘制(四) ...
- 在WPF中自定义你的绘制(二)
原文:在WPF中自定义你的绘制(二) 在WPF中自定义你的绘制(二) ...
- WPF绘制自定义窗口
原文:WPF绘制自定义窗口 WPF是制作界面的一大利器,下面就用WPF模拟一下360的软件管理界面,360软件管理界面如下: 界面不难,主要有如下几个要素: 窗体的圆角 自定义标题栏及按钮 自定义状态 ...
- WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探
原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探 最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...
- WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性
原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...
随机推荐
- uniapp关于uni.getUserProfile的使用
点击查看代码 <button @click="getMy" data-eventsync="true">获取信息</button> le ...
- C#的关于窗体的类库方案 - 开源研究系列文章
这次想到了以前编写的关于应用的那个类库,不过当时的只是定义了显示接口,然后调用窗体显示.现在想到要把这个关于窗体的类库进行集合,统一调用,于是就把原来的代码进行了修改完善,终于得到了这次这个例子. 这 ...
- 组合数学:Burnside引理和Polya定理解决染色置换问题
例题 给3x3的格子上色,4种颜色,可以重复.排除旋转后相同的情况,请问有多少种不同的上色方法? 解答 设格子编号如下: | 1 | 2 | 3 | | 4 | 5 | 6 | | 7 | 8 | 9 ...
- sqlserver 把 某一列的所有值 变成 in 里面的内容
SELECT STUFF(( SELECT ','+'''' +convert(VARCHAR, cDefine3)+'''' from rdrecord08 where dDate>'20 ...
- 阿里巴巴 MySQL 数据库之 SQL 语句规约 (三)
SQL 语句规约 强制部分 [强制] 不要使用 count(列名) 或 count(常量) 来替代 count(*),count(*) 是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NU ...
- Chart.js (v2.9.4) 2-主要的函数和对象介绍
Color() :主要负责渲染图表时候,针对颜色处理相关函数 helpers_core:工具对象,提供了基础的工具函数功能,遍历数组,扩展对象,合并对象,克隆对象等等. core_defaults:负 ...
- .netz 压缩 打包 成单EXE
https://github.com/madebits/msnet-netz-compressor https://madebits.github.io/#r/msnet-netz-compresso ...
- centos os7 和redhat 7 安装yum源失败的解决办法
首先看我的报错 [Errno 14] curl#6 - "Could not resolve host: mirrors.aliyun.com; Unknown error" yu ...
- P7959 [COCI2014-2015#6] WTF 题解
P7959 [COCI2014-2015#6] WTF 题解 呃,是一道 DP 题 说实话,原题实际上是不要输出一种方法的--但是似乎放这道题的人想增加一点难度? 这里有两种做法,但都是 DP. 预备 ...
- LeetCode 37. Sudoku Solver II 解数独 (C++/Java)
题目: Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must sati ...