[技巧] 监听你的 DragEventArgs!





1.00/5 (1投票)
如何通过多个对象连接拖放事件。
问题
在代码后处理几乎任何事情都是不好的(通常来说),并且很容易创建紧密耦合的依赖关系。 在代码后处理事件,例如拖放,更容易产生这些依赖关系。
那么,如果不在代码后处理中,该如何处理拖放事件呢?
解决方案(示例代码)
快速说明 - 我刚刚弄清楚了这一点,想分享一下! 很有可能还有更好的方法来处理或解决这个问题,所以如果你知道任何方法,请在评论中告诉我。
我发现示例是解释概念的最佳方式。 假设你有一个 UserControl
,我们称之为 MyView
,它定义了初始的拖放事件。 我们还有主窗口类(MainWindow
),它将 MyView
作为子元素。 在这个例子中,MainWindow
将监听 MyView
的 Drop
事件,并随后调用其 ViewModel
(MainWindowViewModel
)的方法来处理逻辑。
请记住,这个技巧/窍门的重点 仅 是展示如何 启用监听 使用 DragEventArgs 的事件(例如 Drop 或 DragEnter)。 你实际从哪里监听是取决于你的。
UserControl MyView
MyView.xaml
<UserControl x:Class="MyProject.Views.MyView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
x:Name="uc_View">
<Grid>
<ListBox Name="lbxView" AllowDrop="True" Drop="lbxView_Drop">
<!-- Add listbox content here -->
</ListBox>
</Grid>
</UserControl>
关键代码
AllowDrop
基本上启用拖放功能。
Drop
是我们在拖放事件发生时调用方法名称的地方。
MyView.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
namespace MyProject.Views
{
/// <summary>
/// Interaction logic for MyView.xaml
/// </summary>
public partial class MyView : UserControl
{
// Define an 'EventHandler' for an object to listen to.
// The name doesn't really matter, just know that this is what other
// objects will reference when adding their listener.
public event EventHandler<DragEventArgs> ObjectDropped;
// Define how to invoke/call this event
protected virtual void OnObjectDropped(DragEventArgs e)
{
ObjectDropped?.Invoke(this, e);
}
// Define the drop method that we specified in the MyView.xaml file
private void lbxView_Drop(object sender, DragEventArgs e)
{
OnObjectDropped(sender, e);
}
}
}
关键代码
EventHandler<>
我们需要使用 EventHandler
的模板版本才能使其工作。 这也是其他对象添加其监听方法的公共句柄。
lbxView_Drop
在拖放事件发生时触发,并基本上调用监听委托。
Window MainWindow
MainWindow.xaml
<Window x:Class="MyProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyProject"
xmlns:localViews="clr-namespace:MyProject.Views"
Title="MyApp" Height="500" Width="720">
<Grid>
<localViews:MyView x:Name="myView" ObjectDropped="MyView_ObjectDropped"/>
</Grid>
</Window>
关键代码
ObjectDropped
是我之前提到的公共事件句柄。 你可以在这里传递监听方法名称。
MainWindow.xaml.cs
using System.Windows;
using MyProject.ViewModels;
namespace MyProject
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
// Just for a simple demonstration of passing the logic to the ViewModel
private MainWindowViewModel _viewModel;
private void MyView_ObjectDropped(object sender, DragEventArgs e)
{
// Handle the drop logic here!
// Example:
_viewModel.ObjectDropped( sender, e );
}
}
}
这里没有真正关键的代码,主要是为了完整性。 是的,ViewModel 的处理可以抽象出来,但这超出了本文的范围。
Window MainWindow(备选方案)
我强烈建议不要这样做,但我知道对于其他人来说,这可能是最佳选择。
你可以添加监听器的另一种方法是省略 MainWindow.xaml 中的 ObjectDropped="MyView_ObjectDropped"
,并在 MainWindow
的构造函数中添加监听器。
MainWindow.xaml.cs(备选方案)
using System.Windows;
namespace MyProject
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
myView.ObjectDropped += new EventHandler<DragEventArgs>(MyView_ObjectDropped);
}
private void MyView_ObjectDropped(object sender, DragEventArgs e)
{
// Handle the drop logic here!
}
}
}