Украшатели для C # Windows Forms - PullRequest
3 голосов
/ 11 февраля 2010

В моем приложении WinForms есть холст (панель управления), где пользователи могут перетаскивать такие элементы, как текстовые поля, ярлыки и т. Д. Но я хочу, чтобы им было проще выровнять объекты. Я прочитал об этом, и кажется, что Adorners - это путь? Но, видимо, это только для WPF. К сожалению, WPF для меня не вариант.

То, что я пытаюсь сделать, это чтобы всплывающие строки появлялись каждый раз, когда пользователь перетаскивает объект на холсте ... Как они работают в представлении дизайнера Windows Forms.

Буду признателен за любую помощь.

Спасибо.

Ответы [ 4 ]

3 голосов
/ 12 февраля 2010

Спасибо всем за ваши ответы.

<ч />

Мне удалось найти собственное решение. Код ниже. Пока нет никаких "линий", но я обойду это в один день ...

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 голосов
/ 12 февраля 2010

Здесь был похожий вопрос: Строки Snap-To при выравнивании элементов управления во время выполнения

Где я предложил что-то вроде:

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

Для оснастки. Другой пользователь указал на Form Desginer , который может вам помочь.

1 голос
/ 28 июня 2010

Если я правильно понимаю, вы хотите настроить свой элемент управления так, чтобы он действовал подобно другим элементам управления контейнера (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);
    }
}

Теперь любой элемент управления, который я помещаю как ребенок, привязывается к этому прямоугольнику, когда я перетаскиваю его к краям.

НТН!

1 голос
/ 12 февраля 2010

Это вполне возможно сделать. Посмотрите на метод DrawReversibleLine на MSDN . А пока я попытаюсь найти какой-нибудь код, в котором я делал то же самое.

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 (...), чтобы стереть кадр. Также во время контроля движения. Повторный вызов функции с точно такими же параметрами - это все, что вам нужно. Надеюсь, это поможет.

Кроме того, чтобы уменьшить мерцание , как отмечает Джош, добавьте следующее после вашего InitializeComponents();

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