在Silverlight中使用光栅图像作为按钮

时间:2011-11-01 18:46:29

标签: silverlight windows-phone-7 expression-blend

我从photoshop为我提供了不同按钮状态的按钮。

看起来像这样

<Button x:Name="ResultsBtn" Click="ResultsBtn_Click" FontSize="27" BorderThickness="0"  Padding="-10"  Margin="-10">
    <Grid>
        <Image Source="..But_01_Idle.png"  Width="496"/>
        <TextBlock Text="Results" Margin="174,21,172,23" Width="90" Height="40" Foreground="White" />
    </Grid>
</Button>

该按钮只适用于一个州。

我想使用表达式混合来记录状态并更改图像背后的背景(在本例中为外部发光)或更改状态更改时的源。

我注意到混合似乎只记录位置和变换,而不是属性的变化。

我应该在代码中执行此操作,还是以特定格式发送photoshop文件,以便可以通过混合自动转换

3 个答案:

答案 0 :(得分:2)

好吧,我对Blend感到非常惊讶:它似乎不允许你为源属性设置动画。但是,Silverlight允许它,所以我假设WP7也允许它;这看起来像Blend 4中的一个错误。但是,我仍然不建议使用基于图像的方法,因为当显着放大或缩小时,图像会变形并且看起来很糟糕/像素化。更好的方法是编辑按钮的控件模板并对其进行修改以匹配您的参考图稿。你甚至可以使用File - &gt;导入Adobe Photoshop File ...将基本图稿拉入Blend。然后,只需将其拖入控件模板即可。

如果你没有设置使用图像(这会增加XAP的大小并实际导致加载UserControl加载时间变慢),你可以在Blend中按照以下步骤进行:

  1. 创建一个新项目并向根视觉元素添加一个Button。
  2. 创建一个名为Images的新项目文件夹,并为其添加两个图像。 (我使用了Sample Pictures文件夹中的Koala.jpg和Penguins.jpg。)
  3. 右键单击按钮,然后选择编辑模板 - &gt;编辑副本......
  4. 默认模板将包含一个包含名为Background的边框的网格。在Background边框内部是一个包含Rectangle和另一个Border的Grid。删除这两个最内层的元素。
  5. 现在添加一个Image作为Background border的Grid的子项。
  6. 现在切换到XAML编辑器并修改控件模板的可视状态组以匹配以下代码。 (查找两个“已添加”注释块。)
  7. 运行项目。鼠标悬停在你身上你会看到企鹅。单击并按住鼠标左键,您将看到一只考拉。
<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="Button">
      <Grid>
        <VisualStateManager.VisualStateGroups>
          <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal"/>
            <VisualState x:Name="MouseOver">

             <!-- Added --> 
             <Storyboard>
               <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TheImage" Storyboard.TargetProperty="Source">
                 <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="/Images/Penguins.jpg"/> 
               </ObjectAnimationUsingKeyFrames>
             </Storyboard>
             <!-- End of Added -->

             </VisualState>
             <VisualState x:Name="Pressed">
               <Storyboard>
                 <ColorAnimation Duration="0" To="#FF6DBDD1" Storyboard.TargetProperty="(Border.Background).**(SolidColorBrush.Color)" Storyboard.TargetName="Background"/>

                 <!-- Added -->
                 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TheImage" Storyboard.TargetProperty="Source">
                   <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="/Images/Koala.jpg"/>  
                 </ObjectAnimationUsingKeyFrames>**
                 <!-- End of Added -->

               </Storyboard>
             </VisualState>
             <VisualState x:Name="Disabled">
               <Storyboard>
                 <DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="FocusStates">
              <VisualState x:Name="Focused">
                <Storyboard>
                  <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Unfocused"/>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
        <Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="White" CornerRadius="3">
          <Grid Background="{TemplateBinding Background}" Margin="1">
            <Image x:Name="TheImage" Source=""/>
          </Grid>
        </Border>
        <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        <Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" IsHitTestVisible="false" Opacity="0" RadiusY="3" RadiusX="3"/>
        <Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Margin="1" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#FF6DBDD1" StrokeThickness="1"/>
      </Grid>
    </ControlTemplate>
  </Setter.Value>
</Setter>

答案 1 :(得分:1)

视觉状态是使用动画构建的,因此您只能更改可以设置动画的内容(并期望获得典型结果)。我从来没有尝试过,但我的直觉告诉我一个图像源无法动画,因此VSM可能不是一种可行的方法来管理它。

然而,不透明度可以设置动画,因此您可以在ytour按钮中同时使用两个图像,并使用状态控制其不透明度。只是一个想法。

答案 2 :(得分:0)

您必须创建一个ControlTemplate:

按钮代码:

<Button Template={DynamicResource ButtonTemplate}/>

在资源词典中:

<ControlTemplate x:Key="ButtonTemplate" {x:Type Button}>
    <Grid Padding="-10"  Margin="-10">
        <Image x:Name="IdleState" Source="..But_01_Idle.png"  Width="496"/>
        <Image x:Name="MouseOverState" Source="..But_01_MouseOver.png" Width="496"/>
        <Image x:Name="PressedState..." etc/>
        <TextBlock Text="Results" Margin="174,21,172,23" Width="90" Height="40" Foreground="White" FontSize="27"/>
    </Grid>
</ControlTemplate>

然后,在Blend中,编辑模板,你会发现迈克所说的状态。使用“属性”面板可隐藏/显示要设置样式的每个状态的图像,并且应该完成。