Приведение управления Winforms в начало

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

Ответ 1

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

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

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

Ответ 2

Значения z-index для каждого контейнера.

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

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

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

Ответ 3

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

попробуйте следующее:

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

Ответ 4

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

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

:

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

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

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

userContainer.Controls[userContainer.Controls.Count - 1].BringToFront();

Ответ 5

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

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

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

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

Ответ 6

Что мы должны сделать, чтобы проверить, находится ли контроль впереди или нет?