how to make a image button that change the image w

2019-02-11 07:28发布

I am trying to make an image button that changes the image when the mouse is over the button, i tried few things

this is the last thing I tried but it doesn't work:

<Button Name="fileNameLink" Margin="15,6,30,1" VerticalAlignment="Top"    Click="btnMinimize_Click" MaxWidth="250" Background="Transparent" Cursor="Hand" Visibility="Visible" Height="16">
                    <Button.Template>
                        <ControlTemplate TargetType="Button">
                            <StackPanel>
                                <Image Name="image1"  Source="{StaticResource Minimize1}" Stretch="None" Visibility="Collapsed"/>
                                <Image Name="image2" Source="{StaticResource Minimize2}" Stretch="None" Visibility="Visible"/>
                                <StackPanel.Triggers>
                                    <Trigger Property="IsMouseOver" Value="true">
                                        <Setter TargetName="image1" Property="Visibility" Value="Visible"/>
                                        <Setter TargetName="image2" Property="Visibility" Value="Collapsed"/>
                                        </Trigger>
                                </StackPanel.Triggers>
                            </StackPanel>
                        </ControlTemplate>
                    </Button.Template>
                    <Button.Style>
                        <Style TargetType="Button">
                            <Style.Triggers>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>

i am tring to use the XAML only, without the cs file Thanks

4条回答
祖国的老花朵
2楼-- · 2019-02-11 07:47

Here is another approach to handle it using a specialized style. It should be pointed out, that this could be further improved with using attached properties for customizing the image files properly.

<Style x:Key="ButtonStyle" TargetType="Button">
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid>
                    <Rectangle Fill="Transparent"/>
                    <Image x:Name="img" Width="64" Height="64" Source="a.jpg"/>
                </Grid>
                <DataTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="img" Property="Source" Value="b.jpg"/>
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

The Rectangle is important for the hit testing, otherwise the IsMouseOver won't trigger. And the Stretch on the ContentAlignment is necessary otherwise the ContentPresenter of the button would not span the whole button, therefore IsMouseOver wouldn't trigger again.

查看更多
来,给爷笑一个
3楼-- · 2019-02-11 07:58

You will need a helper class to attach the image source property per button state and a style for your button. Put the helper class in a Helpers folder in your WPF project.

Helper class

public static class ImageLoader
{
    public static ImageSource GetDefaultImage(DependencyObject obj)
    {
        return (ImageSource)obj.GetValue(DefaultImageProperty);
    }
    public static void SetDefaultImage(DependencyObject obj, ImageSource value)
    {
        obj.SetValue(DefaultImageProperty, value);
    }

    public static readonly DependencyProperty DefaultImageProperty =
        DependencyProperty.RegisterAttached(
        "DefaultImage",
        typeof(ImageSource),
        typeof(ImageLoader),
        new UIPropertyMetadata(null));

    public static ImageSource GetHoverImage(DependencyObject obj)
    {
        return (ImageSource)obj.GetValue(HoverImageProperty);
    }
    public static void SetHoverImage(DependencyObject obj, ImageSource value)
    {
        obj.SetValue(HoverImageProperty, value);
    }

    public static readonly DependencyProperty HoverImageProperty =
        DependencyProperty.RegisterAttached(
        "HoverImage",
        typeof(ImageSource),
        typeof(ImageLoader),
        new UIPropertyMetadata(null));

    public static ImageSource GetDisabledImage(DependencyObject obj)
    {
        return (ImageSource)obj.GetValue(DisabledImageProperty);
    }
    public static void SetDisabledImage(DependencyObject obj, ImageSource value)
    {
        obj.SetValue(DisabledImageProperty, value);
    }

    public static readonly DependencyProperty DisabledImageProperty =
        DependencyProperty.RegisterAttached(
        "DisabledImage",
        typeof(ImageSource),
        typeof(ImageLoader),
        new UIPropertyMetadata(null));
}

Button Style

<ResourceDictionary ...
                    xmlns:helper="clr-namespace:MySolution.MyWPFProject.Helpers"
                    ...
                    >

    <Style TargetType="{x:Type Button}" x:Key="MyButtonStyle">
        ...
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <ContentPresenter Name="content" 
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          Margin="{TemplateBinding Padding}"
                                          RecognizesAccessKey="True"
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      />
                        <Border>
                            <!-- Default image -->
                            <Image Name="image"  Source="{TemplateBinding helper:ImageLoader.DefaultImage}" />
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Cursor" Value="Hand" />
                            <!-- Hover image -->
                            <Setter TargetName="image" Property="Source" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=(helper:ImageLoader.HoverImage)}" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <!-- Disabled image -->
                            <Setter TargetName="image" Property="Source" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=(helper:ImageLoader.DisabledImage)}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Usage

<UserControl ...
             xmlns:helper="clr-namespace:MySolution.MyWPFProject.Helpers"
             ...
             >
        <UserControl.Resources >
                <ResourceDictionary Source="Path-to-my-button-style.xaml" />
        </UserControl.Resources>
        ...
        <Button helper:ImageLoader.DefaultImage="Resources/Images/MyDefaultImage.png"
                helper:ImageLoader.HoverImage="Resources/Images/MyHoverImage.png"
                helper:ImageLoader.DisabledImage="Resources/Images/MyDisabledImage.png"
                Style="{DynamicResource MyButtonStyle}" />

        ...
查看更多
Deceive 欺骗
4楼-- · 2019-02-11 08:01

Your Trigger's are applied to the StackPanel. It needs to be set on the ControlTemplate

Try:

<Button Name="fileNameLink"
        Height="16"
        MaxWidth="250"
        Margin="15,6,30,1"
        VerticalAlignment="Top"
        Click="btnMinimize_Click"
        Background="Transparent"
        Cursor="Hand"
        Visibility="Visible">
  <Button.Template>
    <ControlTemplate TargetType="Button">
      <StackPanel>
        <Image Name="image1"
                Source="{StaticResource Minimize1}"
                Stretch="None"
                Visibility="Collapsed" />
        <Image Name="image2"
                Source="{StaticResource Minimize2}"
                Stretch="None"
                Visibility="Visible" />
      </StackPanel>
      <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver"
                  Value="true">
          <Setter TargetName="image1"
                  Property="Visibility"
                  Value="Visible" />
          <Setter TargetName="image2"
                  Property="Visibility"
                  Value="Collapsed" />
        </Trigger>
      </ControlTemplate.Triggers>
    </ControlTemplate>
  </Button.Template>
</Button>

In such cases. You can just use the Trigger to set the Image's source thereby not having to play with switching Visibility on multiple UI element's.

something like:

<Button Name="fileNameLink"
        Height="16"
        MaxWidth="250"
        Margin="15,6,30,1"
        VerticalAlignment="Top"
        Click="btnMinimize_Click"
        Background="Transparent"
        Cursor="Hand"
        Visibility="Visible">
  <Button.Template>
    <ControlTemplate TargetType="Button">
      <Image Name="image"
              Source="{StaticResource Minimize1}"
              Stretch="None" />
      <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver"
                  Value="true">
          <Setter TargetName="image"
                  Property="Source"
                  Value="{StaticResource Minimize2}" />
        </Trigger>
      </ControlTemplate.Triggers>
    </ControlTemplate>
  </Button.Template>
</Button>
查看更多
等我变得足够好
5楼-- · 2019-02-11 08:02

You can achieve this by Image style:

<Button Name="fileNameLink" VerticalAlignment="Top" Click="btnMinimize_Click" MaxWidth="250" Height="100">          
    <Button.Content>
        <StackPanel>
            <Image Name="image1"  Source="{StaticResource Minimize1}" Stretch="None" >
                <Image.Style>
                    <Style TargetType="Image">
                        <Setter Property="Visibility" Value="Visible" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" Value="True">
                                <Setter Property="Visibility" Value="Collapsed" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Image.Style>
            </Image>
            <Image Name="image2" Source="{StaticResource Minimize2}" Stretch="None" >
                <Image.Style>
                    <Style TargetType="Image">
                        <Setter Property="Visibility" Value="Collapsed" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" Value="True">
                                <Setter Property="Visibility" Value="Visible" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Image.Style>
            </Image>                   
        </StackPanel>
    </Button.Content>           
</Button>
查看更多
登录 后发表回答