Верните контроль над Winforms - PullRequest
15 голосов
/ 11 апреля 2010

Существуют ли другие способы вывода элемента управления на фронт, кроме control.BringToFront ()? У меня есть серия ярлыков на пользовательском элементе управления, и когда я пытаюсь вывести одну из них на передний план, она не работает. Я даже перебрал все элементы управления и отправил их обратно, за исключением того, который мне интересен, и это ничего не меняет.

Вот метод, при котором метка добавляется в пользовательский элемент управления

private void AddUserLabel()
{
    UserLabel field = new UserLabel();
    ++fieldNumber;

    field.Name = "field" + fieldNumber.ToString();         

    field.Top = field.FieldTop + fieldNumber;
    field.Left = field.FieldLeft + fieldNumber;
    field.Height = field.FieldHeight;
    field.Width = field.FieldWidth;
    field.RotationAngle = field.FieldRotation;
    field.Barcode = field.BarCoded;
    field.HumanReadable = field.HumanReadable;
    field.Text = field.FieldText;
    field.ForeColor = Color.Black;

    field.MouseDown += new MouseEventHandler(label_MouseDown);
    field.MouseUp += new MouseEventHandler(label_MouseUp);
    field.MouseMove += new MouseEventHandler(label_MouseMove);

    userContainer.Controls.Add(field);

    SendLabelsToBack(); //Send All labels to back

    userContainer.Controls[field.FieldName].BringToFront();
}

Вот метод, который отправляет их всех обратно.

private void SendLabelsToBack()
{
    foreach (UserLabel lbl in userContainer.Controls)
    {
        lbl.SendToBack();
    }
}

Ответы [ 5 ]

19 голосов
/ 11 апреля 2010

Да, есть другой способ. Controls.SetChildIndex() также меняет Z-порядок. Тот, с индексом 0, тот, что сверху. Ничего не покупает, хотя, BringToFront() использует этот метод.

Ваш метод SendLabelsToBack(), как он указан, не может работать, он также отправит метку для добавления на оборотную сторону. Но ваше следующее утверждение исправит это снова.

Хорошо, это не работает, что означает, что метод BringToFront() не выполняется. Посмотрите в окне «Вывод» уведомление об исключении первого случая. Как написано, ваш SendLabelsToBack() вызовет исключение, если пользовательский элемент управления содержит любой элемент управления, кроме UserLabel. Кроме того, установите точку останова после вызова BringToFront() и проверьте значение userContainer.Controls[0].Name при его разрыве.

6 голосов
/ 11 апреля 2010

Элемент управления z-index для каждого контейнера.

Если вы вызовите BringToFront для элемента управления, который находится внутри контейнера (например, Panel), он не выведет контейнер на фронт.
Поэтому элемент управления будет идти только перед другими элементами управления в этом контейнере.

Чтобы увидеть, в каких контейнерах находятся ваши элементы управления, вы можете использовать панель «Структура документа» в меню «Вид».

EDIT : Ваш userContainer элемент управления, вероятно, находится за другим элементом управления.

5 голосов
/ 11 апреля 2010

Вы пробовали Invalidate() после BringToFront()? BringToFront не вызывает событие Paint

попробуйте это:

private void SendLabelsToBack()
{
    foreach (UserLabel lbl in userContainer.Controls)
    {
        lbl.SendToBack();
        lbl.Invalidate();
    }
}
2 голосов
/ 11 апреля 2010

Я думаю, вам просто нужно изменить свою последнюю строку:

userContainer.Controls[field.FieldName].BringToFront(); 

к этому:

userContainer.Controls[field.Name].BringToFront(); 

Когда вы используете строку в качестве индексатора для коллекции Controls, она передается свойством Name элемента управления (не свойством FieldName).

Поскольку вы просто пытаетесь перенести самый последний добавленный элемент управления наверх, это также будет работать:

userContainer.Controls[userContainer.Controls.Count - 1].BringToFront();
0 голосов
/ 02 ноября 2017

Из моего опыта видно, что окна помещают все элементы управления, принадлежащие одному графическому контейнеру (панели, групповому блоку и т. Д.), В коллекцию программного обеспечения. Коллекция упорядочена по дочернему индексу, который является свойством каждого элемента управления в этом контейнере. Хитрость в том, что дети с одинаковым индексом могут и существуют. В этом случае окна будут рисовать тех детей, упорядоченных по отношению к другим, но между ними это будет рисовать их в обратном порядке, они были добавлены в контейнер.

Короче говоря: для одного контейнера вы должны убедиться, что элементы управления имеют разные индексы, изменив ВСЕ, НЕ НЕКОТОРЫЕ из индексов, когда вы хотите изменить z-порядок. Например:

foreach (Control newControl in TopControl.Controls)
{
   TopControl.Controls.SetChildIndex(newControl,indexlogic(newControl));
}

где indexLogic(newControl ) - ваш метод расчета индекса конкретного контроля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...