拖放仅在其背景中工作的 CustomControl
Posted
技术标签:
【中文标题】拖放仅在其背景中工作的 CustomControl【英文标题】:Drag and drop a CustomControl working only from it's background 【发布时间】:2014-06-25 11:29:03 【问题描述】:我有一个自定义控件,其中包含一个下方带有标签的按钮。我想让这些控件可以拖动到另一个控件上,以便在 flowlayoutpanel 中按我想要的方式排列它们。 现在只有当我将控件从它的背景(在下图中用黄色标记)拖动到另一个控件的黄色标记区域时才有效,但如果我从按钮或标签区域拖动则不行..
我怎样才能做到这一点,以便我可以移动自定义控件,无论我从哪里抓取它并将其放在另一个控件上。基本上只是一个控件,不像按钮和标签的容器..
这是我目前的代码:
private void flowLayoutPanel1_DragEnter(object sender, DragEventArgs e)
e.Effect = DragDropEffects.Move;
private void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
CustomControl target = sender as CustomControl;
if (target != null)
int targetIndex = FindCSTIndex(target);
if (targetIndex != -1)
string pictureBoxFormat = typeof(CustomControl).FullName;
if (e.Data.GetDataPresent(pictureBoxFormat))
CustomControl source = e.Data.GetData(pictureBoxFormat) as CustomControl;
int sourceIndex = this.FindCSTIndex(source);
if (targetIndex != -1)
this.flowLayoutPanel1.Controls.SetChildIndex(source, targetIndex);
private int FindCSTIndex(CustomControl cst_ctr)
for (int i = 0; i < this.flowLayoutPanel1.Controls.Count; i++)
CustomControl target = this.flowLayoutPanel1.Controls[i] as CustomControl;
if (cst_ctr == target)
return i;
return -1;
private void OnCstMouseMove(object sender, MouseEventArgs e)
if (e.Button == MouseButtons.Left)
CustomControl cst = sender as CustomControl;
cst.DoDragDrop(cst, DragDropEffects.Move);
还有自定义控件类:
public class CustomControl : Control
private Button _button;
private Label _label;
public CustomControl(Button button, Label label)
_button = button;
_label = label;
button.Width = 50;
button.Height = 50;
label.Width = 65;
button.BackgroundImageLayout = ImageLayout.Stretch;
Height = button.Height + label.Height;
Width = 68;
// Width = Math.Max(button.Width, label.Width);
Controls.Add(_button);
_button.Location = new Point(0, 0);
Controls.Add(_label);
_label.Location = new Point(0, button.Height);
【问题讨论】:
我本想回答您 2 天的问题,但由于某些原因没有回答。您需要处理所有子控件中的拖放事件。可以使其自动化:覆盖(或者订阅)ControlAdded
/СontrolRemoved
事件并在那里添加/删除拖放事件。
你能举个例子吗?我不知道该怎么做。。谢谢!
【参考方案1】:
使用 MouseDown
而不是 MouseMove
来启动拖放操作 (MSDN)。您可以在控件代码本身中启动拖放(假设所有CustomControl
s 都可以拖放),否则您可能想要创建公共方法来签署孩子(暴露孩子是个坏主意,除非你已经在外面使用它们)。
public class CustomControl : Control
...
public CustomControl(Button button, Label label)
...
_button.MouseDown += OnMouseDown;
_label.MouseDown += OnMouseDown;
override void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
if (e.Button == MouseButtons.Left)
(sender as Control).DoDragDrop(this, DragDropEffects.Move);
未经测试,但应该能给你一些想法。
【讨论】:
【参考方案2】:设法解决它:
private void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
Control target = new Control();
target.Parent = sender as Control;
if (target != null)
int targetIndex = FindCSTIndex(target.Parent);
if (targetIndex != -1)
string cst_ctrl = typeof(CustomControl).FullName;
if (e.Data.GetDataPresent(cst_ctrl))
Button source = new Button();
source.Parent = e.Data.GetData(cst_ctrl) as CustomControl;
if (targetIndex != -1)
this.flowLayoutPanel1.Controls.SetChildIndex(source.Parent, targetIndex);
private int FindCSTIndex(Control cst_ctr)
for (int i = 0; i < this.flowLayoutPanel1.Controls.Count; i++)
CustomControl target = this.flowLayoutPanel1.Controls[i] as CustomControl;
if (cst_ctr.Parent == target)
return i;
return -1;
private void OnCstMouseMove(object sender, MouseEventArgs e)
if (e.Button == MouseButtons.Left)
Control cst = sender as Control;
cst.DoDragDrop(cst.Parent, DragDropEffects.Move);
【讨论】:
以上是关于拖放仅在其背景中工作的 CustomControl的主要内容,如果未能解决你的问题,请参考以下文章
锚定到 InputAccessoryView 的按钮仅在其框架中工作
按钮锚定到InputAccessoryView仅在其框架中工作
如何在 iOS 11 的 UITextfield 中启用拖动