【问题标题】:Convert Code behind MouseButtonEventArgs into MVVM将 MouseButtonEventArgs 后面的代码转换为 MVVM
【发布时间】:2017-11-23 04:55:40
【问题描述】:

我还是 MVVM 新手,但我正在努力学习它。

我需要将绘制的矩形调整到我的画布中。但我想用 MVVM 的方式来做。

我发现这篇文章和它的工作,它满足我的需要,但它不是 MVVM

https://denisvuyka.wordpress.com/2007/10/15/wpf-simple-adorner-usage-with-drag-and-resize-operations/

我正在尝试将此代码转换为 MVVM

// Handler for element selection on the canvas providing resizing adorner
        void myCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Remove selection on clicking anywhere the window
            if (selected)
            {
                selected = false;
                if (selectedElement != null)
                {
                    // Remove the adorner from the selected element
                    aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);                    
                    selectedElement = null;
                }
            }

            // If any element except canvas is clicked, 
            // assign the selected element and add the adorner
            if (e.Source != myCanvas)
            {
                _isDown = true;
                _startPoint = e.GetPosition(myCanvas);

                selectedElement = e.Source as UIElement;

                _originalLeft = Canvas.GetLeft(selectedElement);
                _originalTop = Canvas.GetTop(selectedElement);

                aLayer = AdornerLayer.GetAdornerLayer(selectedElement);
                aLayer.Add(new ResizingAdorner(selectedElement));
                selected = true;
                e.Handled = true;
            }
        }

我正在使用 Devexpress MVVM

这是我的 xaml 代码

 <Canvas Name="myCanvas" Background="Gray">
        <dxmvvm:Interaction.Behaviors>
            <dxmvvm:EventToCommand Command="{Binding OnSelectedCommand , Source={x:Static vm:Vm.instance}}" 
                                       EventName="MouseDown" CommandParameter="{Binding ElementName=myCanvas}"
                                       PassEventArgsToCommand="True">
            </dxmvvm:EventToCommand>
        </dxmvvm:Interaction.Behaviors>
</Canvas >

我正在尝试将画布传递到我的视图模型中。

这是我的 ViewModel 的代码

public DelegateCommand<Canvas> OnSelectedCommand { get; private set; }
        public Vm()
        {
            OnSelectedCommand = new DelegateCommand<Canvas>(OnSelectedEvent, true);
        }
        Canvas c = new Canvas();
        private void OnSelectedEvent(object e)
        {
            if (e == null) return;
            c = e as Canvas;

            // Remove selection on clicking anywhere the window
            if (selected)
            {
                selected = false;
                if (selectedElement != null)
                {
                    // Remove the adorner from the selected element
                    aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);
                    selectedElement = null;
                }
            }

            // If any element except canvas is clicked, 
            // assign the selected element and add the adorner
            if (e.Source != myCanvas)
            {
                _isDown = true;
                _startPoint = e.GetPosition(myCanvas);

                selectedElement = e.Source as UIElement;

                _originalLeft = Canvas.GetLeft(selectedElement);
                _originalTop = Canvas.GetTop(selectedElement);

                aLayer = AdornerLayer.GetAdornerLayer(selectedElement);
                aLayer.Add(new ResizingAdorner(selectedElement));
                selected = true;
                e.Handled = true;
            }
        }

目前我的代码不起作用。在后面的代码中,我有方法中需要的MouseButtonEventArgs

我现在面临的问题是它如何访问MouseButtonEventArgs

没有它。我无法使用博客中的示例代码

【问题讨论】:

    标签: c# wpf canvas mvvm


    【解决方案1】:

    您可以使用行为来实现您的目标。

    首先,将以下两个程序集引用添加到您的项目中:

    System.Windows.Interactivity.dll

    Microsoft.Expression.Interactions.dll

    添加以下 xaml 命名空间:

    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    

    然后像这样为 Canvas 控件添加行为:

        <Canvas>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                    <ei:CallMethodAction MethodName="OnLeftButtonClicked" TargetObject="{Binding}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
            ...
        </Canvas>
    

    EventTrigger 是一种触发行为,它将侦听引发的特定事件。 CallMethodAction 是一个动作,它将调用由TargetObjectMethodName 属性指定的方法。这里TargetObject的值是{Binding},表示目标对象就是你的view model,所以它会从你的view model中调用一个这样名字的方法。

    然后,在您的视图模型中,添加以下方法:

        public void OnLeftButtonClicked(object s,MouseButtonEventArgs e)
        {
    
        }
    

    注意:

    1. 修饰符应该是public;

    2. 方法名称应与CallMethodActionMethodName属性相同;

    【讨论】:

    • 谢谢。但是使用上面的代码。如何将画布传递给我的视图模型?
    • s 转换为画布:var canvas = s as Canvas
    • 非常感谢。这真的帮助了我。我一直在寻找解决方案 5 小时。
    • 跟进问题。如何使用您的代码传递多个参数?谢谢
    • 你可以在EventTrigger里面添加更多动作,当触发器被调用时,所有添加的动作都会被有序调用,所以如果你想给你的视图模型传递另一个参数,你可以添加@ 987654336@ 在CallMethodAction 之前,并使用其CommandParameter 属性将参数传递给您的视图模型。然后你可以很容易的将传递给相应命令执行方法的参数传递给OnLeftButtonClicked方法(通过使用全局变量)。但我认为这不是一个好习惯。
    猜你喜欢
    • 2021-10-31
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 2017-12-01
    • 1970-01-01
    • 2022-06-15
    相关资源
    最近更新 更多