C#Windows窗体的装饰器

C#Windows窗体的装饰器,c#,winforms,controls,adorner,C#,Winforms,Controls,Adorner,我的WinForms应用程序中有一个画布(面板控件),用户可以在其中拖动文本框、标签等内容。但我想让他们更容易更精确地对齐对象。我已经读过了,装饰似乎是一种方式?但是,很明显,这只适用于WPF。不幸的是,WPF不是我的选择 我试图做到的是,每当用户拖动画布中的对象时,就会弹出一行。。。它们在Windows窗体设计器视图中的工作方式 如果有任何帮助,我将不胜感激 谢谢。这里有一个类似的问题: 在那里,我提出了如下建议: left = (left/10)*10; top = (top/10)*10;

我的WinForms应用程序中有一个画布(面板控件),用户可以在其中拖动文本框、标签等内容。但我想让他们更容易更精确地对齐对象。我已经读过了,装饰似乎是一种方式?但是,很明显,这只适用于WPF。不幸的是,WPF不是我的选择

我试图做到的是,每当用户拖动画布中的对象时,就会弹出一行。。。它们在Windows窗体设计器视图中的工作方式

如果有任何帮助,我将不胜感激


谢谢。

这里有一个类似的问题:

在那里,我提出了如下建议:

left = (left/10)*10;
top = (top/10)*10;

对于捕捉部分。另一位用户指出了可能会帮助您解决问题的方法。

这是很有可能做到的。查看上的
DrawReversibleLine
方法。同时,我将尝试找到一些代码,在其中我做了同样的事情

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\u MouseUp
事件中,调用ControlPaint.DrawReversibleFrame(…)以擦除帧。此外,在控制移动期间。只需使用完全相同的参数再次调用该函数即可。希望有帮助

另外,如Josh所指出的,为了减少闪烁,在
InitializeComponents()之后添加以下内容:


谢谢大家的回答


我设法想出了自己的解决办法。代码在下面。现在还没有“台词”,但总有一天我会去做的

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();
}
标签l=(标签)发送方;
foreach(Canvas.Controls中的控件)
{
if(l.Location.X>control.Location.X+control.Size.Width&&l.Location.Xcontrol.Location.X-l.Size.Width-5)
l、 位置=新点(control.Location.X-l.Size.Width-5,l.Location.Y);
else if(l.Location.Y>control.Location.Y+control.Size.Height&&l.Location.Ycontrol.Location.Y-control.Size.Height-5)
l、 位置=新点(l.Location.X,l.Location.Y-5);
这个.Update();
}
上面的代码必须放在控件\u MouseMove事件中,当然,您仍然需要自己的代码来实际移动控件


上面的代码将捕捉您正在将5个像素拖动到最近控件的右侧、左侧、顶部或底部的控件。

如果我理解正确,您希望设置控件,使其与其他容器控件(GroupBox、Panel等)类似

如果是这样的话,我想这就是你想要的。将其更改为希望其他控件捕捉到的矩形。例如,我有一个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);
    }
}
现在,当我将其向边缘拖动时,我作为孩子放置的任何控件都将捕捉到该矩形

public override Rectangle DisplayRectangle
{
    get
    {
        return Rectangle.FromLTRB(base.DisplayRectangle.Left,
            base.DisplayRectangle.Top + Font.Height + 4,
            base.DisplayRectangle.Right,
            base.DisplayRectangle.Bottom);
    }
}