彩票走势图

教你轻松修改wpf 中NumericUpDown 控件样式

转帖|其它|编辑:郝浩|2011-01-18 15:32:53.000|阅读 3197 次

概述:我这里提供的是在网上找的别人自己写好的NumericUpDown 控件,然后我进行了样式修改,修改之后是长按向上键,值会不停的增大,直至最大值,同理,长按向下键,值会不停的减小,直至最小值(就是把以前的 Button换成了RepeatButton)。单击功能仍和以前一样。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

  NumericUpDown 控件看起来像是一个文本框与一对用户可单击以调整值的箭头的组合。该控件显示并设置固定的数值选择列表中的单个数值。用户可以通过单击向上和向下、按向上和向下键或在控件的文本框部件中键入一个数字来增大和减小数字。单击向上键时,值向最大值方向移动;单击向下键时,值向最小值方向移动。

  我这里提供的是在网上找的别人自己写好的NumericUpDown 控件,然后我进行了样式修改,修改之后是长按向上键,值会不停的增大,直至最大值,同理,长按向下键,值会不停的减小,直至最小值(就是把以前的Button换成了RepeatButton)。单击功能仍和以前一样。

代码奉上:

  首先这个是自定义控件:

public class NumericUpDown : Control
{
static NumericUpDown()
{
InitializeCommands();

// Listen to MouseLeftButtonDown event to determine if NumericUpDown should move focus to itself
EventManager.RegisterClassHandler(typeof(NumericUpDown),
Mouse.MouseDownEvent, new MouseButtonEventHandler(NumericUpDown.OnMouseLeftButtonDown), true);

DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown),

new FrameworkPropertyMetadata(typeof(NumericUpDown)));
}

public NumericUpDown()
: base()
{
updateValueString();
}

#region Properties

#region Value

public decimal Value
{
get { return (decimal)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}

/// <summary>
/// Identifies the Value dependency property.
/// </summary>
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value", typeof(decimal), typeof(NumericUpDown),
new FrameworkPropertyMetadata(DefaultValue,
new PropertyChangedCallback(OnValueChanged),
new CoerceValueCallback(CoerceValue)
)
);

private static void OnValueChanged(DependencyObject obj,

DependencyPropertyChangedEventArgs args)
{
NumericUpDown control = (NumericUpDown)obj;

decimal oldValue = (decimal)args.OldValue;
decimal newValue = (decimal)args.NewValue;

#region Fire Automation events
NumericUpDownAutomationPeer peer =

UIElementAutomationPeer.FromElement(control) as NumericUpDownAutomationPeer;
if (peer != null)
{
peer.RaiseValueChangedEvent(oldValue, newValue);
}
#endregion

RoutedPropertyChangedEventArgs<decimal> e =

new RoutedPropertyChangedEventArgs<decimal>(
oldValue, newValue, ValueChangedEvent);

control.OnValueChanged(e);

control.updateValueString();
}

/// <summary>
/// Raises the ValueChanged event.
/// </summary>
/// <param name="args">Arguments associated with the ValueChanged event.</param>
protected virtual void OnValueChanged(RoutedPropertyChangedEventArgs<decimal> args)
{
RaiseEvent(args);
}

private static object CoerceValue(DependencyObject element, object value)
{
decimal newValue = (decimal)value;
NumericUpDown control = (NumericUpDown)element;

newValue = Math.Max(control.Minimum, Math.Min(control.Maximum, newValue));
newValue = Decimal.Round(newValue, control.DecimalPlaces);

return newValue;
}

#endregion

#region Minimum

public decimal Minimum
{
get { return (decimal)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}

public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register(
"Minimum", typeof(decimal), typeof(NumericUpDown),
new FrameworkPropertyMetadata(DefaultMinValue,
new PropertyChangedCallback(OnMinimumChanged), new CoerceValueCallback(CoerceMinimum)
)
);

private static void OnMinimumChanged(DependencyObject element,

DependencyPropertyChangedEventArgs args)
{
element.CoerceValue(MaximumProperty);
element.CoerceValue(ValueProperty);
}
private static object CoerceMinimum(DependencyObject element, object value)
{
decimal minimum = (decimal)value;
NumericUpDown control = (NumericUpDown)element;
return Decimal.Round(minimum, control.DecimalPlaces);
}

#endregion

#region Maximum

public decimal Maximum
{
get { return (decimal)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}

public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register(
"Maximum", typeof(decimal), typeof(NumericUpDown),
new FrameworkPropertyMetadata(DefaultMaxValue,
new PropertyChangedCallback(OnMaximumChanged),
new CoerceValueCallback(CoerceMaximum)
)
);

private static void OnMaximumChanged(DependencyObject element,

DependencyPropertyChangedEventArgs args)
{
element.CoerceValue(ValueProperty);
}

private static object CoerceMaximum(DependencyObject element, object value)
{
NumericUpDown control = (NumericUpDown)element;
decimal newMaximum = (decimal)value;
return Decimal.Round(Math.Max(newMaximum, control.Minimum), control.DecimalPlaces);
}
#endregion

#region Change

public decimal Change
{
get { return (decimal)GetValue(ChangeProperty); }
set { SetValue(ChangeProperty, value); }
}

public static readonly DependencyProperty ChangeProperty =
DependencyProperty.Register(
"Change", typeof(decimal), typeof(NumericUpDown),
new FrameworkPropertyMetadata(DefaultChange,

new PropertyChangedCallback(OnChangeChanged),

new CoerceValueCallback(CoerceChange)),
new ValidateValueCallback(ValidateChange)
);

private static bool ValidateChange(object value)
{
decimal change = (decimal)value;
return change > 0;
}

private static void OnChangeChanged

(DependencyObject element, DependencyPropertyChangedEventArgs args)
{

}

private static object CoerceChange(DependencyObject element, object value)
{
decimal newChange = (decimal)value;
NumericUpDown control = (NumericUpDown)element;

decimal coercedNewChange = Decimal.Round(newChange, control.DecimalPlaces);

//If Change is .1 and DecimalPlaces is changed from 1 to 0, we want Change to go to 1, not 0.
//Put another way, Change should always be rounded to DecimalPlaces, but never smaller than the
//previous Change
if (coercedNewChange < newChange)
{
coercedNewChange = smallestForDecimalPlaces(control.DecimalPlaces);
}

return coercedNewChange;
}

private static decimal smallestForDecimalPlaces(int decimalPlaces)
{
if (decimalPlaces < 0)
{
throw new ArgumentException("decimalPlaces");
}

decimal d = 1;

for (int i = 0; i < decimalPlaces; i++)
{
d /= 10;
}

return d;
}

#endregion

#region DecimalPlaces

public int DecimalPlaces
{
get { return (int)GetValue(DecimalPlacesProperty); }
set { SetValue(DecimalPlacesProperty, value); }
}

public static readonly DependencyProperty DecimalPlacesProperty =
DependencyProperty.Register(
"DecimalPlaces", typeof(int), typeof(NumericUpDown),
new FrameworkPropertyMetadata(DefaultDecimalPlaces,
new PropertyChangedCallback(OnDecimalPlacesChanged)
), new ValidateValueCallback(ValidateDecimalPlaces)
);

private static void OnDecimalPlacesChanged(DependencyObject element, DependencyPropertyChangedEventArgs args)
{
NumericUpDown control = (NumericUpDown)element;
control.CoerceValue(ChangeProperty);
control.CoerceValue(MinimumProperty);
control.CoerceValue(MaximumProperty);
control.CoerceValue(ValueProperty);
control.updateValueString();
}

private static bool ValidateDecimalPlaces(object value)
{
int decimalPlaces = (int)value;
return decimalPlaces >= 0;
}

#endregion

#region ValueString
//public string ValueString
//{
// get
// {
// return (string)GetValue(ValueStringProperty);
// }
//}

//private static readonly DependencyPropertyKey ValueStringPropertyKey =
// DependencyProperty.RegisterAttachedReadOnly("ValueString", typeof(string),

typeof(NumericUpDown), new PropertyMetadata());

//public static readonly DependencyProperty ValueStringProperty = ValueStringPropertyKey.DependencyProperty;

public string ValueString
{
get { return (string)GetValue(ValueStringProperty); }
set { SetValue(ValueStringProperty, value); }
}

/// <summary>
/// Identifies the Value dependency property.
/// </summary>
public static readonly DependencyProperty ValueStringProperty =
DependencyProperty.Register("ValueString", typeof(string), typeof(NumericUpDown),

new FrameworkPropertyMetadata());

private void updateValueString()
{
m_NumberFormatInfo.NumberDecimalDigits = this.DecimalPlaces;
string newValueString = this.Value.ToString("f", m_NumberFormatInfo);
//this.SetValue(ValueStringPropertyKey, newValueString);
ValueString = newValueString;
}
private NumberFormatInfo m_NumberFormatInfo = new NumberFormatInfo();

#endregion

#endregion

#region Events
/// <summary>
/// Identifies the ValueChanged routed event.
/// </summary>
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent(
"ValueChanged", RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<decimal>), typeof(NumericUpDown));

/// <summary>
/// Occurs when the Value property changes.
/// </summary>
public event RoutedPropertyChangedEventHandler<decimal> ValueChanged
{
add { AddHandler(ValueChangedEvent, value); }
remove { RemoveHandler(ValueChangedEvent, value); }
}
#endregion

#region Commands

public static RoutedCommand IncreaseCommand
{
get
{
return m_IncreaseCommand;
}
}
public static RoutedCommand DecreaseCommand
{
get
{
return m_DecreaseCommand;
}
}

private static void InitializeCommands()
{
m_IncreaseCommand = new RoutedCommand("IncreaseCommand", typeof(NumericUpDown));
CommandManager.RegisterClassCommandBinding(typeof(NumericUpDown),

new CommandBinding(m_IncreaseCommand, OnIncreaseCommand));
CommandManager.RegisterClassInputBinding(typeof(NumericUpDown),

new InputBinding(m_IncreaseCommand, new KeyGesture(Key.Up)));

m_DecreaseCommand = new RoutedCommand("DecreaseCommand", typeof(NumericUpDown));
CommandManager.RegisterClassCommandBinding(typeof(NumericUpDown),

new CommandBinding(m_DecreaseCommand, OnDecreaseCommand));
CommandManager.RegisterClassInputBinding(typeof(NumericUpDown),

new InputBinding(m_DecreaseCommand, new KeyGesture(Key.Down)));
}

private static void OnIncreaseCommand(object sender, ExecutedRoutedEventArgs e)
{
NumericUpDown control = sender as NumericUpDown;
if (control != null)
{
control.OnIncrease();
}
}

private static void OnDecreaseCommand(object sender, ExecutedRoutedEventArgs e)
{
NumericUpDown control = sender as NumericUpDown;
if (control != null)
{
control.OnDecrease();
}
}

protected virtual void OnIncrease()
{
this.Value += Change;
}

protected virtual void OnDecrease()
{
this.Value -= Change;
}

private static RoutedCommand m_IncreaseCommand;
private static RoutedCommand m_DecreaseCommand;
#endregion

#region Automation

protected override AutomationPeer OnCreateAutomationPeer()
{
return new NumericUpDownAutomationPeer(this);
}

#endregion

/// <summary>
/// This is a class handler for MouseLeftButtonDown event.
/// The purpose of this handle is to move input focus to NumericUpDown when user pressed
/// mouse left button on any part of slider that is not focusable.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
NumericUpDown control = (NumericUpDown)sender;

// When someone click on a part in the NumericUpDown and it's not focusable
// NumericUpDown needs to take the focus in order to process keyboard correctly
if (!control.IsKeyboardFocusWithin)
{
e.Handled = control.Focus() || e.Handled;
}
}

private const decimal DefaultMinValue = 0,
DefaultValue = DefaultMinValue,
DefaultMaxValue = 100,
DefaultChange = 1;
private const int DefaultDecimalPlaces = 0;
}

public class NumericUpDownAutomationPeer :

FrameworkElementAutomationPeer, IRangeValueProvider
{
public NumericUpDownAutomationPeer(NumericUpDown control)
: base(control)
{
}

protected override string GetClassNameCore()
{
return "NumericUpDown";
}

protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Spinner;
}

public override object GetPattern(PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.RangeValue)
{
return this;
}
return base.GetPattern(patternInterface);
}

internal void RaiseValueChangedEvent(decimal oldValue, decimal newValue)
{

base.RaisePropertyChangedEvent(RangeValuePatternIdentifiers.ValueProperty,
(double)oldValue, (double)newValue);

}

#region IRangeValueProvider Members

bool IRangeValueProvider.IsReadOnly
{
get
{
return !IsEnabled();
}
}

double IRangeValueProvider.LargeChange
{
get { return (double)MyOwner.Change; }
}

double IRangeValueProvider.Maximum
{
get { return (double)MyOwner.Maximum; }
}

double IRangeValueProvider.Minimum
{
get { return (double)MyOwner.Minimum; }
}

void IRangeValueProvider.SetValue(double value)
{
if (!IsEnabled())
{
throw new ElementNotEnabledException();
}

decimal val = (decimal)value;
if (val < MyOwner.Minimum || val > MyOwner.Maximum)
{
throw new ArgumentOutOfRangeException("value");
}

MyOwner.Value = val;
}

double IRangeValueProvider.SmallChange
{
get { return (double)MyOwner.Change; }
}

double IRangeValueProvider.Value
{
get { return (double)MyOwner.Value; }
}

#endregion

private NumericUpDown MyOwner
{
get
{
return (NumericUpDown)base.Owner;

然后建一个窗体:

<Window x:Class="WpfTest.NumericUpDownStyle"
xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="//schemas.microsoft.com/winfx/2006/xaml"
<SPAN style="COLOR: #ff0000">xmlns:styles="clr-namespace:WpfTest"
</SPAN> Title="NumericUpDownStyle"
Height="300"
Width="300">
<Window.Resources>
<ControlTemplate x:Key="addBtnTemplate"
TargetType="{x:Type RepeatButton}">
<Border Height="19"
Width="39"
BorderThickness="0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0"
Opacity="1">
<GradientStop Color="#FFb9bbbc"
Offset="0" />
<GradientStop Color="#FF909294"
Offset="0.973" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter HorizontalAlignment="Center"
Content="{TemplateBinding Button.Content}"
VerticalAlignment="Center"></ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed"
Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X=".5"
Y=".3"></TranslateTransform>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<Style TargetType="{x:Type styles:NumericUpDown}">
<Setter Property="BorderBrush"
Value="#81ADD0" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Padding"
Value="0" />
<Setter Property="MinWidth"
Value="180" />
<Setter Property="Height"
Value="40" />
<Setter Property="HorizontalAlignment"
Value="Center" />
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type styles:NumericUpDown}">
<Border BorderBrush="#999999"
Width="128"
Height="39"
BorderThickness="1"
Padding="{TemplateBinding Padding}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>

</Grid.ColumnDefinitions>
<TextBox Text="{Binding
RelativeSource=
{
RelativeSource
Mode=FindAncestor,
AncestorType={x:Type styles:NumericUpDown}
},
Path=Value,
Mode=TwoWay
}"
BorderThickness="0"
IsEnabled="True"
FontSize="24"
TextAlignment="Right"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Grid.Column="0"
Width="70" />
<Border BorderThickness="1,0,0,0" Width="39"
HorizontalAlignment="Right"
BorderBrush="#999999">
<StackPanel Width="39">
<RepeatButton Command="styles:NumericUpDown.IncreaseCommand"
Grid.Row="0"
HorizontalAlignment="Right"
Width="39"
Height="19"
Margin="0,0,0,0"
Template="{StaticResource addBtnTemplate}">
<RepeatButton.Content>
<Path Height="6"
Width="12"
Stretch="Fill"
Opacity="1"
Data="M 666.5,597 C666.5,597 678.5,597 678.5,597 678.5,597 672.5,591 672.5,591 672.5,591 666.5,597 666.5,597 z"
Fill="#ffffff" />
</RepeatButton.Content>
</RepeatButton>
<RepeatButton Command="styles:NumericUpDown.DecreaseCommand"
Margin="0,0,0,0"
Grid.Row="1"
Width="39"
HorizontalAlignment="Right"
Height="19"
Template="{StaticResource addBtnTemplate}">
<RepeatButton.Content>
<Path Height="6"
Width="12"
Stretch="Fill"
Opacity="1"
Data="M 666.5,609 C666.5,609 678.5,609 678.5,609 678.5,609 672.5,615 672.5,615 672.5,615 666.5,609 666.5,609 z"
Fill="#ffffff" />
</RepeatButton.Content>
</RepeatButton>
</StackPanel>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Opacity"
Value="0.2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

</Window.Resources>
<Grid>
<styles:NumericUpDown x:Name="nUpDown_hege"
Minimum="0"
Maximum="100"
Grid.Column="1"></styles:NumericUpDown>
</Grid>
</Window>


 


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:网络转载

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP