有没有办法允许在一个充满控件的表单中的任何位置拖放?
这个想法是允许用户将文件拖到表单中的任何位置以“加载”它。我不需要任何其他DragDrop行为但是这个。
通过仅将AllowDrop=True
设置为表单,我会收到DragEnter
个事件,但不会收到DragDrop
个事件。
一个想法是在DragEnter
上显示最顶层的面板并在那里处理DragDrop
个事件,但我想知道我是否因为没什么经验而错过了一些明显的事情在现场。
另一个想法是迭代所有控件并订阅与Drag相关的事件。不过,我真的不喜欢这种方法。
答案 0 :(得分:3)
当然,迭代控件将起作用,它不需要太多代码:
public Form1() {
InitializeComponent();
WireDragDrop(this.Controls);
}
private void WireDragDrop(Control.ControlCollection ctls) {
foreach (Control ctl in ctls) {
ctl.AllowDrop = true;
ctl.DragEnter += ctl_DragEnter;
ctl.DragDrop += ctl_DragDrop;
WireDragDrop(ctl.Controls);
}
}
void ctl_DragDrop(object sender, DragEventArgs e) {
// etc..
}
void ctl_DragEnter(object sender, DragEventArgs e) {
// etc..
}
如果您仍然不喜欢该方法,那么请使用用户将始终点击的可识别的单个放置目标。可以像标签“Drop here”一样简单。
答案 1 :(得分:1)
我不确定您对表单有什么样的控制权。但我已经使用Button,GroupBox,PictureBox和TextBox进行了测试。默认情况下,所有这些控件都有AllowDrop = false
。而且我可以将外部的东西拖放到表单上。 DragDrop
被解雇了。一切都好。你的问题到底是什么?我猜您的控件有AllowDrop = true
。
如果未触发DragDrop
事件(我认为只有当目标是您的AllowDrop = true
控件之一时才会发生)。我认为以下可能有效。但如果目标是您的AllowDrop = true
控件之一,效果图标就会消失。
public Form1(){
InitializeComponents();
t.Interval = 1;
t.Tick += Tick;
}
IDataObject data;
Timer t = new Timer();
int i = 0;
private void Tick(object sender, EventArgs e)
{
Text = (i++).ToString();
if (ClientRectangle.Contains(PointToClient(new Point(MousePosition.X, MousePosition.Y))) && MouseButtons == MouseButtons.None)
{
t.Stop();
if (data != null)
{
//Process data here
//-----------------
data = null;
}
}
else if (MouseButtons == MouseButtons.None)
{
data = null;
t.Stop();
}
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.AllowedEffect;
if (data == null)
{
data = e.Data;
t.Start();
}
}
我认为您可能必须使用所有控件的循环来添加适当的事件处理程序。没有其他更好的方法。
答案 2 :(得分:-1)
在Drop
事件中。
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files) Console.WriteLine(file);
在DragEnter
事件中。
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effects = DragDropEffects.Copy;