WPF Image Control with Click Event

2019-01-16 23:35发布

问题:

I wish to use an <Image> in my WPF Application which responds to mouse clicks. Only the 'Mouse Up' and 'Moue Down' events are available out of the box. I find this rather particular. Is there a way to extend the control or a way to use another control to give the same effect?

回答1:

To expand on Shawn Mclean's answer, one of the great capabilities of WPF is the ability to leverage the behavior of a control while completely changing the look of that control. If you want to create an image that behavior just like a button (complete with click events, command binding, default button assignment, etc.) you can place an image in a button control and restyle that button to remove the button "chrome". This will give you the nice API of a button with the look you desire. You can reuse this style and this approach will reduce the need to create event handlers in your code behind if you have commands to bind to your new image buttons.

Creating such a style is pretty easy. Simply create a new style resource with a named key in a resource and assign this resource to the Style property of your buttons. Here is an example I threw together:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ButtonStyleTestApp.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">

<Window.Resources>
    <Style x:Key="NoChromeButton" TargetType="{x:Type Button}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid x:Name="Chrome" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>                          
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="#ADADAD"/>
                            <Setter Property="Opacity" TargetName="Chrome" Value="0.5"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid x:Name="LayoutRoot" Background="#FF44494D">
    <Button Style="{DynamicResource NoChromeButton}" Click="ButtonClicked" >
        <Image Source="Desert.png" Stretch="None"/>
    </Button>
</Grid>
</Window>


回答2:

Use MouseUp. You cannot tab through or focus on the Image control anyways so thats the only way to click it.

Another option is to just put the image in a button and remove all styles by editing the control template so it seems like just an image. That way, you can focus on it using the keyboard.



回答3:

You can use a set of 4 handlers and 2 boolean variables:

booleans:

  1. IsClicked
  2. IsEntered

handlers:

  1. OnMouseDown- sets IsClicked true;
  2. OnMouseEnter- sets IsEntered true;
  3. OnMouseLeave - sets IsEntered false;
  4. OnMouseUp - if (IsClicked && IsEntered){ /TODO your logic/} and then sets IsClicked false;

This construction implements the functionality of the classic click.



回答4:

  1. OnMouseLeave - also set is isClicked to false; Otherwise you can click mouse away and release mouse. Then click mouse over and release mouse to still make a click happen.


标签: wpf xaml