EventToCommand с MouseDown и MouseEnter

Я хочу заменить отдельные изображения на инициализированном холсте новыми изображениями в стиле pixelpainter / mapeditor. В настоящее время мне удается заменить изображения на MouseEnter, но это не моя цель. Я хочу изменить изображение только тогда, когда пользователь нажимает кнопку мыши (возможно, с помощью MouseEnter) над изображением.

<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>

Этот код работает только с событием "MouseEnter". MouseDown и даже PreviewMouseDown вместе с другими событиями здесь не работают. Какой путь будет самым чистым, чтобы обойти это? Я хотел бы сохранить мои EventToCommand и RelayCommand.

В моей MainViewModel все, что я делаю, это:

private RelayCommand<BitmapModel> _changeTileCommand;
        public RelayCommand<BitmapModel> ChangeTilesCommand {
            get { return _changeTileCommand ?? (_changeTileCommand = new RelayCommand<BitmapModel>(UpdateTile)); }
        }

с

public void UpdateTile(BitmapModel tile) {
           // BitmapModel tile = drag.TileParam;
            if (tile == null) return;
            if (SelectedMapTile == null) return;

            tile.MapTileImage = SelectedMapTile.MapTileImage;
        }

2 ответа

Решение

Для всех тех душ, спотыкающихся в этой теме за 5 лет, вот как я решил это:

<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>

в комбинации с

    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> следует избегать в сочетании с событиями, поскольку это может сломать вещи, как это случилось со мной.

Ну, вы могли бы сделать очень простой обход с помощью кнопки. Просто вставьте изображение в кнопку и используйте Command а также CommandParameter свойства. Но это только зажигает LeftMouseButtonUp событие!

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

Тогда вам просто нужно немного отрегулировать визуальный вид кнопки, потому что кнопка должна выглядеть как "ничего". Я сделал это с удалением границы и установил плоский стиль через Style Имущество. Может быть, этот вопрос поможет немного улучшить стилизацию кнопки.

Другие вопросы по тегам