我的 WinForms 应用程序中有一个画布(面板控件),用户可以在其中拖动文本框、标签等内容。但我想让他们更容易更精确地对齐对象。我读过它,装饰器似乎是要走的路?但是,显然它只适用于 WPF。不幸的是,WPF 不是我的选择。
我想要完成的是每次用户在画布中拖动对象时都会弹出线条......它们在 Windows 窗体设计器视图中的工作方式。
我会很感激任何帮助。
谢谢你。
谢谢大家的答案。
我设法想出了自己的解决方案。代码在下面。还没有“台词”,但总有一天我会解决的……
Label l = (Label)sender;
foreach (Control control in Canvas.Controls)
{
if (l.Location.X > control.Location.X + control.Size.Width && l.Location.X < control.Location.X + control.Size.Width + 5)
l.Location = new Point(control.Location.X + control.Size.Width + 5, l.Location.Y);
else if (l.Location.X < control.Location.X - l.Size.Width && l.Location.X > control.Location.X - l.Size.Width - 5)
l.Location = new Point(control.Location.X - l.Size.Width - 5, l.Location.Y);
else if (l.Location.Y > control.Location.Y + control.Size.Height && l.Location.Y < control.Location.Y + control.Size.Height + 5)
l.Location = new Point(l.Location.X, control.Location.Y + control.Size.Height + 5);
else if (l.Location.Y < control.Location.Y - control.Size.Height && l.Location.Y > control.Location.Y - control.Size.Height - 5)
l.Location = new Point(l.Location.X, l.Location.Y - 5);
this.Update();
}
上述代码必须放在 Control_MouseMove 事件中,当然,您仍然需要自己的代码来实际移动控件。
上面的代码会将您拖动 5 个像素的控件捕捉到最近控件的右侧、左侧、顶部或底部。
这里有一个类似的问题:Snap-To lines when aligning controls at Runtime
我建议的地方是:
left = (left/10)*10;
top = (top/10)*10;
对于按扣部分。另一位用户指出Form Desginer可能会对您有所帮助。
这是很有可能做到的。查看MSDNDrawReversibleLine
上的方法。同时,我将尝试找到一些我正在做同样事情的代码。
bool AllowResize;
bool DoTracking;
private void MyControl_MouseDown(object sender, MouseEventArgs e)
{
if (AllowResize)
{
DoTracking = true;
ControlPaint.DrawReversibleFrame(new Rectangle(this.PointToScreen(new Point(1,1)),
this.Size), Color.DarkGray, FrameStyle.Thick);
}
}
我知道这是一个非常普遍且主要是粗略的开始,但如前所述,这可能是一项乏味的任务。尤其是在跟踪运动等方面。请记住,在MyControl_MouseUp
事件中调用 ControlPaint.DrawReversibleFrame(...) 以擦除帧。此外,在控制运动期间。您只需要使用完全相同的参数再次调用该函数。希望有帮助。
此外,为了减少flicker,正如 Josh 指出的那样,在您的后面添加以下内容InitializeComponents();
// To reduce redraw flicker
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
如果我理解正确,您希望设置您的控件,使其行为类似于其他容器控件(GroupBox、Panel 等)?
如果是这样,我认为 DisplayRectangle 就是您所追求的。您将其更改为您希望其他控件捕捉到的矩形。例如,我有一个 GroupBox 样式控件,我将 DisplayRectangle 设置为:
public override Rectangle DisplayRectangle
{
get
{
return Rectangle.FromLTRB(base.DisplayRectangle.Left,
base.DisplayRectangle.Top + Font.Height + 4,
base.DisplayRectangle.Right,
base.DisplayRectangle.Bottom);
}
}
现在,当我将它拖向边缘时,我小时候放置的任何控件都会捕捉到该矩形。
!