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呢? ...
随机推荐
- HJ212-2017协议数据采集和接收
1.客户端TCP和UDP的数据发送工具 工具和软件下载页面如下:http://www.zlmcu.com/document/tcp_debug_tools.html 2.服务端数据接收监控软件 IPA ...
- NumPy 数组迭代与合并详解
NumPy 数组迭代 NumPy 数组迭代是访问和处理数组元素的重要方法.它允许您逐个或成组地遍历数组元素. 基本迭代 我们可以使用 Python 的基本 for 循环来迭代 NumPy 数组. 一维 ...
- kubernetes之包管理器Helm
安装helm 安装helm客户端 [machangwei@mcwk8s-master ~]$ curl https://raw.githubusercontent.com/kubernetes/hel ...
- C#的GroupBy方法是如何工作的
前言:先贴结果 GroupBy方法是如何工作的? 一.准备6个待分组的学生对象 class student { public string name;//姓名 public int grade;//年 ...
- go 基数排序
package main import ( "fmt" ) func SelectSortMax(arr []int) int { arrLen := len(arr) if ar ...
- ModelScope初体验
使用环境:windows 11 前置条件:已安装 anaconda 参考文档:环境安装 step1:新建一个 conda 环境,命名为 modelscope conda create -n model ...
- Android 13 - Media框架(17)- OpenMax(五)
关注公众号免费阅读全文,进入音视频开发技术分享群! 这一节最后来了解 OMX_Video.h 以及 OMX_Audio.h 中的内容 1.OMX_Video.h 这里只了解该文件中的 OMX_VIDE ...
- 【web】自定义协议Protocol URL
URL Protocol(自定义协议)可以让web页面调用本地exe程序,这个神奇的功能是怎么实现的呢? URL ProtocolURL Protocol,没错就是标题里所说的自定义协议.这玩意儿大家 ...
- RCTF 2024 WEB wp
RCTF 2024 WEB wp 前言 赛后复现,proxy发现自己真是个呆b... what_is_love 首先拿key1,sql语句处有注入,可以盲注拿key1的值 import request ...
- 机器学习策略篇:详解理解人的表现(Understanding human-level performance)
理解人的表现 人类水平表现这个词在论文里经常随意使用,但现在告诉这个词更准确的定义,特别是使用人类水平表现这个词的定义,可以帮助推动机器学习项目的进展.还记得上个博客中,用过这个词"人类水平 ...