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

166

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

user626528
источник

Ответы:

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.

foson
источник
Примечание. Это не похоже на 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-порядок, могут лучше соответствовать вашему случаю.

CodeNaked
источник
3
<Canvas Panel.ZIndex="1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="570">
  <!-- YOUR XAML CODE -->
</Canvas>
Девам Мехта
источник