BringToFront в WPF - PullRequest
       2

BringToFront в WPF

15 голосов
/ 14 апреля 2011

Мне нужно вывести на передний план пользовательский элемент управления в WPF.

псевдо-код

OnMouseDown()
{
    if (this.parent != null)
        this.parent.BringToFront(this);
}

Я знаю, я знаю , что существует ZIndex, но до сих пор не понимаю, как заменить простой WinForm BringToFront на parent.SetZIndex(this, ?MaxZIndex(parent)? + 1)?

Возможно, есть лучший способ сделать это в такой классной вещи, как WPF ?!.

Ответы [ 5 ]

18 голосов
/ 18 мая 2011

Вот функция расширения, которая добавляет функциональность метода BringToFront ко всем элементам FrameworkElements, содержащимся в Panel.

  public static class FrameworkElementExt
  {
    public static void BringToFront(this FrameworkElement element)
    {
      if (element == null) return;

      Panel parent = element.Parent as Panel;
      if (parent == null) return;

      var maxZ = parent.Children.OfType<UIElement>()
        .Where(x => x != element)
        .Select(x => Panel.GetZIndex(x))
        .Max();
      Panel.SetZIndex(element, maxZ + 1);
    }
  }
14 голосов
/ 15 апреля 2011

На самом деле лучшее, на что вы можете надеяться, - это сделать элемент самым верхним по отношению к любым элементам в одной и той же родительской панели (таким как StackPanel, Grid, Canvas и т. Д.). Z-порядок элементов в панелях управляется вложенным свойством Panel.ZIndex .

Например:

<Grid>
    <Rectangle Fill="Blue" Width="50" Height="50" Panel.ZIndex="1" />
    <Rectangle Fill="Red" Width="50" Height="50" Panel.ZIndex="0" />
</Grid>

В этом примере синий прямоугольник появится сверху. Это объясняется немного подробнее в этом блоге .

Существует также проблема с изменениями Panel.ZIndex, которые не сразу отражаются в пользовательском интерфейсе. Существует закрытый метод, который позволяет обновлять z-index, но, поскольку он закрытый, использовать его не рекомендуется. Чтобы обойти это, вам нужно удалить и повторно добавить детей.

Однако вы не можете сделать любой данный элемент самым верхним. Например:

<Grid>
    <Grid>
        <Rectangle Fill="Blue" Width="50" Height="50" Panel.ZIndex="1" />
        <Rectangle Fill="Red" Width="50" Height="50" Panel.ZIndex="0" />
    </Grid>
    <Grid>
        <Rectangle Fill="Green" Width="50" Height="50" Panel.ZIndex="0" />
        <Rectangle Fill="Yellow" Width="50" Height="50" Panel.ZIndex="0" />
    </Grid>
</Grid>

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

<Grid>
    <Grid Panel.ZIndex="1">
        <Rectangle Fill="Blue" Width="50" Height="50" Panel.ZIndex="1" />
        <Rectangle Fill="Red" Width="50" Height="50" Panel.ZIndex="0" />
    </Grid>
    <Grid Panel.ZIndex="0">
        <Rectangle Fill="Green" Width="50" Height="50" Panel.ZIndex="0" />
        <Rectangle Fill="Yellow" Width="50" Height="50" Panel.ZIndex="0" />
    </Grid>
</Grid>

При работе с ItemsControl этот вопрос актуален. У большинства других элементов управления есть один дочерний элемент, но вам все равно нужно выдвинуть его вперед, чтобы сделать любого из его дочерних элементов лучшим.

Наконец, Украшения - это хороший способ поставить вещи поверх всего, но они не являются частью основного визуального дерева. Поэтому я не уверен, что это сработает в вашем случае.

0 голосов
/ 21 января 2019

Я тестировал только для оконного элемента управления, но ...

this.Topmost = true;
this.Topmost = false;

Первая строка выводит его на передний план, вторая строка останавливает его постоянное нахождение на передней панели.

0 голосов
/ 05 мая 2016

Я нашел лучшее решение. Получите это:

foreach (var item in Grid1.Children)
{
    if ((item as UIElement).Uid == "StackPan1")
    {
        UIElement tmp = item as UIElement;
        Grid1.Children.Remove(item as UIElement);
        Grid1.Children.Add(tmp);
        break;
    }
}

Это просто пример, а не универсальный метод. Но вы можете использовать его в приложениях с динамическим добавлением элементов управления. Этот код просто добавляет элемент, который вы хотите поместить сверху и на UIElementCollection Это работает, если все ваши элементы имеют одинаковый ZIndex.

0 голосов
/ 27 сентября 2014

Я попробовал canvas.zindex, и он не сработал, но решение, которое мне помогло, это использование Border в элементе управления Popup:

<Popup IsOpen="True/False">
    <Border Background="White">
        <DatePicker/>
    </Border>
</Popup>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...