C# Windows Forms 的修饰器

3
我在WinForms应用程序中有一个画布(Panel控件),用户可以在其中拖动文本框、标签等。但我希望让他们更容易地精确对齐对象。我已经研究过了,似乎Adorners是正确的选择?但是,显然它只适用于WPF。不幸的是,WPF对我来说不是一个选项。
我想实现的是,每当用户在画布中拖动对象时,就会出现线条...就像Windows Forms Designer视图中的工作方式一样。
我非常感谢任何帮助。
谢谢。
4个回答

3

感谢大家的回答。


我已经想出了自己的解决方案。下面是代码。目前还没有“行”(lines),但我会在某一天处理它们...

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个像素。


2

1

这是完全有可能的。看一下MSDN上的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_MouseUp事件中调用ControlPaint.DrawReversibleFrame(...)以擦除框架。此外,在控件移动期间,只需使用完全相同的参数再次调用该函数即可。希望这有所帮助。

此外,为了减少闪烁,正如Josh指出的那样,在InitializeComponents();之后添加以下内容。

//  To reduce redraw flicker
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);

1

如果我理解正确,您想设置控件,使其类似于其他容器控件(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);
    }
}

现在,我放置为子级的任何控件都会在我将其向边缘拖动时捕捉到该矩形。

希望对你有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接