在Wp7中按鈕的默認效果是這樣的:
黑色主題普通/按下
白色主題普通/按下
普通狀態的背景色前景很容已通過修改Background、Foreground、BorderBrush等屬性實現
<Button Content="Button" Height="72" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="160"
Background="Red" BorderBrush="Green" Foreground="Blue"
Click="button1_Click" />
但是按下狀態的效果並未改變,仍然是默認效果
按下效果可以通過Blend修改按鈕樣式來實現
默認的按鈕樣式是這樣的
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
<Setter Property="Padding" Value="10,3,10,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
將<VisualState x:Name="Pressed">下的Backgournd屬性改成這樣
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="#600010"/>
按下效果如下:
如果需要加入兩個按鈕,他們的按下效果不完全一樣,例如一個按下背景是棕色,一個是紫色就需要寫兩個Style。
僅僅這點差異,就需要寫一個50行的style,這對代碼維護顯然是不利的。最終找到了一個解決方案。步驟如下
1. 創建一個Button的派生類
public class ButtonEx : Button
{
#region Fields
public static readonly DependencyProperty PressedBackgroundProperty =
DependencyProperty.Register("PressedBackground",
typeof(Brush),
typeof(ButtonEx),
new PropertyMetadata(new SolidColorBrush(Colors.White), null));
public static readonly DependencyProperty PressedForegroundProperty =
DependencyProperty.Register("PressedForeground",
typeof(Brush),
typeof(ButtonEx),
new PropertyMetadata(new SolidColorBrush(Colors.Black), null));
public static readonly DependencyProperty PressedBorderBrushProperty =
DependencyProperty.Register("PressedBorderBrush",
typeof(Brush),
typeof(ButtonEx),
new PropertyMetadata(new SolidColorBrush(Colors.Black), null));
public static readonly DependencyProperty InvisibleMarginProperty =
DependencyProperty.Register("InvisibleMargin",
typeof(Thickness),
typeof(ButtonEx),
new PropertyMetadata(new Thickness(12), null));
#endregion
#region Properties
public Brush PressedBackground
{
set { SetValue(PressedBackgroundProperty, value); }
get { return (Brush)GetValue(PressedBackgroundProperty); }
}
public Brush PressedForeground
{
set { SetValue(PressedForegroundProperty, value); }
get { return (Brush)GetValue(PressedForegroundProperty); }
}
public Brush PressedBorderBrush
{
set { SetValue(PressedBorderBrushProperty, value); }
get { return (Brush)GetValue(PressedBorderBrushProperty); }
}
public Thickness InvisibleMargin
{
set { SetValue(InvisibleMarginProperty, value); }
get { return (Thickness)GetValue(InvisibleMarginProperty); }
}
#endregion
}
2. 通過blend創建一個ButtonEx的默認樣式,改成這樣
<Style x:Key="buttonExStyle" TargetType="my:ButtonEx">
<Setter Property="InvisibleMargin" Value="12" />
<Setter Property="PressedBackground" Value="{StaticResource PhoneAccentBrush}" />
<Setter Property="PressedForeground" Value="{StaticResource PhoneBackgroundBrush}" />
<Setter Property="PressedBorderBrush" Value="{StaticResource PhoneForegroundBrush}" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
<Setter Property="Padding" Value="10,3,10,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="my:ButtonEx">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PressedForeground}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PressedBackground}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PressedBorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{TemplateBinding InvisibleMargin}">
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
3. UI中加入一個ButtonEx
<my:ButtonEx Content="Button" Grid.Row="1" Height="72" HorizontalAlignment="Left" Margin="181,121,0,0" x:Name="buttonEx1" VerticalAlignment="Top" Width="160"
Background="Red" PressedBackground="Green" Style="{StaticResource buttonExStyle}" />
效果如下(普通、按下):
同樣可以很方便地修改按鈕風格,例如
<my:ButtonEx Content="Button" Height="72" HorizontalAlignment="Left" x:Name="buttonEx1" VerticalAlignment="Top" Width="160"
Style="{StaticResource buttonExStyle}"
Click="button1_Click" >
<my:ButtonEx.Background >
<ImageBrush ImageSource="/ListCheckBox;component/Images/Desert.jpg" />
</my:ButtonEx.Background>
<my:ButtonEx.PressedBackground >
<ImageBrush ImageSource="/ListCheckBox;component/Images/Koala.jpg" />
</my:ButtonEx.PressedBackground>
</my:ButtonEx>
PS:樣式的定義可以放在./Themes/generic.xaml中。將Key去掉,編譯選項設爲Resource。這樣這個Style就作爲ButtonEx的默認Style了。