------------恢复内容开始------------
自定义控件是用来实现基本的一些控件的自定义化,本身没有界面,我们新建一个自定义控件,将生成如下文件:
Themes:文件夹下包含了自定义控件的界面样式,默认是Generic.xaml,不同操作系统的界面样式命名都不一样
Numeric.cs包含对代码的处理:
[TemplatePart(Name = "UpButton", Type = typeof(RepeatButton))]
[TemplatePart(Name = "DownButton", Type = typeof(RepeatButton))]
[TemplateVisualState(Name = "Positive", GroupName = "ValueStates")]
[TemplateVisualState(Name = "Negative", GroupName = "ValueStates")]
[TemplateVisualState(Name = "Focused", GroupName = "FocusedStates")]
[TemplateVisualState(Name = "Unfocused", GroupName = "FocusedStates")
public class Numeric : Control
{
static Numeric()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Numeric), new FrameworkPropertyMetadata(typeof(Numeric)));
}
public Numeric()
{
DefaultStyleKey = typeof(Numeric);
this.IsTabStop = true;
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value", typeof(int), typeof(Numeric),
new PropertyMetadata(
new PropertyChangedCallback(ValueChangedCallback)));
public int Value
{
get
{
return (int)GetValue(ValueProperty);
}
set
{
SetValue(ValueProperty, value);
}
}
public override void OnApplyTemplate()
{
UpButtonElement = GetTemplateChild("UpButton") as RepeatButton;
DownButtonElement = GetTemplateChild("DownButton") as RepeatButton;
UpdateStates(false);
}
private static void ValueChangedCallback(DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
Numeric ctl = (Numeric)obj;
int newValue = (int)args.NewValue;
// Call UpdateStates because the Value might have caused the
// control to change ValueStates.
ctl.UpdateStates(true);
// Call OnValueChanged to raise the ValueChanged event.
ctl.OnValueChanged(
new ValueChangedEventArgs(Numeric.ValueChangedEvent,
newValue));
}
public static readonly RoutedEvent ValueChangedEvent =
EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Direct,
typeof(ValueChangedEventHandler), typeof(Numeric));
public event ValueChangedEventHandler ValueChanged
{
add { AddHandler(ValueChangedEvent, value); }
remove { RemoveHandler(ValueChangedEvent, value); }
}
protected virtual void OnValueChanged(ValueChangedEventArgs e)
{
RaiseEvent(e);
}
private void UpdateStates(bool useTransitions)
{
if (Value >= 0)
{
VisualStateManager.GoToState(this, "Positive", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Negative", useTransitions);
}
if (IsFocused)
{
VisualStateManager.GoToState(this, "Focused", false);
}
else
{
VisualStateManager.GoToState(this, "Unfocused", false);
}
}
private RepeatButton downButtonElement;
private RepeatButton DownButtonElement
{
get
{
return downButtonElement;
}
set
{
if (downButtonElement != null)
{
downButtonElement.Click -=
new RoutedEventHandler(downButtonElement_Click);
}
downButtonElement = value;
if (downButtonElement != null)
{
downButtonElement.Click +=
new RoutedEventHandler(downButtonElement_Click);
}
}
}
void downButtonElement_Click(object sender, RoutedEventArgs e)
{
Value--;
}
private RepeatButton upButtonElement;
private RepeatButton UpButtonElement
{
get
{
return upButtonElement;
}
set
{
if (upButtonElement != null)
{
upButtonElement.Click -=
new RoutedEventHandler(upButtonElement_Click);
}
upButtonElement = value;
if (upButtonElement != null)
{
upButtonElement.Click +=
new RoutedEventHandler(upButtonElement_Click);
}
}
}
void upButtonElement_Click(object sender, RoutedEventArgs e)
{
Value++;
}
protected override void onm ouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
Focus();
}
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
UpdateStates(true);
}
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
UpdateStates(true);
}
}
public delegate void ValueChangedEventHandler(object sender, ValueChangedEventArgs e);
public class ValueChangedEventArgs : RoutedEventArgs
{
private int _value;
public ValueChangedEventArgs(RoutedEvent id, int num)
{
_value = num;
RoutedEvent = id;
}
public int Value
{
get { return _value; }
}
}
<Style TargetType="{x:Type local:Numeric}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:Numeric"> <Grid Margin="3" Background="{TemplateBinding Background}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup Name="ValueStates"> <VisualState Name="Negative"> <Storyboard> <ColorAnimation To="Red" Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="(Foreground).(Color)"/> </Storyboard> </VisualState> <VisualState Name="Positive"/> </VisualStateGroup> <VisualStateGroup Name="FocusStates"> <VisualState Name="Focused"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Visibility" Duration="0"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState Name="Unfocused"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Border BorderThickness="1" BorderBrush="Gray" Margin="7,2,2,2" Grid.RowSpan="2" Background="#E0FFFFFF" VerticalAlignment="Center" HorizontalAlignment="Stretch"> <TextBlock Name="TextBlock" Width="60" TextAlignment="Right" Padding="5" Text="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type local:Numeric}},Path=Value}"/> </Border> <RepeatButton Content="Up" Margin="2,5,5,0" Name="UpButton" Grid.Column="1" Grid.Row="0"/> <RepeatButton Content="Down" Margin="2,0,5,5" Name="DownButton" Grid.Column="1" Grid.Row="1"/> <Rectangle Name="FocusVisual" Grid.ColumnSpan="2" Grid.RowSpan="2" Stroke="White" StrokeThickness="1" Visibility="Collapsed"/> </Grid> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
当创建控件时候,编辑模板, Generi.xaml的样式内容最终会生成样式模板内容
------------恢复内容结束------------