【问题标题】:EventToCommand with MouseDown and MouseEnter带有 MouseDown 和 MouseEnter 的 EventToCommand
【发布时间】:2015-11-30 15:09:30
【问题描述】:

我想用新图像、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;
        }

【问题讨论】:

    标签: c# wpf mvvm eventtocommand


    【解决方案1】:

    你可以用一个按钮做一个非常简单的解决方法。只需将图像插入按钮并使用CommandCommandParameter 属性。但这只会在 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 属性将其设置为平面样式来完成此操作。也许this Question 有助于更好地设置按钮的样式。

    【讨论】:

    • 感谢您的回答!我想知道是否有与按钮无关的解决方案。我的应用程序看起来像this。我真的希望切换到按钮不会把事情搞砸。另外,你说只有LeftMouseButtonUp 可以吗?我真的希望拖动绘图工作,而不仅仅是单击图像,这就是这个问题的原因。
    • @Eiron 是的,我明白这一点。那么这显然是错误的解决方案。
    【解决方案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;
    }
    

    &lt;Image.InputBinding&gt; 应避免与事件结合使用,因为它可能会像对我一样破坏事情。

    【讨论】:

    • 如果你不关心参数,你可以使用 InvokeCommandAction 而不是 EventToCommand(你仍然可以传递参数,但我认为你不能传递通常的事件参数)。 EventToCommand 是 MVVMLight 库的一部分(额外依赖)
    猜你喜欢
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多