Convert Code behind MouseButtonEventArgs into MVVM

Viewed 817

Im still new to MVVM but im trying to learn it.

I need to resize the Drawn rectangle into my canvas. But i want to do it in MVVM way.

I found this post and its working and it suite my needs but its not MVVM

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

I am trying to convert this code into 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;
            }
        }

I am using Devexpress MVVM

and this is my xaml code

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

i am trying to pass the canvas into my view model.

this is the code for my 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;
            }
        }

currently my code doesn't work. In the code behind i have the MouseButtonEventArgs which is needed in the method.

the problem i am facing now is how do it access the MouseButtonEventArgs?

Without it. I can't use the sample code from the blog

1 Answers

You can use Behavior to implement your goal.

Firstly, add the following two assemblies reference to your project:

System.Windows.Interactivity.dll

Microsoft.Expression.Interactions.dll

Add the following xaml namespace:

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

Then add behaviors for the Canvas control like this:

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

EventTrigger is a trigger behavior that will listen for a specific event raised up. CallMethodAction is an action that will invoke a method which is specified by TargetObject and MethodName properties. Here, the value of TargetObject is {Binding}, it means the target object is your view model, so it will invoke a method with such a name from your view model.

Then, in your view model, add the following method:

    public void OnLeftButtonClicked(object s,MouseButtonEventArgs e)
    {

    }

Notice:

  1. The modifier should be public;

  2. The method name should be identical to the MethodName property of CallMethodAction;

Related