21

I'm putting a WPF application together in which I have an image control which I want to bind a custom command object to from my view model that will execute when the image is clicked. I have exposed the command object from my view model and just need to bind it to the image control.

Is it possible to bind this command object to an image control? If so any advice would be appreciated.

ASh
  • 34,632
  • 9
  • 60
  • 82
David
  • 3,519
  • 1
  • 24
  • 30

5 Answers5

51

Here's yet another solution I personally love to use most of the time if I want an image with command without enclosing it in another control.

<Image Source="Images/tick.png" Cursor="Hand" Tooltip="Applies filter">
     <Image.InputBindings>
          <MouseBinding Gesture="LeftClick" Command="{Binding ApplyFilter, Mode=OneTime}" />
     </Image.InputBindings>
</Image>

I set its properties Hand and Tooltip so that it's more clear that it's an action and not a static image.

Ondrej Janacek
  • 12,486
  • 14
  • 59
  • 93
  • 2
    As far as I can see, this solution executes the command already when the mouse button is pressed down. I would expect that the execution is started when the mouse button is released. Like the behavior of a button. Just a remark! – Florian Sep 24 '15 at 13:33
  • 3
    @Florian Thanks, I didn't notice that. I don't usually stop in the middle of clicking something. – Ondrej Janacek Sep 24 '15 at 16:50
  • Nice approach. I am still concerned about the button-like features I have to implement for a full button-like experience. Some are obvious and I can manage, but some are not and they might end up in poor quality experience for some cases. So, for maintainability and accessibility I prefer to work with a button image. But again, your approach is functional and original. – profimedica Dec 18 '18 at 07:20
22

You need to put the image in a button, and bind the button to the command:

<Button Command="{Binding MyCommand}">
    <Image Source="myImage.png" />
</Button>

If you don't want the standard button chrome, just change the template of the button with something like that:

<ControlTemplate x:Key="tplFlatButton" TargetType="{x:Type Button}">
    <Border Width="{TemplateBinding Width}"
            Height="{TemplateBinding Height}"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}">
        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                          TextElement.Foreground="{TemplateBinding Foreground}"
                          TextElement.FontFamily="{TemplateBinding FontFamily}"
                          TextElement.FontSize="{TemplateBinding FontSize}"
                          TextElement.FontStretch="{TemplateBinding FontStretch}"
                          TextElement.FontWeight="{TemplateBinding FontWeight}"/>
    </Border>
</ControlTemplate>

Note that you will also need to change other properties to override the default button style, otherwise the template above will use the default button background and border:

<Style x:Key="stlFlatButton" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="{x:Null}" />
    <Setter Property="BorderBrush" Value="{x:Null}" />
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="Template" Value="{StaticResource tplFlatButton}" />
</Style>
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
13

It can be simpler to avoid using a button and use a Hyperlink instead:

<TextBlock DockPanel.Dock="Top">
   <Hyperlink Command="{Binding SomeCommand}">
      <Image Source="image.png" />
   </Hyperlink>
</TextBlock>

Note that this will render the hyperlink with the default text decoration, so you'll want to add a style that removes that - putting this in the resource dictionary of the containing element will do the trick:

<Style x:Key={x:Type Hyperlink}" TargetType="Hyperlink">
   <Setter Property="TextDecorations"
           Value="{x:Null}" />
</Style>
user1069816
  • 2,763
  • 2
  • 26
  • 43
Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
6

Simplified version of answer from @Robert Rossney:

<TextBlock>
    <Hyperlink Command="{Binding SomeCommand}" TextDecorations="{x:Null}">
        <Image Source="{StaticResource image.png}" Width="16" />
    </Hyperlink>
</TextBlock>

The best way to include an image is to use a {StaticResource x}, see WPF image resources

Community
  • 1
  • 1
Contango
  • 76,540
  • 58
  • 260
  • 305
1

reset control template of the button and use image in control template..

 <Button Width="100" Height="100" Command="{Binding SampleCommand}">
            <Button.Template>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Image Stretch="Uniform" Source="Images/tick.png"></Image>
                </ControlTemplate>
            </Button.Template>
        </Button>
zamoldar
  • 548
  • 10
  • 13