Как сделать наложение контроля над всеми другими элементами управления?


166

Мне нужно, чтобы элемент управления отображался над всеми другими элементами управления, чтобы он частично перекрывал их.

Ответы:


162

Если вы используете Canvasили Gridв вашем макете, дайте элемент управления, который будет помещен сверху выше ZIndex.

Из MSDN :

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="ZIndex Sample">
  <Canvas>
    <Rectangle Canvas.ZIndex="3" Width="100" Height="100" Canvas.Top="100" Canvas.Left="100" Fill="blue"/>
    <Rectangle Canvas.ZIndex="1" Width="100" Height="100" Canvas.Top="150" Canvas.Left="150" Fill="yellow"/>
    <Rectangle Canvas.ZIndex="2" Width="100" Height="100" Canvas.Top="200" Canvas.Left="200" Fill="green"/>

    <!-- Reverse the order to illustrate z-index property -->

    <Rectangle Canvas.ZIndex="1" Width="100" Height="100" Canvas.Top="300" Canvas.Left="200" Fill="green"/>
    <Rectangle Canvas.ZIndex="3" Width="100" Height="100" Canvas.Top="350" Canvas.Left="150" Fill="yellow"/>
    <Rectangle Canvas.ZIndex="2" Width="100" Height="100" Canvas.Top="400" Canvas.Left="100" Fill="blue"/>
  </Canvas>
</Page>

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

Если вы хотите сделать что-то более сложное, вы можете посмотреть, как ChildWindowэто реализовано в Silverlight. Он перекрывает полупрозрачный фон и всплывающее окно на весь ваш RootVisual.


Примечание. Это не похоже на HTML-холст, как я ожидал. Он не предназначен для прямого рисования, но предоставляет контекст абсолютного позиционирования (в который вы обычно непосредственно помещаете фигуры).
— Пол

73

Роберт Россни имеет хорошее решение. Вот альтернативное решение, которое я использовал в прошлом, которое отделяет «Наложение» от остального содержимого. Это решение использует преимущество присоединенного свойства, Panel.ZIndexчтобы поместить «Наложение» поверх всего остального. Вы можете либо установить видимость «наложения» в коде, либо использовать DataTrigger.

<Grid x:Name="LayoutRoot">

 <Grid x:Name="Overlay" Panel.ZIndex="1000" Visibility="Collapsed">
    <Grid.Background>
      <SolidColorBrush Color="Black" Opacity=".5"/>
    </Grid.Background>

    <!-- Add controls as needed -->
  </Grid>

  <!-- Use whatever layout you need -->
  <ContentControl x:Name="MainContent" />

</Grid>

Это наложение будет охватывать все окно, а не только конкретную область.
— Метро Смурф

Лучшее решение! Спасибо!
— Разработчик

Именно то, что мне было нужно, чтобы выложить «экран конфиденциальности» поверх всего окна моего приложения (например, чтобы скрыть конфиденциальную информацию, если пользователь уходит со своего рабочего стола), с очень небольшим кодом. Потрясающие!
— Уитц

40

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

Вот полезный пример, который открывает панель, которая отключает все в представлении (т.е. пользовательский элемент управления) с занятым сообщением, пока выполняется долго выполняемая задача (то есть, когда BusyMessageсвойство bound не равно нулю):

<Grid>

    <local:MyUserControl DataContext="{Binding}"/>

    <Grid>
        <Grid.Style>
            <Style TargetType="Grid">
                <Setter Property="Visibility"
                        Value="Visible" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding BusyMessage}"
                                 Value="{x:Null}">
                        <Setter Property="Visibility"
                                Value="Collapsed" />
                    </DataTrigger>

                </Style.Triggers>
            </Style>
        </Grid.Style>
        <Border HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                Background="DarkGray"
                Opacity=".7" />
        <Border HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Background="White"
                Padding="20"
                BorderBrush="Orange"
                BorderThickness="4">
            <TextBlock Text="{Binding BusyMessage}" />
        </Border>
    </Grid>
</Grid>

23

Поместите элемент управления, который вы хотите перенести, в конец кода xaml. Т.е.

<Grid>
  <TabControl ...>
  </TabControl>
  <Button Content="ALways on top of TabControl Button"/>
</Grid>

13

Это обычная функция Adorners в WPF. Украшатели обычно отображаются над всеми другими элементами управления, но другие ответы, в которых упоминается z-порядок, могут лучше соответствовать вашему случаю.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.