使用模板在悬停/单击时更改按钮背景图像

时间:2012-03-28 18:21:05

标签: c# wpf

我有一个带有大量按钮的应用程序,我想用悬停/点击效果更加花哨。我希望有人可以使用样式模板,所以我不必为每个按钮编写触发器,但我有点陷入这个阶段。

我认为您可以通过以下代码片段了解我要完成的工作:

<Button BorderBrush="#00000000" Foreground="#00000000" Height="20" HorizontalContentAlignment="Right" IsEnabled="True" Name="btnMinimizeWindow" Width="21" DockPanel.Dock="Right" Margin="0,0,4,2" BorderThickness="0" Focusable="False" Style="{StaticResource ModernButton}">
    <Button.Background>
        <ImageBrush ImageSource="/MyApp;component/Images/btnMinimize.png" />
    </Button.Background>
    <Button.Resources>
        <DataTemplate x:Key="Default" >
            <Image Source="/MyApp;component/Images/btnMinimize.png" />
        </DataTemplate>
        <DataTemplate x:Key="Hover">
            <Image Source="/MyApp;component/Images/btnMinimizeHover.png" />
        </DataTemplate>
        <DataTemplate x:Key="Active">
            <Image Source="/MyApp;component/Images/btnMinimizeActive.png" />
        </DataTemplate>
    </Button.Resources>
</Button>

和模板文件:

<Style x:Key="ModernButton" TargetType="{x:Type Button}">
    <Setter Property="Padding" Value="1"/>
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Name="border" Background="{TemplateBinding Background}">
                    <ContentPresenter Name="Content" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                  Margin="{TemplateBinding Padding}"
                                  RecognizesAccessKey="True"
                                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">

                    </Trigger>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">

                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我该如何解决这个问题?甚至可以这样做,还是我必须用数百万个触发器来混乱我的代码?

1 个答案:

答案 0 :(得分:6)

您可以为状态正常 MouseOver 按下(可能还有更多)的背景图像定义attached properties。您可以将这些附加属性用于控件模板中单独的Image控件的Source属性,并修改例如VisualState更改时图像的不透明度。

示例样式:

<Style TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Disabled"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="mouseOverBackgroundImage" Storyboard.TargetProperty="Opacity" Duration="0:0:0.1" To="1"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="pressedBackgroundImage" Storyboard.TargetProperty="Opacity" Duration="0:0:0.1" To="1"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Image Name="normalBackgroundImage" Source="{TemplateBinding local:BackgroundImages.NormalBackgroundImage}"/>
                    <Image Name="mouseOverBackgroundImage" Source="{TemplateBinding local:BackgroundImages.MouseOverBackgroundImage}" Opacity="0"/>
                    <Image Name="pressedBackgroundImage" Source="{TemplateBinding local:BackgroundImages.PressedBackgroundImage}" Opacity="0"/>
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

在具有附加属性集的Button中使用:

<Button local:BackgroundImages.NormalBackgroundImage="C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg"
        local:BackgroundImages.MouseOverBackgroundImage="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"
        local:BackgroundImages.PressedBackgroundImage="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg"
        Content="Hello"/>

最后是那些附加属性的定义:

public static class BackgroundImages
{
    public static readonly DependencyProperty NormalBackgroundImageProperty =
        DependencyProperty.RegisterAttached("NormalBackgroundImage", typeof(ImageSource), typeof(BackgroundImages));

    public static readonly DependencyProperty MouseOverBackgroundImageProperty =
        DependencyProperty.RegisterAttached("MouseOverBackgroundImage", typeof(ImageSource), typeof(BackgroundImages));

    public static readonly DependencyProperty PressedBackgroundImageProperty =
        DependencyProperty.RegisterAttached("PressedBackgroundImage", typeof(ImageSource), typeof(BackgroundImages));

    public static ImageSource GetNormalBackgroundImage(DependencyObject obj)
    {
        return (ImageSource)obj.GetValue(NormalBackgroundImageProperty);
    }

    public static void SetNormalBackgroundImage(DependencyObject obj, ImageSource value)
    {
        obj.SetValue(NormalBackgroundImageProperty, value);
    }

    public static ImageSource GetMouseOverBackgroundImage(DependencyObject obj)
    {
        return (ImageSource)obj.GetValue(MouseOverBackgroundImageProperty);
    }

    public static void SetMouseOverBackgroundImage(DependencyObject obj, ImageSource value)
    {
        obj.SetValue(MouseOverBackgroundImageProperty, value);
    }

    public static ImageSource GetPressedBackgroundImage(DependencyObject obj)
    {
        return (ImageSource)obj.GetValue(PressedBackgroundImageProperty);
    }

    public static void SetPressedBackgroundImage(DependencyObject obj, ImageSource value)
    {
        obj.SetValue(PressedBackgroundImageProperty, value);
    }
}