WPF自定义控件开发 - 第二节(NumberUpDown)
本节在前文NumberBox的基础上实现一个带有递增&递减按钮的数字框。
它具有以下功能:
- 可以指定一个数值范围(最小值&最大值)
- 点击按钮/鼠标滚轮可以递增/递减指定的数值
继承WPF的基元控件System.Windows.Controls.Primitives.RangeBase,它提供的一系列属性刚好满足我们的需求。
几点小细节需要注意:
- BooleanToVisibilityConverter 这个值转换器,以前在.NET FRAMEWORK时代我都是自己写的,不知道是需要引用特定的库还是我疏忽了,没发现有现成的。但在WPF CORE我发现有内置的。
- 递增/递减按钮我这里使用RepeatButton。它支持“按住”不放时重复触发Click。
- 按钮上的箭头使用Path绘制,简单的Icon我个人比较喜欢用Path,而不是去网上爬别人的png图。使用Path最大的优势就是便于控制它的颜色。
XAML:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SharpSoft.WPF.Controls">
<BooleanToVisibilityConverter x:Key="b2v"/>
<Style TargetType="local:NumericUpDown">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:NumericUpDown">
<DockPanel>
<UniformGrid Rows="2" Columns="1" DockPanel.Dock="Right" VerticalAlignment="Stretch">
<RepeatButton x:Name="BTNUP" BorderThickness="1" Padding="0" Focusable="False" Interval="{
TemplateBinding ButtonRepeatInterval}" IsEnabled="{
TemplateBinding CanIncrement}">
<Viewbox>
<Path Stroke="{
TemplateBinding Foreground}" Width="12" Height="6" StrokeThickness="1.5" Data="M2,5.333 L6,1.333 L10,5.333"></Path>
</Viewbox>
</RepeatButton>
<RepeatButton x:Name="BTNDOWN" BorderThickness="1" Padding="0" Focusable="False" Interval="{
TemplateBinding ButtonRepeatInterval}" IsEnabled="{
TemplateBinding CanDecrement}">
<Viewbox>
<Path Stroke="{
TemplateBinding Foreground}" Width="12" Height="6" StrokeThickness="1.5" Data="M2,0.666 L6,4.666 L10,0.666"></Path>
</Viewbox>
</RepeatButton>
</UniformGrid>
<local:NumberBox x:Name="TEXT" Focusable="True" FormatString="{
TemplateBinding FormatString}" TextAlignment="{
TemplateBinding TextAlignment}" VerticalContentAlignment="{
TemplateBinding VerticalContentAlignment}"/>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
namespace SharpSoft.WPF.Controls
{
/// <summary>
/// 具有调节按钮的数值框
/// </summary>
[TemplatePart(Name = "BTNUP", Type = typeof(ButtonBase))]
[TemplatePart(Name = "BTNDOWN", Type = typeof(ButtonBase))]
[TemplatePart(Name = "TEXT", Type = typeof(NumberBox))]
public class NumericUpDown : System.Windows.Controls.Primitives.RangeBase
{