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.
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.
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");
}
}
}
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>