使用 MVVM 在画布中移动项目 [英] Move items in a canvas using 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>
我已经成功地将事件(现在什么都不做)绑定到 MouseLeftButtonDown
、MouseLeftButtonUp
和 MouseMove
但我不知道如何从视图模型中获取光标的位置.
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屋!