Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
454 views
in Technique[技术] by (71.8m points)

c# - Change button background image on hover/click using a template

I have got an application with tons and tons of buttons which I want to make a bit more fancy with hover/click effects. I was hoping one could use a styling template for this so I wouldn't have to write the triggers for each and every button, but I am kind of stuck in this phase.

I think you get the general idea of what I am trying to accomplish here with this code snippet:

<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>

and the template file:

<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>

How do I go about this problem? Is it even possible to do it this way or do I have to clutter my code with millions of triggers?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could define attached properties for the background images for states Normal, MouseOver and Pressed (and maybe more). You would use these attached properties for the Sourceproperty of separate Image controls in a control template and modify e.g. the Image's Opacity when the VisualState changes.

An example style:

<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>

used in a Button with the attached properties set:

<Button local:BackgroundImages.NormalBackgroundImage="C:UsersPublicPicturesSample PicturesTulips.jpg"
        local:BackgroundImages.MouseOverBackgroundImage="C:UsersPublicPicturesSample PicturesDesert.jpg"
        local:BackgroundImages.PressedBackgroundImage="C:UsersPublicPicturesSample PicturesPenguins.jpg"
        Content="Hello"/>

And finally the definition of those attached properties:

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);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...