views:

426

answers:

3

I want to make a user control that shows an image and can invoke a command when clicked. Later I want to bind a list of these controls to a list of products.

+3  A: 

There are several ways to do this, but one simple solution would be to use a button (maybe style away the border and background), and use the image as the content of the button.

You can later use a ListBox or similar, and override the DataTemplate to use the button and an image for each product.

code-zoop
This is in fact the first route I was taking, but I am wondering if there is a cleaner solution.
mico
A: 

This is what I came up with after a few experiments.

Apparently, there is a section input-bindings in the header of a user control where a mouse binding can be placed, so I styled the control this way

<UserControl x:Class="TestSandbox.Views.ClickableImage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             xmlns:vm="clr-namespace:TestSandbox.ViewModels"
             xmlns:vw="clr-namespace:TestSandbox.Views"

             mc:Ignorable="d">
    <UserControl.DataContext>
        <vm:ViewModel1/>
    </UserControl.DataContext>

    <UserControl.InputBindings>
        <MouseBinding Gesture="LeftClick"
              Command="{Binding Path=DisplayProductCommand}" />
    </UserControl.InputBindings>

    <Image Source="..\Images\picture-of-my-product.jpg" />
</UserControl>

The DataContext might be inherited in production, and the image will be bound to a list of Product objects.

The binding to a command requires a public property in the view model ViewModel1. This is the class ViewModel1.

The dependency on a particular MVVM framework (in this case MVVM Foundation) is in the use of the RelayCommand class only.

namespace TestSandbox.ViewModels
{
    class ViewModel1
    {
        private ICommand _displayProduct;

        public ICommand DisplayProductCommand
        {
            get
            {
                if (_displayProduct == null)
                {
                    _displayProduct = new RelayCommand(DisplayProduct, CanDisplayProduct);
                }

                return _displayProduct;
            }
        }

        private bool CanDisplayProduct()
        {
            Console.WriteLine("CanDisplayProduct");
            return true;
        }

        private void DisplayProduct()
        {
            Console.WriteLine("DisplayProduct");
        }
    }
}
mico
A: 

Well, after a little more fiddling, a simple button does the job. Here it is:

<Button Command="{Binding Path=DisplayProductCommand}" >
   <Image Source="..\Images\my-beautiful-product.jpg"/>
</Button>
mico