簡體   English   中英

使用MVVM在WPF畫布上繪制動態圓

[英]Drawing dynamic Circle on WPF Canvas with MVVM

我已經在WPF中編寫了一個代碼,以便在Canvas中的Mouse Events上畫一個圓並將其拖到畫布上,並在后面的代碼中調整大小。 它的工作正常。 但是我需要使用MVVM框架實現相同的結果。

這是我的代碼,

XAML

<Window x:Class="testapp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
    <Grid>
        <Canvas x:Name="canvas" Background="Transparent" MouseDown="canvas_PreviewMouseDown" MouseMove="canvas_PreviewMouseMove" MouseUp="canvas_PreviewMouseUp"></Canvas>
    </Grid>
</Window>

背后的代碼

private enum HitType
    {
        None, Body, UL, UR, LR, LL, L, R, T, B
    };
private bool DragInProgress = false;
private Point LastPoint;
HitType MouseHitType = HitType.None;
Ellipse elip = new Ellipse();
private Point anchorPoint;
private bool is_drawing = false;

public MainWindow()
    {
        InitializeComponent();            
    }

private HitType SetHitType(Ellipse ellips, Point point)
    {
        double left = Canvas.GetLeft(ellips);
        double top = Canvas.GetTop(ellips);
        double right = left + ellips.Width;
        double bottom = top + ellips.Height;
        if (point.X < left) return HitType.None;
        if (point.X > right) return HitType.None;
        if (point.Y < top) return HitType.None;
        if (point.Y > bottom) return HitType.None;

        const double GAP = 10;
        if (point.X - left < GAP)
        {
            if (point.Y - top < GAP) return HitType.UL;
            if (bottom - point.Y < GAP) return HitType.LL;
            return HitType.L;
        }
        if (right - point.X < GAP)
        {
            if (point.Y - top < GAP) return HitType.UR;
            if (bottom - point.Y < GAP) return HitType.LR;
            return HitType.R;
        }
        if (point.Y - top < GAP) return HitType.T;
        if (bottom - point.Y < GAP) return HitType.B;
        return HitType.Body;
    }

private void SetMouseCursor()
    {
        Cursor desired_cursor = Cursors.Arrow;
        switch (MouseHitType)
        {
            case HitType.None:
                desired_cursor = Cursors.Arrow;
                break;
            case HitType.Body:
                desired_cursor = Cursors.Hand;
                break;
            case HitType.UL:
            case HitType.LR:
                desired_cursor = Cursors.SizeNWSE;
                break;
            case HitType.LL:
            case HitType.UR:
                desired_cursor = Cursors.SizeNESW;
                break;
            case HitType.T:
            case HitType.B:
                desired_cursor = Cursors.SizeNS;
                break;
            case HitType.L:
            case HitType.R:
                desired_cursor = Cursors.SizeWE;
                break;
        }

        if (Cursor != desired_cursor) { Cursor = desired_cursor; }
        canvas.Cursor = desired_cursor;
    }

private void canvas_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.Source is Ellipse)
        {
            elip = e.Source as Ellipse;
            MouseHitType = SetHitType(elip, Mouse.GetPosition(canvas));
            if (MouseHitType == HitType.None) return;
            LastPoint = Mouse.GetPosition(canvas);
            DragInProgress = true;
        }
        else
        {
            is_drawing = true;
            anchorPoint = e.MouseDevice.GetPosition(canvas);
            elip = new Ellipse
            {
                Stroke = Brushes.Black,
                StrokeThickness = 2,
                Fill = Brushes.Transparent
            };
            canvas.Children.Add(elip);
        }
    }

private void canvas_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (!DragInProgress)
        {
            MouseHitType = SetHitType(elip, Mouse.GetPosition(canvas));
            SetMouseCursor();

            if (!is_drawing)
                return;

            Point location = e.MouseDevice.GetPosition(canvas);

            double minX = Math.Min(location.X, anchorPoint.X);
            double minY = Math.Min(location.Y, anchorPoint.Y);
            Double maxX = Math.Max(location.X, anchorPoint.X);
            Double maxY = Math.Max(location.Y, anchorPoint.Y);

            Canvas.SetTop(elip, minY);
            Canvas.SetLeft(elip, minX);

            double height = maxY - minY;
            double width = maxX - minX;

            elip.Height = Math.Abs(height);
            elip.Width = Math.Abs(width);
        }
        else
        {
            Point point = Mouse.GetPosition(canvas);
            double offset_x = point.X - LastPoint.X;
            double offset_y = point.Y - LastPoint.Y;

            double new_x = Canvas.GetLeft(elip);
            double new_y = Canvas.GetTop(elip);
            double new_width = elip.Width;
            double new_height = elip.Height;

            switch (MouseHitType)
            {
                case HitType.Body:
                    new_x += offset_x;
                    new_y += offset_y;
                    break;
                case HitType.UL:
                    new_x += offset_x;
                    new_y += offset_y;
                    new_width -= offset_x;
                    new_height -= offset_y;
                    break;
                case HitType.UR:
                    new_y += offset_y;
                    new_width += offset_x;
                    new_height -= offset_y;
                    break;
                case HitType.LR:
                    new_width += offset_x;
                    new_height += offset_y;
                    break;
                case HitType.LL:
                    new_x += offset_x;
                    new_width -= offset_x;
                    new_height += offset_y;
                    break;
                case HitType.L:
                    new_x += offset_x;
                    new_width -= offset_x;
                    break;
                case HitType.R:
                    new_width += offset_x;
                    break;
                case HitType.B:
                    new_height += offset_y;
                    break;
                case HitType.T:
                    new_y += offset_y;
                    new_height -= offset_y;
                    break;
            }

            if ((new_width > 0) && (new_height > 0))
            {
                Canvas.SetLeft(elip, new_x);
                Canvas.SetTop(elip, new_y);
                elip.Width = new_width;
                elip.Height = new_height;
                LastPoint = point;
            }
        }
    }

private void canvas_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (DragInProgress)
            DragInProgress = false;
        if (is_drawing)
        {
            is_drawing = false;
            elip.Stroke = Brushes.Black;
            elip.StrokeThickness = 2;
            elip.Fill = Brushes.Transparent;
        }
    }       

我嘗試使用MVVM Framework達到相同的結果,但是它不起作用。

https://www.codeproject.com/Tips/478643/Mouse-Event-Commands-for-MVVM

上面的鏈接幫助我使用MVVM編寫了Mouse Event Commands,並且我使用相同的代碼進行了少量修改就可以實現結果,並且可以正常工作。

我的代碼中的更改是

在“代碼隱藏”中,我創建了一個Canvas元素,例如

Canvas canvas = new Canvas();

並在canvas_PreviewMouseDown方法中包含了一行代碼

if (e.OriginalSource is Canvas)
            canvas = (Canvas)e.OriginalSource;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM