I want to replace single images on a initialized canvas with new images, pixelpainter / mapeditor style. Currently I manage to replace images on MouseEnter but this isn't my goal. I only want to change the image when the user has his mousebutton down (maybe with MouseEnter) above a image.
<DataTemplate>
<Image Source="{Binding MapTileImage}" Stretch="Fill" Width="{Binding Width}" Height="{Binding Height}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<command:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.ChangeTilesCommand}" CommandParameter="{Binding .}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</DataTemplate>
This code works only with the event "MouseEnter". MouseDown and even PreviewMouseDown along with other events do not work here. Which way would be the cleanest to get around this? I'd like to keep my EventToCommand and RelayCommand.
In my MainViewModel all I do is:
private RelayCommand<BitmapModel> _changeTileCommand;
public RelayCommand<BitmapModel> ChangeTilesCommand {
get { return _changeTileCommand ?? (_changeTileCommand = new RelayCommand<BitmapModel>(UpdateTile)); }
}
with
public void UpdateTile(BitmapModel tile) {
// BitmapModel tile = drag.TileParam;
if (tile == null) return;
if (SelectedMapTile == null) return;
tile.MapTileImage = SelectedMapTile.MapTileImage;
}
For all those souls stumbling on this thread in 5 years, here is how I solved it:
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding MapTileImage}" Stretch="Fill" Width="{Binding Width}" Height="{Binding Height}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<command:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.ChangeTilesCommand}" CommandParameter="{Binding .}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonDown">
<command:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.DrawingCommand}" PassEventArgsToCommand="True"/>
<command:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.ChangeTilesCommand}" CommandParameter="{Binding .}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonUp">
<command:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.DrawingCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
in combination with
private RelayCommand<BitmapModel> _changeTileCommand;
public RelayCommand<BitmapModel> ChangeTilesCommand {
get { return _changeTileCommand ?? (_changeTileCommand = new RelayCommand<BitmapModel>(UpdateTile, CanDraw)); }
}
private RelayCommand<MouseEventArgs> _drawingCommand;
public RelayCommand<MouseEventArgs> DrawingCommand {
get { return _drawingCommand ?? (_drawingCommand = new RelayCommand<MouseEventArgs>(MouseDown)); }
}
void MouseDown(MouseEventArgs mouse) {
if (mouse.LeftButton == MouseButtonState.Pressed) _mouseDown = true;
else if (mouse.LeftButton == MouseButtonState.Released) _mouseDown = false;
}
bool CanDraw(BitmapModel tile) {
return _mouseDown;
}
<Image.InputBinding>
should be avoided in combination with events as it might break things as it did with me.