如何在允许用户在画布上绘图的应用程序上实现MVVM?

时间:2018-03-07 08:43:20

标签: mvvm architecture

应用程序允许用户在画布上绘图,这些是他们可以绘制的一些内容:

  1. 绘制线:用户首先单击画布上的点以标记起点,然后拖动并释放鼠标以标记终点。
  2. 绘制矩形:用户首先单击画布上的一个点以标记矩形的第一个角,然后拖动并释放鼠标以标记对角。
  3. 绘制圆圈:用户首先单击画布上的一个点来标记半径的开始(即这是圆心),然后拖动并释放鼠标以标记圆的半径结束。 / LI>

    这些需要使用鼠标进行交互,因此无法使用Command。 View如何告诉ViewModel所有鼠标事件和鼠标坐标?

2 个答案:

答案 0 :(得分:0)

您必须为要创建的屏幕和对象创建ViewModel,并为绘图创建一些自定义控件。

在互联网上大量使用完整样本

一些链接:

Scribble-WPF-InkCanvas-Application-Using-PRISM-MVVM

Adventures-into-Ink-API-using-WPF

MVVM-Diagram-Designer

SimpleEditor

答案 1 :(得分:0)

  

这些需要使用鼠标进行交互,因此无法使用   命令。 View如何告诉ViewModel所有鼠标事件   和鼠标坐标?

您可以使用EventToCommand将事件绑定到命令,并使用命令参数和converterMouseEventArgs传递并转换为包含所有必需数据的对象实现你的绘图逻辑。

以下是一个简单的示例,说明如何在MvvmLight中执行此操作,以演示如何跟踪ViewModel属性到鼠标位置和鼠标左键状态。

首先,您显然定义了ViewModel属性,这些属性将保持鼠标位置和状态:

private double _posX = 0;
public double PosX
{
    // ...
}

private double _posY = 0;
public double PosY
{
    // ...
}

private bool _isClicked = false;
public bool IsClicked
{
    // ...
}

下一步是创建一个转换器,它将MouseEventArgs转换为一个对象,然后在ViewModel中使用该对象来保存和解释鼠标事件数据。在此示例中,我们将其存储在自定义MouseData对象中:

public class MouseData
{
    public double PosX { get; set; }
    public double PosY { get; set; }
    public bool IsClicked { get; set; }
}

public class MouseEventArgsConverter : IEventArgsConverter
{
    public object Convert(object value, object parameter)
    {
        var args = (MouseEventArgs)value;
        var element = (FrameworkElement)parameter;
        var point = args.GetPosition(element);

        var mouseData = new MouseData();
        mouseData.PosX = point.X;
        mouseData.PosY = point.Y;
        mouseData.IsClicked = args.LeftButton == MouseButtonState.Pressed;

        return mouseData;
    }
}

然后定义一个接受转换参数的命令并实现绘图逻辑:

public ICommand MouseMoveCommand
{
    get;
    private set;
}
private void MouseMoveCommandExecute(MouseData e)
{
    PosX = e.PosX;
    PosY = e.PosY;
    IsClicked = e.IsClicked;

    // draw lines, rectangles, circles, ecc. here
}

最后在您的XAML中,将Canvas MouseMove事件绑定到新创建的命令,并指定必须用于转换事件arg的转换器:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"

...

<Canvas x:Name="MyCanvas" Background="LightGray">
    <Canvas.Resources>
        <ResourceDictionary>
            <local:MouseEventArgsConverter x:Key="MouseEventArgsConverter" />
        </ResourceDictionary>
    </Canvas.Resources>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseMove">
            <cmd:EventToCommand Command="{Binding MouseMoveCommand}"
                                EventArgsConverter="{StaticResource MouseEventArgsConverter}"
                                EventArgsConverterParameter="{Binding ElementName=MyCanvas}"
                                PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Canvas>