我有一个简单的程序可以创建一些按钮,它允许您使用自定义类移动它们。这些按钮被添加到面板中,他们不应该离开它。但是,当鼠标左键仍处于保持状态时,我似乎无法做到这一点,即我在面板边界的边缘停止控制并禁用可拖动功能,但是一旦我释放鼠标按钮它实际上会采取行动。这是代码:
private void CreateButtons(IList<Button> inputArray)
{
for (int i = 0; i < inputArray.Count; i++)
{
inputArray[i] = new Button
{
Height = 100,
Width = 100
};
PuzzelHolder.Controls.Add(inputArray[i]);
inputArray[i].Text = Values[i].ToString();
inputArray[i].TextAlign = ContentAlignment.MiddleCenter;
inputArray[i].Draggable(true);
inputArray[i].Location = new Point(20, 20);
inputArray[i].MouseDown += Button_Mouse_Down;
inputArray[i].MouseUp += Button_Mouse_Up;
//horizontal += inputArray[i].Width;
}
}
这就是我创建按钮的方式,因为你可以看到它们有与之相关的事件:
private void Button_Mouse_Down(object sender, MouseEventArgs e)
{
if (IsLeaving(((Control) sender), PuzzelHolder))
{
((Control) sender).Location = new Point(((Control) sender).Location.X, ((Control) sender).Location.Y);
((Control) sender).Draggable(false);
}
else
{
((Control) sender).Draggable(true);
}
}
private void Button_Mouse_Up(object sender, MouseEventArgs e)
{
((Control)sender).Draggable(true);
}
这里也是Draggable类:
public static class ControlExtension
{
private static readonly Dictionary<Control, bool> draggables =
new Dictionary<Control, bool>();
private static System.Drawing.Size mouseOffset;
public static void Draggable(this Control control, bool Enable)
{
if (Enable)
{
// enable drag feature
if (draggables.ContainsKey(control))
{ // return if control is already draggable
return;
}
// 'false' - initial state is 'not dragging'
draggables.Add(control, false);
// assign required event handlersnnn
control.MouseDown += control_MouseDown;
control.MouseUp += control_MouseUp;
control.MouseMove += control_MouseMove;
}
else
{
// disable drag feature
if (!draggables.ContainsKey(control))
{ // return if control is not draggable
return;
}
// remove event handlers
control.MouseDown -= control_MouseDown;
control.MouseUp -= control_MouseUp;
control.MouseMove -= control_MouseMove;
draggables.Remove(control);
}
}
private static void control_MouseDown(object sender, MouseEventArgs e)
{
mouseOffset = new System.Drawing.Size(e.Location);
// turning on dragging
draggables[(Control)sender] = true;
}
private static void control_MouseUp(object sender, MouseEventArgs e)
{
// turning off dragging
draggables[(Control)sender] = false;
}
private static void control_MouseMove(object sender, MouseEventArgs e)
{
// only if dragging is turned on
if (draggables[(Control)sender])
{
// calculations of control's new position
var newLocationOffset = e.Location - mouseOffset;
((Control)sender).Left += newLocationOffset.X;
((Control)sender).Top += newLocationOffset.Y;
}
}
}
答案 0 :(得分:0)
有很多方法可以做到这一点。这取决于你想要的行为。
1.允许将此按钮拖出窗体外。
您可以设置主窗体属性IsMdiContainer = true。然后通过计算相对位置,设置按钮的顶部和左侧,并使用鼠标按下事件进行操作。
void button1_MouseUp(object sender, MouseEventArgs e) { var btnDragged = ((Control)sender); var parent = btnDragged.Parent; if (btnDragged.Left parent.Width) btnDragged.Left = parent.Width - btnDragged.Width; if (btnDragged.Bottom > (parent.Height - btnDragged.Height)) btnDragged.Top = parent.Height - btnDragged.Height * 2; }
如果您不想要mdicontainer,那么只需在上面的代码中用您的主表单名称替换父变量。
如果你不想让按钮被拖到外面。你可以在鼠标移动事件中做同样的事情。但它会给你一些闪烁。 您还可以更改扩展类以支持此行为。
static void control_MouseMove(object sender, MouseEventArgs e)
{
// only if dragging is turned on
if (draggables[(Control)sender] == true)
{
var parent = ((Control)sender).Parent;
System.Drawing.Point newLocationOffset = e.Location - mouseOffset;
var controlDragged = (Control)sender;
if ((controlDragged.Left + newLocationOffset.X) >= 0 && (controlDragged.Right + newLocationOffset.X) <= parent.Width && (controlDragged.Top + newLocationOffset.Y) >= 0 && (controlDragged.Bottom + newLocationOffset.Y) < (parent.Height - controlDragged.Height))
{
controlDragged.Left += newLocationOffset.X;
controlDragged.Top += newLocationOffset.Y;
}
}
}
我希望这会有所帮助。