WPF控件NumericUpDown-自定义微调控件

时间:2022-10-18 15:26:35

XAML代码: 

<UserControl

    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"

    mc:Ignorable="d"

    x:Class="Sample.NumericControl"

    x:Name="UserControl"

    Width="200" Height="23" MaxHeight="23" MinHeight="23" MinWidth="50" xmlns:Sample="clr-namespace:Sample">

    <UserControl.Resources>

        <Sample:DoubleValueConverter x:Key="MyValueConverter"/>

        <Style x:Key="ArrowButtonStyle" BasedOn="{x:Null}" TargetType="{x:Type Button}">

            <Setter Property="Template">

                <Setter.Value>

                    <ControlTemplate TargetType="{x:Type Button}">

                        <Grid>

                            <Rectangle Stroke="#FFA0A0A0" d:LayoutOverrides="GridBox" RadiusX="1"RadiusY="1" Width="20" Height="8">

                                <Rectangle.Fill>

                                    <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">

                                        <GradientStop Color="#FFDCDCDC" Offset="0"/>

                                        <GradientStop Color="#FFDCDCDC" Offset="0.991"/>

                                        <GradientStop Color="#FFC8C8C8" Offset="0.496"/>

                                        <GradientStop Color="#FFDCDCDC" Offset="0.549"/>

                                    </LinearGradientBrush>

                                </Rectangle.Fill>

                            </Rectangle>

                            <Path Fill="#FF5A5A5A" Margin="7,2,7,2" Stretch="Fill" Stroke="{x:Null}" Data="M135.66667,4.6666667 L132.16599,9.4999781 139.16621,9.4999778 z" Width="5"Height="4" HorizontalAlignment="Center" VerticalAlignment="Center"/>

                        </Grid>

                        <ControlTemplate.Triggers>

                            <Trigger Property="IsFocused" Value="True"/>

                            <Trigger Property="IsDefaulted" Value="True"/>

                            <Trigger Property="IsMouseOver" Value="True"/>

                            <Trigger Property="IsPressed" Value="True"/>

                            <Trigger Property="IsEnabled" Value="False"/>

                        </ControlTemplate.Triggers>

                    </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>

    </UserControl.Resources>

 

    <Grid x:Name="LayoutRoot">

        <Border x:Name="ControlBorder" CornerRadius="2,2,2,2" BorderThickness="1,1,1,1"BorderBrush="#FFA0A0A0" Background="#FFFFFFFF">

            <Grid x:Name="ValueGrid" Width="Auto">

                <Grid.ColumnDefinitions>

                    <ColumnDefinition/>

                    <ColumnDefinition Width="26"/>

                </Grid.ColumnDefinitions>

                <TextBox Grid.Column="0" BorderBrush="{x:Null}" BorderThickness="0,0,0,0"Margin="2,2,2,2" VerticalContentAlignment="Center" x:Name="ValueText"LostFocus="ValueText_LostFocus" Text="{Binding Path=Value, Converter={StaticResourceMyValueConverter}, ElementName=UserControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,FallbackValue=0}"/>

                <Button HorizontalAlignment="Right" Style="{DynamicResource ArrowButtonStyle}"Width="20" x:Name="UpButton" Grid.Column="1" Margin="0,2,3,0" Click="UpButton_Click" Height="8"VerticalAlignment="Top" />

                <Button HorizontalAlignment="Right" Style="{DynamicResource ArrowButtonStyle}"VerticalAlignment="Bottom" Width="20" Height="8" RenderTransformOrigin="0.5,0.5"x:Name="DownButton" Grid.Column="1" Margin="0,0,3,2" Click="DownButton_Click">

                    <Button.RenderTransform>

                        <TransformGroup>

                            <ScaleTransform ScaleX="1" ScaleY="-1"/>

                            <SkewTransform AngleX="0" AngleY="0"/>

                            <RotateTransform Angle="0"/>

                            <TranslateTransform X="0" Y="0"/>

                        </TransformGroup>

                    </Button.RenderTransform>

                </Button>

            </Grid>

        </Border>

    </Grid>

</UserControl>

 

后台代码: 

using System;

using System.IO;

using System.Net;

using System.ComponentModel;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Navigation;

 

namespace Sample

{

    public partial class NumericControl : INotifyPropertyChanged

    {

        private double numericValue = 0;

 

        public NumericControl()

        {

            this.InitializeComponent();

        }

 

        public double Value

        {

            get { return numericValue; }

            set

            {

                numericValue = value;

                NotifyPropertyChanged("Value");

            }

        }

        public double Increment { getset; }

        public double MaxValue { getset; }

        public double MinValue { getset; }

 

        private void UpButton_Click(object sender, RoutedEventArgs e)

        {

            double newValue = (Value + Increment);

            if (newValue > MaxValue)

            {

                Value = MaxValue;

            }

            else

            {

                Value = newValue;

            }

        }

 

        private void DownButton_Click(object sender, RoutedEventArgs e)

        {

            double newValue = (Value - Increment);

            if (newValue < MinValue)

            {

                Value = MinValue;

            }

            else

            {

                Value = newValue;

            }

        }

 

        private void ValueText_LostFocus(object sender, RoutedEventArgs e)

        {

            try

            {

                Value = double.Parse(ValueText.Text);

            }

            catch (Exception)

            {

                Value = 0;

            }

        }

 

 

        #region INotifyPropertyChanged Members

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        public void NotifyPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));

            }

        }

 

        #endregion

    }

 

    [ValueConversion(typeof(double), typeof(string))]

    public class DoubleValueConverter : IValueConverter

    {

        #region IValueConverter Members

 

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            try

            {

                return value.ToString();

            }

            catch (Exception)

            {

                return "0";

            }

        }

 

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            try

            {

                return double.Parse((string)value);

            }

            catch (Exception)

            {

                return 0;

            }

        }

 

        #endregion

    }

}

 

要点:

1.  灵活使用布局控件是良好设计的关键。

2.  尽量使用设计器来完成大部分XMAL代码。

3.  这里的Value属性是double型的。

4.  用属性MaxValueMinValueIncrement来控制最大值、最小值和增量。

5.  实现InotifyPropertyChanged接口,这样当属性Value的值改变时,能够通知与之绑定的ValueText控件。这样做的目的是实现数据的双向绑定。

6.  实现一个IvalueConverter接口的类DoubleValueConverter,用于为数据绑定进行格式转换。

7.  对错误的输入进行适当处理。

 

转载自网易博客:http://blog.163.com/tianshi_17th/blog/static/48564189200917337274/