locked
[FAQ] 如何修改Metro中已有控件的样式,比如让按钮在按下时改变字体颜色? RRS feed

答案

  • 答:

    对于一般修改控件的一些可视状态(所谓可视状态 (VisualState)指:按下,鼠标经过,未激活,键盘焦点等)时的样式通常有一些常见的方式i。
    不过在这之前,您需要要了解一下相关知识:

    1. 关于控件模板的知识,即如果自定义通常情况下的控件的样式以及内部内容的样式。
    文档: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh465318
    示例:http://code.msdn.microsoft.com/windowsapps/XAML-user-and-custom-a8a9505e

    2. 关于VisualState的知识。由于Metro中样式没有触发器,因此在发生特殊状态时对于样式的改变需要通过VisualState来实现。具体用法是在ControlTemplate中建立各种情况的VisualState来进行模板的改变。

    以下为VisualState类介绍和具体用法的文档: http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.visualstate.aspx
    在Control Template中同样有一个非常详细的VisualState的用法示例可以用作参考:http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh465374

    通常来说要达到控件在某些状态下的变化,通常有以下两步:

    1. 在Blend中可以导出控件默认样式模板的代码。(下面会给出Button控件和数据列表ListView控件的模板导出方法)
    2. 在VisualState中找到要修改的状态,并且修改具体代码。

      以下几个MSDN论坛上已经回答的问题可以用作参考:
        这是设置Button被点击时修改字体颜色的回答:
        http://social.msdn.microsoft.com/Forums/zh-CN/metroappzhcn/thread/ca0212f0-f7e2-4bc0-bdbb-a9784d2eaa23
        这是以图片作为Button,设置Button被按下和抬起时图片不变的回答:
        http://social.msdn.microsoft.com/Forums/zh-CN/metroappzhcn/thread/860dbcd7-412a-4eb2-96a0-d164edd1da25
        这是设置Button按下和抬起时显示不一样图片的回答:
        http://social.msdn.microsoft.com/Forums/zh-CN/metroappzhcn/thread/37fa7386-0406-4265-82c4-993ec7be458e



    1、对于默认样式模板的导出:

    • Button控件默认模板导出,在Blend中新建XAML项目,随意放置一个Button,右击其,选择 编辑模板>编辑副本, 既可以在XAML代码模式下看到其Button的默认样式代码。

    导出后,按钮的默认样式模板如下:

    <Style TargetType="Button">
      <Setter Property="Background" Value="{StaticResource ButtonBackgroundThemeBrush}"/>
      <Setter Property="Foreground" Value="{StaticResource ButtonForegroundThemeBrush}"/>
      <Setter Property="BorderBrush" Value="{StaticResource ButtonBorderThemeBrush}"/>
      <Setter Property="BorderThickness" Value="{StaticResource ButtonBorderThemeThickness}"/>
      <Setter Property="Padding" Value="12,4,12,4"/>
      <Setter Property="HorizontalAlignment" Value="Left"/>
      <Setter Property="VerticalAlignment" Value="Center"/>
      <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
      <Setter Property="FontWeight" Value="SemiBold"/>
      <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="Button">
            <Grid>
              <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                  <VisualState x:Name="Normal"/>
                  <VisualState x:Name="PointerOver">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPointerOverBackgroundThemeBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPointerOverForegroundThemeBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                  <VisualState x:Name="Pressed">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPressedBackgroundThemeBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPressedForegroundThemeBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                  <VisualState x:Name="Disabled">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonDisabledBackgroundThemeBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Border">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonDisabledBorderThemeBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonDisabledForegroundThemeBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="FocusStates">
                  <VisualState x:Name="Focused">
                    <Storyboard>
                      <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhite"/>
                      <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlack"/>
                    </Storyboard>
                  </VisualState>
                  <VisualState x:Name="Unfocused"/>
                  <VisualState x:Name="PointerFocused"/>
                </VisualStateGroup>
              </VisualStateManager.VisualStateGroups>
              <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="3">
                <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
              </Border>
              <Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
              <Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
            </Grid>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

    • ListView控件对于自身的默认样式导出如上。ItemContainer的默认样式的导出,如上操作,在右击后选择 编辑其他模板>编辑生成的项目容器(ItemContainerStyle)>编辑副本,既可以导出。

    2、对于默认样式模板的修改:

    例如:按钮在按下时改变字体颜色?

    这就需要我们在导出的按钮默认样式模板中修改 x:Name="Pressed" 的可视状态内容,我们可以将Foreground下变换的值改为Green,即:

    <VisualState x:Name="Pressed">
      <Storyboard>
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPressedBackgroundThemeBrush}"/>
         </ObjectAnimationUsingKeyFrames>
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
            <DiscreteObjectKeyFrame KeyTime="0" Value="Green"/>
         </ObjectAnimationUsingKeyFrames>
      </Storyboard>
    </VisualState>

    3、最终效果:

    -----------------------------------------------------------------------------------------

    另外,Blend本身就是一个非常好的UI设计工具,在Blend中完全可以完成这些控件的自定义样式,例如上面所说的修改按钮按下颜色,在这个帖子中, http://social.msdn.microsoft.com/Forums/zh-CN/metroappzhcn/thread/ca0212f0-f7e2-4bc0-bdbb-a9784d2eaa23 Lingling Tong 给出了一个Blend下修改的方法,请参考。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us


    2012年6月29日 4:05
    版主