单击更改 WPF 图像按钮的图像

Change the images of WPF image button on click

我想创建一个图像按钮控件,单击按钮时图像源会发生变化。通过在控件模板触发器中直接传递 normal/clicked 图片路径值很容易创建。

但我的要求是创建一个通用图像按钮,可以在多个地方使用不同的 normal/clicked 图像。这样我就可以在按钮控件本身中传递两个图像源。

 <Button x:Name="buttonImage" local:ImageButton.NormalImage="Images/ImgA.png" local:ImageButton.PressedImage="Images/ImgB.png" Style="{DynamicResource ImageButtonStyle}" />

我正在尝试使用依赖附加属性并通过与祖先的路径绑定实现正常图像,但无法在 IsPressed 触发器上实现按下图像。在下面的代码中,ImageButton 是附加属性所在的 class。

 <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border x:Name="BtnBorder"  BorderThickness="1">
                        <Image  x:Name="ButtonImage" Source="{Binding Path=(local:ImageButton.NormalImage), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="16" Height="16"/>
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter TargetName="ButtonImage" Property="Source" Value="{Binding local:ImageButton.PressedImage, RelativeSource= {RelativeSource TemplatedParent}}" />
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="BtnBorder" Property="BorderBrush" Value="Red" />
                        </Trigger>

                    </ControlTemplate.Triggers>

                </ControlTemplate>
            </Setter.Value>
        </Setter>

如果您知道实现此功能的更好方法,请告诉我。

以下代码适用于我:

public class ImageButton : ButtonBase
{
    private const string NormalImageSourcePropertyName = "NormalImageSource";
    private const string MouseOverImageSourcePropertyName = "MouseOverImageSource";
    private const string MouseOverPressedImageSourcePropertyName = "MouseOverPressedImageSource";
    private const string PressedImageSourcePropertyName = "PressedImageSource";

    public static readonly DependencyProperty NormalImageSourceProperty =
        DependencyProperty.Register(NormalImageSourcePropertyName, typeof(ImageSource), typeof(ImageButton));
    public static readonly DependencyProperty MouseOverImageSourceProperty =
        DependencyProperty.Register(MouseOverImageSourcePropertyName, typeof(ImageSource), typeof(ImageButton));
    public static readonly DependencyProperty MouseOverPressedImageSourceProperty =
        DependencyProperty.Register(MouseOverPressedImageSourcePropertyName, typeof(ImageSource), typeof(ImageButton));
    public static readonly DependencyProperty PressedImageSourceProperty =
        DependencyProperty.Register(PressedImageSourcePropertyName, typeof(ImageSource), typeof(ImageButton));

    static ImageButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
    }

    public ImageSource NormalImageSource
    {
        get
        {
            return (ImageSource)GetValue(NormalImageSourceProperty);
        }
        set
        {
            SetValue(NormalImageSourceProperty, value);
        }
    }

    public ImageSource MouseOverImageSource
    {
        get
        {
            return (ImageSource)GetValue(MouseOverImageSourceProperty);
        }
        set
        {
            SetValue(MouseOverImageSourceProperty, value);
        }
    }

    public ImageSource MouseOverPressedImageSource
    {
        get
        {
            return (ImageSource)GetValue(MouseOverPressedImageSourceProperty);
        }
        set
        {
            SetValue(MouseOverPressedImageSourceProperty, value);
        }
    }

    public ImageSource PressedImageSource
    {
        get
        {
            return (ImageSource)GetValue(PressedImageSourceProperty);
        }
        set
        {
            SetValue(PressedImageSourceProperty, value);
        }
    }
}

风格是

<Style TargetType="{x:Type local:ImageButton}">
    <Setter Property="IsTabStop" Value="False"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ImageButton}">
                <Image x:Name="ButtonImage" Source="{TemplateBinding NormalImageSource}" SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
                <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True"/>
                            <Condition Property="IsPressed" Value="False"/>
                        </MultiTrigger.Conditions>
                        <Setter TargetName="ButtonImage" Property="Source" Value="{Binding Path=MouseOverImageSource, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True"/>
                            <Condition Property="IsPressed" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter TargetName="ButtonImage" Property="Source" Value="{Binding Path=MouseOverPressedImageSource, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="False"/>
                            <Condition Property="IsPressed" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter TargetName="ButtonImage" Property="Source" Value="{Binding Path=PressedImageSource, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

它比你的问题更详细一些,因为它支持 4 张图像,使悬停时的用户体验更好。

我使用它的例子:

<local:ImageButton DockPanel.Dock="Left" x:Name="PART_CloseButton" Height="13" Width="13" Margin="3" NormalImageSource="/ICeTechControlLibrary;component/Images/exit-small.png" MouseOverImageSource="/ICeTechControlLibrary;component/Images/exit-small-hover.png" MouseOverPressedImageSource="/ICeTechControlLibrary;component/Images/exit-small-hover.png" PressedImageSource="/ICeTechControlLibrary;component/Images/exit-small-hover.png" />