Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Image Control with Click Event

Tags:

wpf

xaml

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?

like image 228
Jesse Hallam Avatar asked Nov 11 '10 04:11

Jesse Hallam


3 Answers

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>
like image 196
C8H10N4O2 Avatar answered Oct 19 '22 05:10

C8H10N4O2


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.

like image 26
Shawn Mclean Avatar answered Oct 19 '22 04:10

Shawn Mclean


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.

like image 43
Semm Avatar answered Oct 19 '22 06:10

Semm