本文介绍如何实现个 Mac 风格按钮先看下效果:
左边排是普通按钮右边排是 Mac 风格按钮其中获得焦点按钮在视觉上用圈虚线框表示
Button Control控件开放了个 Template 属性我们要做就是创建个 Style. 比如叫做 MacButton然后让按钮例子去套用这个 Style 即可:
<ButtonStyle="{StaticResourceMacButton}"/>
而 Style 本质上是用来设置属性值Template 也是个特殊属性它是 CcontrolTemplate. 在 Xaml 语法中可以这样写:
<SetterProperty="Template">
<Setter.Value>
<ControlTemplateTargetType="Button">
</ControlTemplate>
</Setter.Value>
</Setter>
所有Control控件真实内容都在上面 "...." 中定义即可
再介绍点基础知识
Control控件契约 (Control Contract)
Silverlight 2beta 2 内置每种Control控件都有其自身契约我们在为Control控件创建 Style 时必须符合此契约要求才能生效
般包含3个方面:
1) 属性
2) Control控件可能用到 UIElement. (用 TemplatePartAttribute 标记)
3) VisualState 对象 (用 TemplateVisualState 在Control控件上标记)
这里 VisualState 很有意思表示Control控件状态并且状态可以分组同个组内状态可以互相迁移
比如 Button 有两组状态:组是“普通”、“鼠标悬停”、“按下”、“禁用”;而另组是“获得焦点”、“失去焦点”
两组状态可以同时生效互不影响
在 ControlTemplate 内我们可以定义各个状态以及状态间迁移时动画 (用个 Storyboard 定义)以及状态的间迁移花费多少时间 (Duration) 等
Button Control控件契约如下:
[TemplateVisualState(Name="Normal",GroupName="CommonStates")]
[TemplateVisualState(Name="MouseOver",GroupName="CommonStates")]
[TemplateVisualState(Name="Pressed",GroupName="CommonStates")]
[TemplateVisualState(Name="Disabled",GroupName="CommonStates")]
[TemplateVisualState(Name="Unfocused",GroupName="FocusStates")]
[TemplateVisualState(Name="Focused",GroupName="FocusStates")]
publicButton:Control
{
publicreadonlyDependencyPropertyBackgroundProperty;
publicreadonlyDependencyPropertyBorderBrushProperty;
publicreadonlyDependencyPropertyBorderThicknessProperty;
publicreadonlyDependencyPropertyContentProperty;
publicreadonlyDependencyPropertyContentTemplateProperty;
publicreadonlyDependencyPropertyFontFamilyProperty;
publicreadonlyDependencyPropertyFontSizeProperty;
publicreadonlyDependencyPropertyFontStretchProperty;
publicreadonlyDependencyPropertyFontStyleProperty;
publicreadonlyDependencyPropertyFontWeightProperty;
publicreadonlyDependencyPropertyForegroundProperty;
publicreadonlyDependencyPropertyHorizontalContentAlignmentProperty;
publicreadonlyDependencyPropertyPaddingProperty;
publicreadonlyDependencyPropertyTextAlignmentProperty;
publicreadonlyDependencyPropertyTextDecorationsProperty;
publicreadonlyDependencyPropertyTextWrappingProperty;
publicreadonlyDependencyPropertyVerticalContentAlignmentProperty;
publicBrushBackground{get;;}
publicBrushBorderBrush{get;;}
publicThicknessBorderThickness{get;;}
publicobjectContent{get;;}
publicDataTemplateContentTemplate{get;;}
publicFontFamilyFontFamily{get;;}
publicdoubleFontSize{get;;}
publicFontStretchFontStretch{get;;}
publicFontStyleFontStyle{get;;}
publicFontWeightFontWeight{get;;}
publicBrushForeground{get;;}
publicHorizontalAlignmentHorizontalContentAlignment{get;;}
publicThicknessPadding{get;;}
publicTextAlignmentTextAlignment{get;;}
publicTextDecorationCollectionTextDecorations{get;;}
publicTextWrappingTextWrapping{get;;}
publicVerticalAlignmentVerticalContentAlignment{get;;}
}
有关动画更多知识参考 Silverlight 2beta 2 文档
简单说下创建这个样式步骤:
在 ExpressionBlend 2.5 中首先我们往界面上拖个 Button. 然后在右键菜单中:
选择 "Edit a Copy" 后就会自动创建个指定名称 Style, 其内容是 Button 默认模板
模板内容非常繁琐我们如果自己全部手写很困难所以我们选择在默认模板基础上修改
后续步骤主要是在模板Control控件树中删除掉不必要内容并且修改些画刷等设置重新定义动画等等不再详述具体请看代码
另外这里我发现个特别需要注意问题就是 Button 默认生成模板中其 Unfocused 状态动画必须删除掉才行:
<vsm:VisualStatex:Name="Unfocused">
<Storyboard>
<!--自动生成模板下这里是有内容要删掉!-->
</Storyboard>
</vsm:VisualState>
否则你会发现套用了该风格所有按钮都无法失去焦点页面上会出现若干个按钮同时为高亮状态滑稽情景
下面是例子全部代码:
<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="SilverlightApplication6.Page"
d:DesignWidth="640"d:DesignHeight="480"xmlns:vsm="clr-:.Windows;assembly=.Windows">
<UserControl.Resources>
<vsm:Stylex:Key="MacButton"TargetType="Button">
<vsm:SetterProperty="IsEnabled"Value="true"/>
<vsm:SetterProperty="IsTabStop"Value="true"/>
<vsm:SetterProperty="Background"Value="#FF003255"/>
<vsm:SetterProperty="Foreground"Value="#FF313131"/>
<vsm:SetterProperty="MinWidth"Value="5"/>
<vsm:SetterProperty="MinHeight"Value="5"/>
<vsm:SetterProperty="Margin"Value="0"/>
<vsm:SetterProperty="HorizontalContentAlignment"Value="Center"/>
<vsm:SetterProperty="VerticalContentAlignment"Value="Center"/>
<vsm:SetterProperty="Cursor"Value="Arrow"/>
<vsm:SetterProperty="TextAlignment"Value="Left"/>
<vsm:SetterProperty="TextWrapping"Value="NoWrap"/>
<vsm:SetterProperty="FontSize"Value="11"/>
<vsm:SetterProperty="Template">
<vsm:Setter.Value>
<ControlTemplateTargetType="Button">
<Grid>
<Grid.Resources>
<Colorx:Key="LinearBevelLightStartColor">#FFFFFFFF</Color>
<Colorx:Key="LinearBevelLightEndColor">#F4E2E0E0</Color>
<Colorx:Key="LinearBevelDarkStartColor">#E0E5E5E5</Color>
<Colorx:Key="LinearBevelDarkEndColor">#B2FFFFFF</Color>
<Colorx:Key="MouseOverLinearBevelDarkEndColor">#7FFC1717</Color>
<Colorx:Key="HoverLinearBevelLightStartColor">#FCFFFFFF</Color>
<Colorx:Key="HoverLinearBevelLightEndColor">#EAFFFFFF</Color>
<Colorx:Key="HoverLinearBevelDarkStartColor">#D8FFFFFF</Color>
<Colorx:Key="HoverLinearBevelDarkEndColor">#4CFFFFFF</Color>
<Colorx:Key="CurvedBevelFillStartColor">#B3FFFFFF</Color>
<Colorx:Key="CurvedBevelFillEndColor">#3CFFFFFF</Color>
<SolidColorBrushx:Key="BorderBrush"Color="#FF5E5E5E"/>
<SolidColorBrushx:Key="AccentBrush"Color="#FF000000"/>
<SolidColorBrushx:Key="DisabledBrush"Color="#A5FFFFFF"/>
<LinearGradientBrushx:Key="FocusedStrokeBrush"EndPo="0.5,1"StartPo="0.5,0">
<GradientStopColor="#B2FFFFFF"Off="0"/>
<GradientStopColor="#51FFFFFF"Off="1"/>
<GradientStopColor="#66FFFFFF"Off="0.325"/>
<GradientStopColor="#1EFFFFFF"Off="0.325"/>
</LinearGradientBrush>
</Grid.Resources>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroupx:Name="CommonStates">
<vsm:VisualStateGroup.Transitions>
<vsm:VisualTransitionDuration="00:00:00.2000000"To="MouseOver"/>
<vsm:VisualTransitionDuration="0:0:0.1"To="Pressed"/>
<vsm:VisualTransitionDuration="00:00:00.2000000"From="Normal"To="MouseOver"/>
</vsm:VisualStateGroup.Transitions>
<vsm:VisualStatex:Name="Normal">
<Storyboard/>
</vsm:VisualState>
<vsm:VisualStatex:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<SplineColorKeyFrameKeyTime="0"Value="#c8d5ed"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<SplineColorKeyFrameKeyTime="0"Value="#97c2ee"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
<SplineColorKeyFrameKeyTime="0"Value="#6eadee"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
<SplineColorKeyFrameKeyTime="0"Value="#aff9ff"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualStatex:Name="Pressed">
<Storyboard>
<DoubleAnimationUsingKeyFramesDuration="0"Storyboard.TargetName="BackgroundGradient"Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Off)">
<SplineDoubleKeyFrameKeyTime="0"Value=".2"/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<SplineColorKeyFrameKeyTime="0"Value="#bac5e8"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<SplineColorKeyFrameKeyTime="0"Value="#7bb2e9"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
<SplineColorKeyFrameKeyTime="0"Value="#4d9ae7"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Duration="0"
Storyboard.TargetName="BackgroundGradient"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
<SplineColorKeyFrameKeyTime="0"Value="#85eaff"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualStatex:Name="Disabled">
<Storyboard>
<DoubleAnimationUsingKeyFramesDuration="0"Storyboard.TargetName="DisabledVisual"Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrameKeyTime="0"Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroupx:Name="FocusStates">
<vsm:VisualStatex:Name="Focused">
最新评论