ComponentOne C1ToolbarToggleButton Style
2012-11-29 23:01 gitenius 阅读(779) 评论(1) 编辑 收藏 举报本文主要介绍 C1ToolbarToggleButton Control 的样式修改。
本文分为以下几个部分:
一:Outer Border 和 Inner Border 对布局及视觉效果的影响
二:C1ToolbarToggleButton 元素布局
第一部分:视觉状态管理器(VisualStateManager)
第二部分:视觉树(Visual Tree)
第三部分:CommonStates静态分析
第四部分: Resources And Binding:(Default Style)
第五部分:视觉状态切换(VisualStateGroup.Transitions)
三:自定义按钮示例
一:Outer Border 和 Inner Border 对布局及视觉效果的影响
源码BorderLayout.xaml:(注意<Border>的Margin属性和Background的属性)
<StackPanel > <!-- Example1: InnerBorder.Background=Transparent Margin=0 --> <TextBlock Text="Example 1" /> <Border Tag="OuterBorder" Background="Orange" Width="132" Height="20"> <Border Tag="InnerBorder" BorderBrush="Green" BorderThickness="2" Margin="0" Background="Transparent"/> </Border> <Border Height="20"/> <!-- Example2: InnerBorder.Background=Red Margin=0 --> <TextBlock Text="Example 2" /> <Border Tag="OuterBorder" Background="Orange" Width="132" Height="20"> <Border Tag="InnerBorder" BorderBrush="Green" BorderThickness="2" Margin="0" Background="Red"/> </Border> <Border Height="20"/> <!-- Example3: InnerBorder.Background=Transparent Margin=5 --> <TextBlock Text="Example 3" /> <Border Tag="OuterBorder" Background="Orange" Width="132" Height="20"> <Border Tag="InnerBorder" BorderBrush="Green" BorderThickness="2" Margin="5" Background="Transparent"/> </Border> <Border Height="20"/> <!-- Example4: InnerBorder.Background=Green Margin=5 --> <TextBlock Text="Example 4" /> <Border Tag="OuterBorder" Background="Orange" Width="132" Height="20"> <Border Tag="InnerBorder" BorderBrush="Green" BorderThickness="2" Margin="5" Background="Red"/> </Border> </StackPanel>
Border元素嵌套属性区别:
视觉效果对比图(5):
(图5)
二:C1ToolbarToggleButton 元素布局
安装开发工具:Expression Blend 4 和 ComponentOne for Silverlight / ComponentOne for WPF 控件。
Expression Blend 4 官方网站:http://www.microsoft.com/china/expression/
ComponentOne 官方网站:http://our.componentone.com/
使用EB4编辑Button的模版,如图(6)所示:
图(6)
下面参考并讲解源文件ButtonStyle.xaml(分析C1ToolbarToggleButton的布局系统)
第一部分:视觉状态管理器(VisualStateManager)
CommandStates包含Normal,MouseOver,Pressed,Disabled四种视觉状态
CheckStates包含Unchecked,Checked,Indeterminate三种视觉状态
FocusStates包含Unfocused,Focused两种视觉状态
ToolbarStates包含Large,Medium,Small三种视觉状态
由此可见:C1ToolbarToggleButton控件稍微复杂一些,如图(7)所示
图(7)
第二部分:视觉树(Visual Tree)
元素的视觉树,如图(8)所示
图(8)
注意元素的排列顺序:BackgroundElement《MouseOverElement《PressedElement《CheckedElement《Grid《DisabledVisualElement(“A《B”表示A元素在B元素下边)
第三部分:CommonStates静态分析
CommonStates的四种视觉状态:(视觉效果与第一部分的Outer Border,Inner Border类似。Outer Border显示为背景色,Inner Border 显示边框颜色)
所以可以通过修改 BackgroudElement元素的外观来修改 C1ToolbarToggleButton的按钮外观(即修改Border的样式)
<!-- Normal 元素 --> <Border x:Name="BackgroundElement" Background="{Binding Output, ElementName=BackgroundBrush}"> <Border BorderBrush="{Binding Output, ElementName=InnerBorderBrush}" BorderThickness="{StaticResource InnerBorderThickness}"/> </Border>
<!-- MouseOver 元素 --> <Border x:Name="MouseOverElement" Background="{Binding Output, ElementName=MouseOverBrush}" Visibility="Collapsed"> <Border BorderBrush="{Binding Output, ElementName=InnerBorderMouseOverBrush}" BorderThickness="{StaticResource InnerBorderThickness}"/> </Border>
<!-- PressedElement 元素 --> <Border x:Name="PressedElement" BorderBrush="{TemplateBinding PressedBrush}" Background="{Binding Output, ElementName=PressedBrush}" Visibility="Collapsed"> <Border BorderBrush="{Binding Output, ElementName=InnerBorderPressedBrush}" BorderThickness="{StaticResource InnerBorderThickness}"/> </Border>
<!-- Checked 元素 --> <Border x:Name="CheckedElement" Background="{Binding Output, ElementName=CheckedBrush}" Visibility="Collapsed"/>
<!-- ContentPresenter --> <Grid Margin="{TemplateBinding Padding}"> <StackPanel x:Name="LargeView" DataContext="{Binding Converter={StaticResource commandConverter}, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}"> <Image x:Name="img1" Source="{Binding LargeImageSource}" Stretch="None"/> <TextBlock x:Name="LargeText" TextAlignment="Center" Text="{Binding LabelTitle}"/> </StackPanel> <StackPanel x:Name="MediumView" DataContext="{Binding Converter={StaticResource commandConverter}, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}" Orientation="Horizontal" Visibility="Collapsed"> <Image x:Name="img2" Source="{Binding SmallImageSource}" Stretch="None"/> <TextBlock x:Name="MediumText" Text="{Binding LabelTitle}" VerticalAlignment="Center"/> </StackPanel> <StackPanel x:Name="SmallView" DataContext="{Binding Converter={StaticResource commandConverter}, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}" Orientation="Horizontal" Visibility="Collapsed"> <Image x:Name="img3" Source="{Binding SmallImageSource}" Stretch="None"/> </StackPanel> <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid>
<!-- Disabled 元素 --> <Border x:Name="DisabledVisualElement" Background="{StaticResource DisabledBrush}" IsHitTestVisible="False" Visibility="Collapsed"/>
C1ToolbarToggleButton的Normal,MouseOver,Pressed,Disabled四种状态对比图(9):
图(9)
注意OuterBorder .Background和 InnerBorder.BorderBrush的变化,这里使用了资源绑定
以上是使用默认资源样式的效果图,修改相应的资源可以达到修改按钮颜色的效果,比如金属色,半透明按钮等
第四部分: Resources And Binding:(Default Style)
Source Code:
<!-- Normal 元素 绑定资源 Template中定义--> <c1:C1BrushBuilder x:Name="BackgroundBrush" DesignBrush="{StaticResource GeneralGradientBrush}" DesignColor="{StaticResource BaseColor}" Input="{TemplateBinding Background}"/> <c1:C1BrushBuilder x:Name="InnerBorderBrush" DesignBrush="{StaticResource InnerBorderBrush}" DesignColor="{StaticResource BaseColor}" Input="{TemplateBinding Background}"/>
<!-- MouseOver 元素 绑定资源 Template中定义--> <c1:C1BrushBuilder x:Name="MouseOverBrush" DesignBrush="{StaticResource GeneralGradientOverBrush}" DesignColor="{StaticResource MouseOverColor}" Input="{TemplateBinding MouseOverBrush}"/> <c1:C1BrushBuilder x:Name="InnerBorderMouseOverBrush" DesignBrush="{StaticResource InnerBorderMouseOverBrush}" DesignColor="{StaticResource MouseOverColor}" Input="{TemplateBinding MouseOverBrush}"/>
<!-- PressedElement 元素 绑定资源 Template中定义--> <c1:C1BrushBuilder x:Name="PressedBrush" DesignBrush="{StaticResource GeneralGradientSelectedBackground}" DesignColor="{StaticResource SelectedColor}" Input="{TemplateBinding PressedBrush}"/> <c1:C1BrushBuilder x:Name="InnerBorderPressedBrush" DesignBrush="{StaticResource InnerBorderPressedBrush}" DesignColor="{StaticResource SelectedColor}" Input="{TemplateBinding PressedBrush}"/>
<!-- Checked 元素 绑定资源 Template中定义--> <c1:C1BrushBuilder x:Name="CheckedBrush" DesignBrush="{StaticResource GeneralGradientCheckedBrush}" DesignColor="{StaticResource SelectedColor}" Input="{TemplateBinding PressedBrush}"/>
<!-- Disabled 元素 绑定资源 UserControl.Resource中定义--> <SolidColorBrush x:Key="DisabledBrush" Color="#A5FFFFFF"/> <!-- C1ToolbarToggleButton的Padding属性值 --> <Thickness x:Key="ToolbarButtonPadding">2</Thickness> <!-- InnerBorder 的BorderThickness属性值 --> <Thickness x:Key="InnerBorderThickness">1</Thickness> <!--Normal , MouseOver , Pressed 状态下 OuterBorder的Background属性值 --> <LinearGradientBrush x:Key="GeneralGradientBrush" EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFFAFBFC" Offset="0"/> <GradientStop Color="#FFD1DCE8" Offset="1"/> </LinearGradientBrush> <LinearGradientBrush x:Key="GeneralGradientOverBrush" EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFDCEEF3" Offset="0"/> <GradientStop Color="#FFC5E3ED" Offset="1"/> </LinearGradientBrush> <LinearGradientBrush x:Key="GeneralGradientSelectedBackground" EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFC6E5F0" Offset="0"/> <GradientStop Color="#FFA8D4E3" Offset="1"/> </LinearGradientBrush> <!-- Normal , MouseOver , Pressed 状态下 OuterBorder,InnerBorder的DesignColor属性值--> <Color x:Key="BaseColor">#FFD1DCE8</Color> <Color x:Key="MouseOverColor">#FFBFE1EA</Color> <Color x:Key="SelectedColor">#FF8ED1E2</Color> <!-- Normal ,MouseOver,Pressed ,Checked 状态下 InnerBorder 的BorderBrush属性值 --> <SolidColorBrush x:Key="InnerBorderBrush" Color="#FFFAFBFC"/> <SolidColorBrush x:Key="InnerBorderMouseOverBrush" Color="#FFFAFBFC"/> <SolidColorBrush x:Key="InnerBorderPressedBrush" Color="#FFFAFBFC"/> <SolidColorBrush x:Key="GeneralGradientCheckedBrush" Color="#FF8ED1E2"/> <!-- 详见C1ToolbarCommandConverter类,用于绑定上下文 --> <c1:C1ToolbarCommandConverter x:Key="commandConverter"/>
具体效果请参考图(10)
图(10)
Binding部分:
1.以BackgroundElement为例
<c1:C1BrushBuilder x:Name="BackgroundBrush" DesignBrush="{StaticResource GeneralGradientBrush}" DesignColor="{StaticResource BaseColor}" Input="{TemplateBinding Background}"/>
<!-- Normal 元素 --> <Border x:Name="BackgroundElement" Background="{Binding Output, ElementName=BackgroundBrush}"> <Border BorderBrush="{Binding Output, ElementName=InnerBorderBrush}" BorderThickness="{StaticResource InnerBorderThickness}"/> </Border>
BackgroundElement元素的Background绑定包BackgroundBrush元素上,Path=Output
2.以LargeView为例
<StackPanel x:Name="LargeView" DataContext="{Binding Converter={StaticResource commandConverter}, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}"> <Image x:Name="img1" Source="{Binding LargeImageSource}" Stretch="None"/> <TextBlock x:Name="LargeText" TextAlignment="Center" Text="{Binding LabelTitle}"/> </StackPanel>
通过绑定使LargeView的DataContext设置为其父元素,由于上下文在VisualTree上的传递,最终达到C1ToolbarToggleButton本身。
所以Margin属性绑定到Padding属性,img1.Source绑定到LargeImageSource属性,LargeText.Text绑定到LabelTitle属性
附注:关于绑定的详细信息,不妨参考《深入浅出WPF》相关章节(便于理解较难的概念)
第五部分:视觉状态切换(VisualStateGroup.Transitions)
上面介绍了C1ToolbarToggleButton的Normal,MouseOver,Pressed,Disabled四种状态图,
现在讲解Normal-〉MouseOver的过程:
在CommonStates视觉状态组中,查看MouseOver状态,通过鼠标所在位置判断,启动StoryBoard,改变MouseOverElement.Visibility=Visible,改变状态为MouseOver。
<VisualState x:Name="Normal"/> <VisualState x:Name="MouseOver"> <Storyboard> <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="MouseOverElement"> <DiscreteObjectKeyFrame KeyTime="00:00:00"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState>
MouseOver->Pressed,Pressed->Normal等等状态同上,均是通过修改Visibility属性值来改变状态。
请注意Disabled状态:DisabledVisualElement位置为7,参考图(8),即DisabledVisualElement为最上层元素,IsEnabled=True时,颜色为半透明
三:自定义按钮示例
按钮样式一(共享源码):
修改的最主要的代码:
<Border x:Name="BackgroundElement" Background="{Binding Output, ElementName=BackgroundBrush}"> <Border > <Border.Background> <ImageBrush ImageSource="BtnBorder.png"/> </Border.Background> </Border> </Border>
效果图(11)
图(11)
按钮样式二(暂不共享源码,若需要请给我发邮件)
图(12)
本示例代码下载([November 29 2012]C1ToolbarToggleButtonStyle.zip):https://skydrive.live.com/?cid=B53A8D0EF3B97142&id=B53A8D0EF3B97142!110