0

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;
        }
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Eiron
  • 433
  • 1
  • 7
  • 15

2 Answers2

0

Well you could do a very easy workaround with a button. Just insert the image into the button and use the Command and CommandParameter properties. But this only fires on LeftMouseButtonUp event!

<Button Margin="100" BorderThickness="0" 
        Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
        Command="..." 
        CommandParameter="...">
    <Image Source="..." Stretch="Fill" 
           Width="{Binding Width}" 
           Height="{Binding Height}" />
</Button>

Then you just have to adjust the visual of the button a bit, because the button should look like "nothing". I have done this with removing the border and set it to a flat style via the Style Property. Maybe this Question helps with styling the button a littlebit better.

Community
  • 1
  • 1
Jens
  • 2,592
  • 2
  • 21
  • 41
  • Thanks for the answer! I'm wondering if there is a solution which hasn't to do with buttons. My application looks like [this](http://puu.sh/lEday/24234dd616.png). I'm really hoping that switching to buttons won't mess things up. Also, you say only `LeftMouseButtonUp` will work? I really want drag drawing to work, not just single clicks on images, which is the reason of this question. – Eiron Nov 30 '15 at 15:38
  • @Eiron yes i understand that. then this is obviously the wrong solution. – Jens Nov 30 '15 at 15:46
0

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.

Eiron
  • 433
  • 1
  • 7
  • 15
  • If you don't care about args you could use InvokeCommandAction intead of EventToCommand (you can still pass arguments, I don't think you can pass usual event args though). EventToCommand is part of MVVMLight library (extra dependency) – ed22 Mar 16 '19 at 21:32