欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于WPF實(shí)現(xiàn)數(shù)字框控件

 更新時間:2023年08月10日 09:21:30   作者:WPF開發(fā)者  
這篇文章主要介紹了如何利用WPF實(shí)現(xiàn)數(shù)字框控件,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定的幫助,需要的小伙伴可以參考一下

WPF 實(shí)現(xiàn)數(shù)字框控件

框架使用.NET4 至 .NET6;

Visual Studio 2022;

實(shí)現(xiàn)代碼

1)新增 NumericBox.cs 代碼如下:

OnPreviewKeyDown 方法:

  • 處理 Enter 鍵:調(diào)用 DealInputText 方法處理輸入文本,選擇所有文本,并標(biāo)記事件為已處理。
  • 處理向上箭頭鍵:調(diào)用 ContinueChangeValue 方法增加 NumericBox 值,并標(biāo)記事件為已處理。
  • 處理向下箭頭鍵:調(diào)用 ContinueChangeValue 方法減少 NumericBox 值,并標(biāo)記事件為已處理。

OnPreviewKeyUp 方法:

處理釋放的向上箭頭鍵或向下箭頭鍵:調(diào)用 ResetInternal 方法重置 NumericBox 內(nèi)部狀態(tài)。

嘗試將輸入的文本轉(zhuǎn)換為 double 類型的數(shù)值。

如果轉(zhuǎn)換成功:

檢查轉(zhuǎn)換后的值與當(dāng)前值是否非常接近,如果是,則不做任何操作。

否則,根據(jù)轉(zhuǎn)換后的值和最大值、最小值進(jìn)行比較:

如果大于最大值,則將值設(shè)置為最大值。

如果小于最小值,則將值設(shè)置為最小值。

否則,將值設(shè)置為轉(zhuǎn)換后的值。

如果轉(zhuǎn)換失敗,則將當(dāng)前值設(shè)置回文本框。

Precision 可輸入多少小數(shù)位。

using?System;
using?System.Collections.Generic;
using?System.ComponentModel;
using?System.Diagnostics;
using?System.Linq;
using?System.Runtime.InteropServices;
using?System.Text;
using?System.Windows.Controls.Primitives;
using?System.Windows.Input;
using?System.Windows;
using?System.Xml.Linq;
using?WPFDevelopers.Utilities;
using?System.Windows.Controls;
using?WPFDevelopers.Datas;
namespace?WPFDevelopers.Controls
{
????[DefaultEvent("ValueChanged"),?DefaultProperty("Value")]
????[TemplatePart(Name?=?TextBoxTemplateName,?Type?=?typeof(TextBox))]
????[TemplatePart(Name?=?NumericUpTemplateName,?Type?=?typeof(RepeatButton))]
????[TemplatePart(Name?=?NumericDownTemplateName,?Type?=?typeof(RepeatButton))]
????public?class?NumericBox?:?Control
????{
????????private?static?readonly?Type?_typeofSelf?=?typeof(NumericBox);
????????private?const?double?DefaultInterval?=?1d;
????????private?const?int?DefaultDelay?=?500;
????????private?const?string?TextBoxTemplateName?=?"PART_TextBox";
????????private?const?string?NumericUpTemplateName?=?"PART_NumericUp";
????????private?const?string?NumericDownTemplateName?=?"PART_NumericDown";
????????private?static?RoutedCommand?_increaseCommand?=?null;
????????private?static?RoutedCommand?_decreaseCommand?=?null;
????????private?TextBox?_valueTextBox;
????????private?RepeatButton?_repeatUp;
????????private?RepeatButton?_repeatDown;
????????private?double?_internalLargeChange?=?DefaultInterval;
????????private?double?_intervalValueSinceReset?=?0;
????????private?double??_lastOldValue?=?null;
????????private?bool?_isManual;
????????private?bool?_isBusy;
????????static?NumericBox()
????????{
????????????InitializeCommands();
????????????DefaultStyleKeyProperty.OverrideMetadata(_typeofSelf,?new?FrameworkPropertyMetadata(_typeofSelf));
????????}
????????#region?Command
????????private?static?void?InitializeCommands()
????????{
????????????_increaseCommand?=?new?RoutedCommand("Increase",?_typeofSelf);
????????????_decreaseCommand?=?new?RoutedCommand("Decrease",?_typeofSelf);
????????????CommandManager.RegisterClassCommandBinding(_typeofSelf,?new?CommandBinding(_increaseCommand,?OnIncreaseCommand,?OnCanIncreaseCommand));
????????????CommandManager.RegisterClassCommandBinding(_typeofSelf,?new?CommandBinding(_decreaseCommand,?OnDecreaseCommand,?OnCanDecreaseCommand));
????????}
????????public?static?RoutedCommand?IncreaseCommand
????????{
????????????get?{?return?_increaseCommand;?}
????????}
????????public?static?RoutedCommand?DecreaseCommand
????????{
????????????get?{?return?_decreaseCommand;?}
????????}
????????private?static?void?OnIncreaseCommand(object?sender,?RoutedEventArgs?e)
????????{
????????????var?numericBox?=?sender?as?NumericBox;
????????????numericBox.ContinueChangeValue(true);
????????}
????????private?static?void?OnCanIncreaseCommand(object?sender,?CanExecuteRoutedEventArgs?e)
????????{
????????????var?numericBox?=?sender?as?NumericBox;
????????????e.CanExecute?=?(!numericBox.IsReadOnly?&&?numericBox.IsEnabled?&&?DoubleUtil.LessThan(numericBox.Value,?numericBox.Maximum));
????????}
????????private?static?void?OnDecreaseCommand(object?sender,?RoutedEventArgs?e)
????????{
????????????var?numericBox?=?sender?as?NumericBox;
????????????numericBox.ContinueChangeValue(false);
????????}
????????private?static?void?OnCanDecreaseCommand(object?sender,?CanExecuteRoutedEventArgs?e)
????????{
????????????var?numericBox?=?sender?as?NumericBox;
????????????e.CanExecute?=?(!numericBox.IsReadOnly?&&?numericBox.IsEnabled?&&?DoubleUtil.GreaterThan(numericBox.Value,?numericBox.Minimum));
????????}
????????#endregion
????????#region?RouteEvent
????????public?static?readonly?RoutedEvent?ValueChangedEvent?=?EventManager.RegisterRoutedEvent("ValueChanged",?RoutingStrategy.Bubble,?typeof(RoutedPropertyChangedEventHandler<double>),?_typeofSelf);
????????public?event?RoutedPropertyChangedEventHandler<double>?ValueChanged
????????{
????????????add?{?AddHandler(ValueChangedEvent,?value);?}
????????????remove?{?RemoveHandler(ValueChangedEvent,?value);?}
????????}
????????#endregion
????????#region?Properties
????????public?static?readonly?DependencyProperty?DisabledValueChangedWhileBusyProperty?=?DependencyProperty.Register("DisabledValueChangedWhileBusy",?typeof(bool),?_typeofSelf,
???????????new?PropertyMetadata(false));
????????[Category("Common")]
????????[DefaultValue(true)]
????????public?bool?DisabledValueChangedWhileBusy
????????{
????????????get?{?return?(bool)GetValue(DisabledValueChangedWhileBusyProperty);?}
????????????set?{?SetValue(DisabledValueChangedWhileBusyProperty,?value);?}
????????}
????????public?static?readonly?DependencyProperty?IntervalProperty?=?DependencyProperty.Register("Interval",?typeof(double),?_typeofSelf,
???????????new?FrameworkPropertyMetadata(DefaultInterval,?IntervalChanged,?CoerceInterval));
????????[Category("Behavior")]
????????[DefaultValue(DefaultInterval)]
????????public?double?Interval
????????{
????????????get?{?return?(double)GetValue(IntervalProperty);?}
????????????set?{?SetValue(IntervalProperty,?value);?}
????????}
????????private?static?object?CoerceInterval(DependencyObject?d,?object?value)
????????{
????????????var?interval?=?(double)value;
????????????return?DoubleUtil.IsNaN(interval)???0?:?Math.Max(interval,?0);
????????}
????????private?static?void?IntervalChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????var?numericBox?=?(NumericBox)d;
????????????numericBox.ResetInternal();
????????}
????????public?static?readonly?DependencyProperty?SpeedupProperty?=?DependencyProperty.Register("Speedup",?typeof(bool),?_typeofSelf,
???????????new?PropertyMetadata(true));
????????[Category("Common")]
????????[DefaultValue(true)]
????????public?bool?Speedup
????????{
????????????get?{?return?(bool)GetValue(SpeedupProperty);?}
????????????set?{?SetValue(SpeedupProperty,?value);?}
????????}
????????public?static?readonly?DependencyProperty?DelayProperty?=?DependencyProperty.Register("Delay",?typeof(int),?_typeofSelf,
????????????new?PropertyMetadata(DefaultDelay,?null,?CoerceDelay));
????????[DefaultValue(DefaultDelay)]
????????[Category("Behavior")]
????????public?int?Delay
????????{
????????????get?{?return?(int)GetValue(DelayProperty);?}
????????????set?{?SetValue(DelayProperty,?value);?}
????????}
????????private?static?object?CoerceDelay(DependencyObject?d,?object?value)
????????{
????????????var?delay?=?(int)value;
????????????return?Math.Max(delay,?0);
????????}
????????public?static?readonly?DependencyProperty?UpDownButtonsWidthProperty?=?DependencyProperty.Register("UpDownButtonsWidth",?typeof(double),?_typeofSelf,
???????????new?PropertyMetadata(20d));
????????[Category("Appearance")]
????????[DefaultValue(20d)]
????????public?double?UpDownButtonsWidth
????????{
????????????get?{?return?(double)GetValue(UpDownButtonsWidthProperty);?}
????????????set?{?SetValue(UpDownButtonsWidthProperty,?value);?}
????????}
????????public?static?readonly?DependencyProperty?TextAlignmentProperty?=?TextBox.TextAlignmentProperty.AddOwner(_typeofSelf);
????????[Category("Common")]
????????public?TextAlignment?TextAlignment
????????{
????????????get?{?return?(TextAlignment)GetValue(TextAlignmentProperty);?}
????????????set?{?SetValue(TextAlignmentProperty,?value);?}
????????}
????????public?static?readonly?DependencyProperty?IsReadOnlyProperty?=?TextBoxBase.IsReadOnlyProperty.AddOwner(_typeofSelf,
????????????new?FrameworkPropertyMetadata(false,?FrameworkPropertyMetadataOptions.Inherits,?IsReadOnlyPropertyChangedCallback));
????????[Category("Appearance")]
????????public?bool?IsReadOnly
????????{
????????????get?{?return?(bool)GetValue(IsReadOnlyProperty);?}
????????????set?{?SetValue(IsReadOnlyProperty,?value);?}
????????}
????????private?static?void?IsReadOnlyPropertyChangedCallback(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????if?(e.OldValue?==?e.NewValue?||?e.NewValue?==?null)
????????????????return;
????????????((NumericBox)d).ToggleReadOnlyMode((bool)e.NewValue);
????????}
????????public?static?readonly?DependencyProperty?PrecisionProperty?=?DependencyProperty.Register("Precision",?typeof(int?),?_typeofSelf,
????????????new?PropertyMetadata(null,?OnPrecisionChanged,?CoercePrecision));
????????[Category("Common")]
????????public?int??Precision
????????{
????????????get?{?return?(int?)GetValue(PrecisionProperty);?}
????????????set?{?SetValue(PrecisionProperty,?value);?}
????????}
????????private?static?object?CoercePrecision(DependencyObject?d,?object?value)
????????{
????????????var?precision?=?(int?)value;
????????????return?(precision.HasValue?&&?precision.Value?<?0)???0?:?precision;
????????}
????????private?static?void?OnPrecisionChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????var?numericBox?=?(NumericBox)d;
????????????var?newPrecision?=?(int?)e.NewValue;
????????????var?roundValue?=?numericBox.CorrectPrecision(newPrecision,?numericBox.Value);
????????????if?(DoubleUtil.AreClose(numericBox.Value,?roundValue))
????????????????numericBox.InternalSetText(roundValue);
????????????else
????????????????numericBox.Value?=?roundValue;
????????}
????????public?static?readonly?DependencyProperty?MinimumProperty?=?DependencyProperty.Register("Minimum",?typeof(double),?_typeofSelf,
????????????new?PropertyMetadata(double.MinValue,?OnMinimumChanged));
????????[Category("Common")]
????????public?double?Minimum
????????{
????????????get?{?return?(double)GetValue(MinimumProperty);?}
????????????set?{?SetValue(MinimumProperty,?value);?}
????????}
????????private?static?void?OnMinimumChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????var?numericBox?=?(NumericBox)d;
????????????numericBox.CoerceValue(MaximumProperty,?numericBox.Maximum);
????????????numericBox.CoerceValue(ValueProperty,?numericBox.Value);
????????}
????????public?static?readonly?DependencyProperty?MaximumProperty?=?DependencyProperty.Register("Maximum",?typeof(double),?_typeofSelf,
????????????new?PropertyMetadata(double.MaxValue,?OnMaximumChanged,?CoerceMaximum));
????????[Category("Common")]
????????public?double?Maximum
????????{
????????????get?{?return?(double)GetValue(MaximumProperty);?}
????????????set?{?SetValue(MaximumProperty,?value);?}
????????}
????????private?static?object?CoerceMaximum(DependencyObject?d,?object?value)
????????{
????????????var?minimum?=?((NumericBox)d).Minimum;
????????????var?val?=?(double)value;
????????????return?DoubleUtil.LessThan(val,?minimum)???minimum?:?val;
????????}
????????private?static?void?OnMaximumChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????var?numericBox?=?(NumericBox)d;
????????????numericBox.CoerceValue(ValueProperty,?numericBox.Value);
????????}
????????public?static?readonly?DependencyProperty?ValueProperty?=?DependencyProperty.Register("Value",?typeof(double),?_typeofSelf,
????????????new?FrameworkPropertyMetadata(0d,?FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,?OnValueChanged,?CoerceValue));
????????[Category("Common")]
????????public?double?Value
????????{
????????????get?{?return?(double)GetValue(ValueProperty);?}
????????????set?{?SetValue(ValueProperty,?value);?}
????????}
????????private?static?object?CoerceValue(DependencyObject?d,?object?value)
????????{
????????????var?numericBox?=?(NumericBox)d;
????????????var?val?=?(double)value;
????????????if?(DoubleUtil.LessThan(val,?numericBox.Minimum))
????????????????return?numericBox.Minimum;
????????????if?(DoubleUtil.GreaterThan(val,?numericBox.Maximum))
????????????????return?numericBox.Maximum;
????????????return?numericBox.CorrectPrecision(numericBox.Precision,?val);
????????}
????????private?static?void?OnValueChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????var?numericBox?=?(NumericBox)d;
????????????numericBox.OnValueChanged((double)e.OldValue,?(double)e.NewValue);
????????}
????????#endregion
????????#region?Virtual
????????protected?virtual?void?OnValueChanged(double?oldValue,?double?newValue)
????????{
????????????InternalSetText(newValue);
????????????InvalidateRequerySuggested(newValue);
????????????if?((!_isBusy?||?!DisabledValueChangedWhileBusy)?&&?!DoubleUtil.AreClose(oldValue,?newValue))
????????????{
????????????????RaiseEvent(new?TextBoxValueChangedEventArgs<double>(oldValue,?newValue,?_isManual,?_isBusy,?ValueChangedEvent));
????????????}
????????????_isManual?=?false;
????????}
????????#endregion
????????#region?Override
????????public?override?void?OnApplyTemplate()
????????{
????????????base.OnApplyTemplate();
????????????UnsubscribeEvents();
????????????_valueTextBox?=?GetTemplateChild(TextBoxTemplateName)?as?TextBox;
????????????_repeatUp?=?GetTemplateChild(NumericUpTemplateName)?as?RepeatButton;
????????????_repeatDown?=?GetTemplateChild(NumericDownTemplateName)?as?RepeatButton;
????????????if?(_valueTextBox?==?null?||?_repeatUp?==?null?||?_repeatDown?==?null)
????????????{
????????????????throw?new?NullReferenceException(string.Format("You?have?missed?to?specify?{0},?{1}?or?{2}?in?your?template",?NumericUpTemplateName,?NumericDownTemplateName,?TextBoxTemplateName));
????????????}
????????????_repeatUp.PreviewMouseUp?+=?OnRepeatButtonPreviewMouseUp;
????????????_repeatDown.PreviewMouseUp?+=?OnRepeatButtonPreviewMouseUp;
????????????ToggleReadOnlyMode(IsReadOnly);
????????????OnValueChanged(Value,?Value);
????????}
????????protected?override?void?OnGotFocus(RoutedEventArgs?e)
????????{
????????????base.OnGotFocus(e);
????????????if?(Focusable?&&?!IsReadOnly)
????????????{
????????????????Focused();
????????????????SelectAll();
????????????}
????????}
????????protected?override?void?OnPreviewMouseWheel(MouseWheelEventArgs?e)
????????{
????????????base.OnPreviewMouseWheel(e);
????????????if?(e.Delta?!=?0?&&?(IsFocused?||?_valueTextBox.IsFocused))
????????????????ContinueChangeValue(e.Delta?>=?0,?false);
????????}
????????protected?override?void?OnPreviewKeyDown(KeyEventArgs?e)
????????{
????????????base.OnPreviewKeyDown(e);
????????????switch?(e.Key)
????????????{
????????????????case?Key.Enter:
????????????????????DealInputText(_valueTextBox.Text);
????????????????????SelectAll();
????????????????????e.Handled?=?true;
????????????????????break;
????????????????case?Key.Up:
????????????????????ContinueChangeValue(true);
????????????????????e.Handled?=?true;
????????????????????break;
????????????????case?Key.Down:
????????????????????ContinueChangeValue(false);
????????????????????e.Handled?=?true;
????????????????????break;
????????????}
????????}
????????protected?override?void?OnPreviewKeyUp(KeyEventArgs?e)
????????{
????????????base.OnPreviewKeyUp(e);
????????????switch?(e.Key)
????????????{
????????????????case?Key.Down:
????????????????case?Key.Up:
????????????????????ResetInternal();
????????????????????break;
????????????}
????????}
????????#endregion
????????#region?Event?
????????private?void?OnRepeatButtonPreviewMouseUp(object?sender,?MouseButtonEventArgs?e)
????????{
????????????ResetInternal();
????????}
????????private?void?OnPreviewMouseLeftButtonDown(object?sender,?MouseButtonEventArgs?e)
????????{
????????????if?(Focusable?&&?!IsReadOnly?&&?!_valueTextBox.IsKeyboardFocusWithin)
????????????{
????????????????e.Handled?=?true;
????????????????Focused();
????????????????SelectAll();
????????????}
????????}
????????private?void?OnTextBoxLostFocus(object?sender,?RoutedEventArgs?e)
????????{
????????????var?tb?=?(TextBox)sender;
????????????DealInputText(tb.Text);
????????}
????????private?void?OnValueTextBoxPaste(object?sender,?DataObjectPastingEventArgs?e)
????????{
????????????var?textBox?=?(TextBox)sender;
????????????var?textPresent?=?textBox.Text;
????????????if?(!e.SourceDataObject.GetDataPresent(DataFormats.Text,?true))
????????????????return;
????????????var?text?=?e.SourceDataObject.GetData(DataFormats.Text)?as?string;
????????????var?newText?=?string.Concat(textPresent.Substring(0,?textBox.SelectionStart),?text,?textPresent.Substring(textBox.SelectionStart?+?textBox.SelectionLength));
????????????double?number;
????????????if?(!double.TryParse(newText,?out?number))
????????????????e.CancelCommand();
????????}
????????#endregion
????????#region?Private
????????private?void?UnsubscribeEvents()
????????{
????????????if?(_valueTextBox?!=?null)
????????????{
????????????????_valueTextBox.LostFocus?-=?OnTextBoxLostFocus;
????????????????_valueTextBox.PreviewMouseLeftButtonDown?-=?OnPreviewMouseLeftButtonDown;
????????????????DataObject.RemovePastingHandler(_valueTextBox,?OnValueTextBoxPaste);
????????????}
????????????if?(_repeatUp?!=?null)
????????????????_repeatUp.PreviewMouseUp?-=?OnRepeatButtonPreviewMouseUp;
????????????if?(_repeatDown?!=?null)
????????????????_repeatDown.PreviewMouseUp?-=?OnRepeatButtonPreviewMouseUp;
????????}
????????private?void?Focused()
????????{
????????????_valueTextBox?.Focus();
????????}
????????private?void?SelectAll()
????????{
????????????_valueTextBox?.SelectAll();
????????}
????????private?void?DealInputText(string?inputText)
????????{
????????????double?convertedValue;
????????????if?(double.TryParse(inputText,?out?convertedValue))
????????????{
????????????????if?(DoubleUtil.AreClose(Value,?convertedValue))
????????????????{
????????????????????InternalSetText(Value);
????????????????????return;
????????????????}
????????????????_isManual?=?true;
????????????????if?(convertedValue?>?Maximum)
????????????????{
????????????????????if?(DoubleUtil.AreClose(Value,?Maximum))
????????????????????????OnValueChanged(Value,?Value);
????????????????????else
????????????????????????Value?=?Maximum;
????????????????}
????????????????else?if?(convertedValue?<?Minimum)
????????????????{
????????????????????if?(DoubleUtil.AreClose(Value,?Minimum))
????????????????????????OnValueChanged(Value,?Value);
????????????????????else
????????????????????????Value?=?Minimum;
????????????????}
????????????????else
????????????????????Value?=?convertedValue;
????????????}
????????????else
????????????????InternalSetText(Value);
????????}
????????private?void?MoveFocus()
????????{
????????????var?request?=?new?TraversalRequest((Keyboard.Modifiers?&?ModifierKeys.Shift)?==?ModifierKeys.Shift???FocusNavigationDirection.Previous?:?FocusNavigationDirection.Next);
????????????var?elementWithFocus?=?Keyboard.FocusedElement?as?UIElement;
????????????elementWithFocus?.MoveFocus(request);
????????}
????????private?void?ToggleReadOnlyMode(bool?isReadOnly)
????????{
????????????if?(_valueTextBox?==?null)
????????????????return;
????????????if?(isReadOnly)
????????????{
????????????????_valueTextBox.LostFocus?-=?OnTextBoxLostFocus;
????????????????_valueTextBox.PreviewMouseLeftButtonDown?-=?OnPreviewMouseLeftButtonDown;
????????????????DataObject.RemovePastingHandler(_valueTextBox,?OnValueTextBoxPaste);
????????????}
????????????else
????????????{
????????????????_valueTextBox.LostFocus?+=?OnTextBoxLostFocus;
????????????????_valueTextBox.PreviewMouseLeftButtonDown?+=?OnPreviewMouseLeftButtonDown;
????????????????DataObject.AddPastingHandler(_valueTextBox,?OnValueTextBoxPaste);
????????????}
????????}
????????private?void?InternalSetText(double?newValue)
????????{
????????????var?text?=?newValue.ToString(GetPrecisionFormat());
????????????if?(_valueTextBox?!=?null?&&?!Equals(text,?_valueTextBox.Text))
????????????????_valueTextBox.Text?=?text;
????????}
????????private?string?GetPrecisionFormat()
????????{
????????????return?Precision.HasValue?==?false
??????????????????"g"
????????????????:?(Precision.Value?==?0
??????????????????????"#0"
????????????????????:?("#0.0"?+?string.Join("",?Enumerable.Repeat("#",?Precision.Value?-?1))));
????????}
????????private?void?CoerceValue(DependencyProperty?dp,?object?localValue)
????????{
????????????SetCurrentValue(dp,?localValue);
????????????CoerceValue(dp);
????????}
????????private?double?CorrectPrecision(int??precision,?double?originValue)
????????{
????????????return?Math.Round(originValue,?precision????0,?MidpointRounding.AwayFromZero);
????????}
????????private?void?ContinueChangeValue(bool?isIncrease,?bool?isContinue?=?true)
????????{
????????????if?(IsReadOnly?||?!IsEnabled)
????????????????return;
????????????if?(isIncrease?&&?DoubleUtil.LessThan(Value,?Maximum))
????????????{
????????????????if?(!_isBusy?&&?isContinue)
????????????????{
????????????????????_isBusy?=?true;
????????????????????if?(DisabledValueChangedWhileBusy)
????????????????????????_lastOldValue?=?Value;
????????????????}
????????????????_isManual?=?true;
????????????????Value?=?(double)CoerceValue(this,?Value?+?CalculateInterval(isContinue));
????????????}
????????????if?(!isIncrease?&&?DoubleUtil.GreaterThan(Value,?Minimum))
????????????{
????????????????if?(!_isBusy?&&?isContinue)
????????????????{
????????????????????_isBusy?=?true;
????????????????????if?(DisabledValueChangedWhileBusy)
????????????????????????_lastOldValue?=?Value;
????????????????}
????????????????_isManual?=?true;
????????????????Value?=?(double)CoerceValue(this,?Value?-?CalculateInterval(isContinue));
????????????}
????????}
????????private?double?CalculateInterval(bool?isContinue?=?true)
????????{
????????????if?(!Speedup?||?!isContinue)
????????????????return?Interval;
????????????if?(DoubleUtil.GreaterThan((_intervalValueSinceReset?+=?_internalLargeChange),?_internalLargeChange?*?100))
????????????????_internalLargeChange?*=?10;
????????????return?_internalLargeChange;
????????}
????????private?void?ResetInternal()
????????{
????????????_internalLargeChange?=?Interval;
????????????_intervalValueSinceReset?=?0;
????????????_isBusy?=?false;
????????????if?(_lastOldValue.HasValue)
????????????{
????????????????_isManual?=?true;
????????????????OnValueChanged(_lastOldValue.Value,?Value);
????????????????_lastOldValue?=?null;
????????????}
????????}
????????private?void?InvalidateRequerySuggested(double?value)
????????{
????????????if?(_repeatUp?==?null?||?_repeatDown?==?null)
????????????????return;
????????????if?(DoubleUtil.AreClose(value,?Maximum)?&&?_repeatUp.IsEnabled
???????????????||?DoubleUtil.AreClose(value,?Minimum)?&&?_repeatDown.IsEnabled)
????????????????CommandManager.InvalidateRequerySuggested();
????????????else
????????????{
????????????????if?(!_repeatUp.IsEnabled?||?!_repeatDown.IsEnabled)
????????????????????CommandManager.InvalidateRequerySuggested();
????????????}
????????}
????????#endregion
????}
}

2)新增 NumericBox.xaml 代碼如下:

  • 上下按鈕部分使用了一個垂直的 Grid,其中包含三個行定義。第一行是上按鈕,第二行是一個高度為 1 的占位行,第三行是下按鈕。
  • 上按鈕和下按鈕都是 RepeatButton 類型,并分別命名為 PART_NumericUp 和 PART_NumericDown。它們分別與 controls:NumericBox.IncreaseCommand 和 controls:NumericBox.DecreaseCommand 命令關(guān)聯(lián)。
  • 樣式的觸發(fā)器部分定義了一個觸發(fā)條件,當(dāng) UpDownButtonsWidth 屬性的值為 0 時,將隱藏上下按鈕。
<ResourceDictionary
????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????xmlns:controls="clr-namespace:WPFDevelopers.Controls">
????<ResourceDictionary.MergedDictionaries>
????????<ResourceDictionary?Source="Basic/ControlBasic.xaml"?/>
????</ResourceDictionary.MergedDictionaries>
????<Style
????????x:Key="WD.NumericBox"
????????BasedOn="{StaticResource?WD.ControlBasicStyle}"
????????TargetType="{x:Type?controls:NumericBox}">
????????<Setter?Property="ScrollViewer.HorizontalScrollBarVisibility"?Value="Disabled"?/>
????????<Setter?Property="ScrollViewer.VerticalScrollBarVisibility"?Value="Disabled"?/>
????????<Setter?Property="BorderThickness"?Value="1"?/>
????????<Setter?Property="BorderBrush"?Value="{DynamicResource?WD.BaseSolidColorBrush}"?/>
????????<Setter?Property="Background"?Value="{DynamicResource?WD.BackgroundSolidColorBrush}"?/>
????????<Setter?Property="HorizontalContentAlignment"?Value="Stretch"?/>
????????<Setter?Property="VerticalContentAlignment"?Value="Center"?/>
????????<Setter?Property="FocusVisualStyle"?Value="{x:Null}"?/>
????????<Setter?Property="Padding"?Value="{StaticResource?WD.DefaultPadding}"?/>
????????<Setter?Property="Template">
????????????<Setter.Value>
????????????????<ControlTemplate?TargetType="{x:Type?controls:NumericBox}">
????????????????????<controls:SmallPanel?Width="{TemplateBinding?Width}"?Height="{TemplateBinding?Height}">
????????????????????????<Border
????????????????????????????x:Name="PART_Border"
????????????????????????????Background="{TemplateBinding?Background}"
????????????????????????????BorderBrush="{TemplateBinding?BorderBrush}"
????????????????????????????BorderThickness="{TemplateBinding?BorderThickness}"
????????????????????????????CornerRadius="{Binding?Path=(helpers:ElementHelper.CornerRadius),?RelativeSource={RelativeSource?TemplatedParent}}"
????????????????????????????SnapsToDevicePixels="{TemplateBinding?SnapsToDevicePixels}">
????????????????????????????<Grid>
????????????????????????????????<Grid.ColumnDefinitions>
????????????????????????????????????<ColumnDefinition?/>
????????????????????????????????????<ColumnDefinition?Width="Auto"?/>
????????????????????????????????</Grid.ColumnDefinitions>
????????????????????????????????<TextBox
????????????????????????????????????x:Name="PART_TextBox"
????????????????????????????????????MinHeight="{TemplateBinding?MinHeight}"
????????????????????????????????????Padding="{TemplateBinding?Padding}"
????????????????????????????????????HorizontalAlignment="Stretch"
????????????????????????????????????VerticalAlignment="Center"
????????????????????????????????????HorizontalContentAlignment="{TemplateBinding?HorizontalContentAlignment}"
????????????????????????????????????VerticalContentAlignment="{TemplateBinding?VerticalContentAlignment}"
????????????????????????????????????Background="{x:Null}"
????????????????????????????????????BorderThickness="0"
????????????????????????????????????FocusVisualStyle="{x:Null}"
????????????????????????????????????Focusable="{TemplateBinding?Focusable}"
????????????????????????????????????FontFamily="{TemplateBinding?FontFamily}"
????????????????????????????????????FontSize="{TemplateBinding?FontSize}"
????????????????????????????????????Foreground="{TemplateBinding?Foreground}"
????????????????????????????????????HorizontalScrollBarVisibility="{TemplateBinding?ScrollViewer.HorizontalScrollBarVisibility}"
????????????????????????????????????InputMethod.IsInputMethodEnabled="False"
????????????????????????????????????IsReadOnly="{TemplateBinding?IsReadOnly}"
????????????????????????????????????IsTabStop="{TemplateBinding?IsTabStop}"
????????????????????????????????????SelectionBrush="{DynamicResource?WD.WindowBorderBrushSolidColorBrush}"
????????????????????????????????????SnapsToDevicePixels="{TemplateBinding?SnapsToDevicePixels}"
????????????????????????????????????Style="{x:Null}"
????????????????????????????????????TabIndex="{TemplateBinding?TabIndex}"
????????????????????????????????????TextAlignment="{TemplateBinding?TextAlignment}"
????????????????????????????????????VerticalScrollBarVisibility="{TemplateBinding?ScrollViewer.VerticalScrollBarVisibility}"?/>
????????????????????????????????<Grid?Grid.Column="1"?Width="{TemplateBinding?UpDownButtonsWidth}">
????????????????????????????????????<Grid.RowDefinitions>
????????????????????????????????????????<RowDefinition?/>
????????????????????????????????????????<RowDefinition?Height="1"?/>
????????????????????????????????????????<RowDefinition?/>
????????????????????????????????????</Grid.RowDefinitions>
????????????????????????????????????<RepeatButton
????????????????????????????????????????x:Name="PART_NumericUp"
????????????????????????????????????????Grid.Row="0"
????????????????????????????????????????Margin="0,1,1,0"
????????????????????????????????????????Command="{x:Static?controls:NumericBox.IncreaseCommand}"
????????????????????????????????????????Delay="{TemplateBinding?Delay}"
????????????????????????????????????????IsTabStop="False"
????????????????????????????????????????Style="{StaticResource?WD.DefaultRepeatButton}">
????????????????????????????????????????<controls:PathIcon?Kind="ChevronUp"?Style="{StaticResource?WD.MiniPathIcon}"?/>
????????????????????????????????????</RepeatButton>
????????????????????????????????????<RepeatButton
????????????????????????????????????????x:Name="PART_NumericDown"
????????????????????????????????????????Grid.Row="2"
????????????????????????????????????????Margin="0,0,1,1"
????????????????????????????????????????Command="{x:Static?controls:NumericBox.DecreaseCommand}"
????????????????????????????????????????Delay="{TemplateBinding?Delay}"
????????????????????????????????????????IsTabStop="False">
????????????????????????????????????????<controls:PathIcon?Kind="ChevronDown"?Style="{StaticResource?WD.MiniPathIcon}"?/>
????????????????????????????????????</RepeatButton>
????????????????????????????????</Grid>
????????????????????????????</Grid>
????????????????????????</Border>
????????????????????</controls:SmallPanel>
????????????????????<ControlTemplate.Triggers>
????????????????????????<Trigger?Property="UpDownButtonsWidth"?Value="0">
????????????????????????????<Setter?TargetName="PART_NumericDown"?Property="Visibility"?Value="Collapsed"?/>
????????????????????????????<Setter?TargetName="PART_NumericUp"?Property="Visibility"?Value="Collapsed"?/>
????????????????????????</Trigger>
????????????????????????<Trigger?Property="IsReadOnly"?Value="True">
????????????????????????????<Setter?Property="Focusable"?Value="False"?/>
????????????????????????????<Setter?TargetName="PART_NumericDown"?Property="IsEnabled"?Value="False"?/>
????????????????????????????<Setter?TargetName="PART_NumericUp"?Property="IsEnabled"?Value="False"?/>
????????????????????????</Trigger>
????????????????????????<Trigger?Property="IsMouseOver"?Value="True">
????????????????????????????<Setter?Property="BorderBrush"?Value="{DynamicResource?WD.PrimaryNormalSolidColorBrush}"?/>
????????????????????????</Trigger>
????????????????????</ControlTemplate.Triggers>
????????????????</ControlTemplate>
????????????</Setter.Value>
????????</Setter>
????</Style>
????<Style?BasedOn="{StaticResource?WD.NumericBox}"?TargetType="{x:Type?controls:NumericBox}"?/>
</ResourceDictionary>

3)示例 代碼如下:

????????????<wd:NumericBox
????????????????Width="100"
????????????????Maximum="100"
????????????????Minimum="0"?/>
????????????<wd:NumericBox
????????????????Width="100"
????????????????Margin="10,0"
????????????????Maximum="1000"
????????????????Minimum="100"
????????????????UpDownButtonsWidth="0"?/>
????????????<wd:NumericBox?Width="100"?Precision="3"?/>

效果圖

以上就是基于WPF實(shí)現(xiàn)數(shù)字框控件的詳細(xì)內(nèi)容,更多關(guān)于WPF數(shù)字框控件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Unity為軟件添加使用有效期的具體步驟

    Unity為軟件添加使用有效期的具體步驟

    今天小編遇到這樣一個需求需要為軟件設(shè)定一個使用有效期,當(dāng)超過指定時間后,程序無法執(zhí)行,實(shí)現(xiàn)思路并不復(fù)雜,今天小編通過本文給大家分享Unity為軟件添加使用有效期的具體步驟,感興趣的朋友一起看看吧
    2022-03-03
  • c# 如何實(shí)現(xiàn)自動更新程序

    c# 如何實(shí)現(xiàn)自動更新程序

    這篇文章主要介紹了如何用c# 自動更新程序,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03
  • unity里獲取text中文字寬度并截斷省略的操作

    unity里獲取text中文字寬度并截斷省略的操作

    這篇文章主要介紹了unity里獲取text中文字寬度并截斷省略的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C# 減少嵌套循環(huán)的兩種方法

    C# 減少嵌套循環(huán)的兩種方法

    最近在解決性能優(yōu)化的問題,看到了一堆嵌套循環(huán),四五層級的循環(huán)真的有點(diǎn)過分了,在數(shù)據(jù)量成萬,十萬級別的時候,真的非常影響性能。本文介紹了C# 減少嵌套循環(huán)的兩種方法,幫助各位選擇適合自己的優(yōu)化方案,優(yōu)化程序性能
    2021-06-06
  • C#窗體傳值實(shí)例匯總

    C#窗體傳值實(shí)例匯總

    這篇文章主要介紹了C#窗體傳值,實(shí)例形式匯總了靜態(tài)變量傳值、委托傳值、對話框之間的傳值等常見應(yīng)用技巧,需要的朋友可以參考下
    2014-12-12
  • C#并行庫Parallel類介紹

    C#并行庫Parallel類介紹

    這篇文章介紹了C#并行庫Parallel類,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • Unity游戲開發(fā)中的橋接模式

    Unity游戲開發(fā)中的橋接模式

    橋接模式是Unity游戲開發(fā)中常用的設(shè)計模式之一,用于將抽象部分與實(shí)現(xiàn)部分分離,從而使它們可以獨(dú)立地變化。通過橋接模式,不同的抽象類可以與不同的實(shí)現(xiàn)類組合使用,從而實(shí)現(xiàn)更加靈活和可擴(kuò)展的系統(tǒng)設(shè)計。常見的應(yīng)用包括游戲中的場景渲染、UI界面設(shè)計、音效播放等
    2023-05-05
  • C#爬蟲基礎(chǔ)之HttpClient獲取HTTP請求與響應(yīng)

    C#爬蟲基礎(chǔ)之HttpClient獲取HTTP請求與響應(yīng)

    這篇文章介紹了C#使用HttpClient獲取HTTP請求與響應(yīng)的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C# 生成隨機(jī)數(shù)的代碼

    C# 生成隨機(jī)數(shù)的代碼

    這篇文章主要介紹了C# 生成隨機(jī)數(shù)的代碼的相關(guān)資料,非常的簡單實(shí)用,需要的朋友可以參考下
    2015-03-03
  • C#實(shí)現(xiàn)身份證實(shí)名認(rèn)證接口的示例代碼

    C#實(shí)現(xiàn)身份證實(shí)名認(rèn)證接口的示例代碼

    身份證實(shí)名認(rèn)證,即通過姓名和身份證號校驗(yàn)個人信息的匹配程度,廣泛應(yīng)用于金融、互聯(lián)網(wǎng)等多個領(lǐng)域,本文主要介紹了C#實(shí)現(xiàn)身份證實(shí)名認(rèn)證接口的示例代碼,感興趣的可以了解一下
    2024-09-09

最新評論