[C#] [WPF] 在MVVM中实现拖拽功能 - 入门

拖拽功能是使用频率较高的一种交互, 用传统方法去写很简单, 但是在mvvm规则下, 也没必要弄得很麻烦
我的入门案例就选择了使用mvvm重写tutorialspoint - Interaction里的调色盘案例, view如下
image

MainWindow.xaml

这里的重点是控件要允许拖拽以及对应的事件
目标控件, 填充色绑定, 允许drop, drop方法

<!-- #region target-->
<Rectangle
    AllowDrop="True"
    Drop="TargetRect_Drop"
    Fill="{Binding FillColor}"/>
<!--#endregion-->

来源控件, 因为要拖动, 所以用MouseMove

<!--#region source-->
<Rectangle
    Fill="Beige"
    MouseMove="SourceRect_MouseMove" />
<!--#endregion-->

MainWindow.xaml.cs

在这里, 就是写事件的主要逻辑
1️⃣ 首先, 设置一个全局变量

MainWindowViewModel MainVM;

2️⃣然后写方法

// drop方法
private void TargetRect_Drop(object sender, DragEventArgs e)
{
	// GetDataPresent: 检查e.Data是否可以转换为string格式来存储
	if (e.Data.GetDataPresent(DataFormats.StringFormat))
	{
		// GetData: 将数据转化为string格式, 注意将DataObject类型强制转为string
		string color = (string)e.Data.GetData(DataFormats.StringFormat);
		// 赋值
		MainVM.FillColor = color;
		//MainVM.FillColorName = (Color)ColorConverter.ConvertFromString(MainVM.FillColor);
	}
}

然后是MouseMove

// drag方法: 鼠标左键点击并拖动时触发, 因为要拖动,所以需要一个MouseMove事件
private void SourceRect_MouseMove(object sender, MouseEventArgs e)
{
    // 按下左键
    if (e.LeftButton == MouseButtonState.Pressed)
    {
        // 指定sender
        Rectangle source = sender as Rectangle;
        // 拖动方法DargDrop.DoDragDrop
        DragDrop.DoDragDrop(source, source.Fill.ToString(), DragDropEffects.Copy);
    }
}

MainViewModel.cs

简简单单声明一下要用的变量

[ObservableProperty]
private string _fillColor = "AliceBlue";

关于DragDrop.DoDragDrop

应该是拖拽行为中比较重要的方法(看了好多都是用这个)
官方文档: https://learn.microsoft.com/en-us/dotnet/api/system.windows.dragdrop.dodragdrop?view=windowsdesktop-8.0

⭐省流: 意思就是这个方法需要指定来源, 传输的数据还有效果, 数据会被自动封装 (目标引用数据的话可以用e.Data.GetData啥的), 返回的就是传入的拖拽效果enum值⭐

用处: 启动一次拖拽行为

// 如果dragSource或data为null, 则报错
public static System.Windows.DragDropEffects DoDragDrop (
	System.Windows.DependencyObject dragSource, 
	object data, 
	System.Windows.DragDropEffects allowedEffects);

参数:
dragSource ➡️ 指代被拖拽的对象
data ➡️ 包含传输数据的data对象
allowedEffects ➡️ 行为中允许的拖拽效果, 来自DragDropEffects之中的某个值

返回: 拖拽行为中最终效果, 同样来自DragDropEffects

DragDrop.DoDragDrop(
	source, 
	source.Fill.ToString(), 
	DragDropEffects.Copy)

source代表被拖拽的控件/对象, 传输的是source的Fill属性, 并且会被自动封装进DataObject中

DragDropEffects - Enum
(不想写了了直接放图)
image

posted @ 2024-05-15 11:03  Akira300000  阅读(102)  评论(0编辑  收藏  举报