使用 MVVM 在画布中移动项目 [英] Move items in a canvas using MVVM

查看:26
本文介绍了使用 MVVM 在画布中移动项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望用户能够在画布中自由移动项目.
我的应用正在使用 Caliburn.Micro.

I want the user to be able to move items freely in a canvas.
My app is using Caliburn.Micro.

如果 Items,我的 MainViewModel 有一个集合:

My MainViewModel has a collection if Items :

public BindableCollection<ItemViewModel> Items { get; set; }

我通过 ItemsControl 在画布中显示:

That I display in a canvas through an ItemsControl :

<ItemsControl x:Name="Items">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas Background="#FFCADEEF" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding Path=X}" />
            <Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
            <Setter Property="Width" Value="{Binding Path=Width}" />
            <Setter Property="Height" Value="{Binding Path=Height}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Background="{Binding Path=BackgroundColor}">
                <Rectangle>
                    <Rectangle.Fill>
                        <VisualBrush Visual="{StaticResource appbar_cursor_move}" />
                    </Rectangle.Fill>
                </Rectangle>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我已经成功地将事件(现在什么都不做)绑定到 MouseLeftButtonDownMouseLeftButtonUpMouseMove 但我不知道如何从视图模型中获取光标的位置.

I have successfully bound events (that do nothing for now) to the MouseLeftButtonDown, MouseLeftButtonUp and MouseMove but I have no idea how to get the cursor's position from the viewmodel.

推荐答案

我已经从 另一个 GitHub 帐户 :

public class DragBehavior
{
    public readonly TranslateTransform Transform = new TranslateTransform();
    private Point _elementStartPosition2;
    private Point _mouseStartPosition2;
    private static DragBehavior _instance = new DragBehavior();
    public static DragBehavior Instance
    {
        get { return _instance; }
        set { _instance = value; }
    }

    public static bool GetDrag(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsDragProperty);
    }

    public static void SetDrag(DependencyObject obj, bool value)
    {
        obj.SetValue(IsDragProperty, value);
    }

    public static readonly DependencyProperty IsDragProperty =
      DependencyProperty.RegisterAttached("Drag",
      typeof(bool), typeof(DragBehavior),
      new PropertyMetadata(false, OnDragChanged));

    private static void OnDragChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        // ignoring error checking
        var element = (UIElement)sender;
        var isDrag = (bool)(e.NewValue);

        Instance = new DragBehavior();
        ((UIElement)sender).RenderTransform = Instance.Transform;

        if (isDrag)
        {
            element.MouseLeftButtonDown += Instance.ElementOnMouseLeftButtonDown;
            element.MouseLeftButtonUp += Instance.ElementOnMouseLeftButtonUp;
            element.MouseMove += Instance.ElementOnMouseMove;
        }
        else
        {
            element.MouseLeftButtonDown -= Instance.ElementOnMouseLeftButtonDown;
            element.MouseLeftButtonUp -= Instance.ElementOnMouseLeftButtonUp;
            element.MouseMove -= Instance.ElementOnMouseMove;
        }
    }

    private void ElementOnMouseLeftButtonDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
    {
        var parent = Application.Current.MainWindow;
        _mouseStartPosition2 = mouseButtonEventArgs.GetPosition(parent);
        ((UIElement)sender).CaptureMouse();
    }

    private void ElementOnMouseLeftButtonUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
    {
        ((UIElement)sender).ReleaseMouseCapture();
        _elementStartPosition2.X = Transform.X;
        _elementStartPosition2.Y = Transform.Y;
    }

    private void ElementOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
    {
        var parent = Application.Current.MainWindow;
        var mousePos = mouseEventArgs.GetPosition(parent);
        var diff = (mousePos - _mouseStartPosition2);
        if (!((UIElement)sender).IsMouseCaptured) return;
        Transform.X = _elementStartPosition2.X + diff.X;
        Transform.Y = _elementStartPosition2.Y + diff.Y;
    }        
}

并简单地将其附加到 ItemsControl DataTemplate :

And simply attached it to the ItemsControl DataTemplate :

<DataTemplate>
    <Border
        Background="{Binding Path=BackgroundColor}"
        behaviors:DragBehavior.Drag="True">
        <!-- whatever -->
    </Border>
</DataTemplate>

现在我需要找到当用户停止拖动时如何从行为向视图模型发送消息(我假设它涉及一个新的行为属性).

Now I need to find how to send a message from the behavior to the viewmodel when the user stops dragging (I'm assuming it involves a new behavior property).

这篇关于使用 MVVM 在画布中移动项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆