Bagaimana cara membuat kontrol overlay di atas semua kontrol lainnya?

166

Saya perlu membuat kontrol muncul di atas semua kontrol lain, sehingga sebagian akan overlay.

pengguna626528
sumber

Jawaban:

162

Jika Anda menggunakan Canvasatau Griddalam tata letak Anda, berikan kontrol untuk diletakkan di atas yang lebih tinggi ZIndex.

Dari 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>

Jika Anda tidak menentukan ZIndex, anak-anak panel diberikan sesuai urutan yang ditentukan (yaitu yang terakhir di atas).

Jika Anda ingin melakukan sesuatu yang lebih rumit, Anda dapat melihat bagaimana ChildWindowpenerapannya di Silverlight. Itu melapisi latar semi-transparan dan popup seluruh Anda RootVisual.

foson
sumber
Catatan: Ini tidak seperti Kanvas HTML seperti yang saya harapkan. Ini tidak dimaksudkan untuk menggambar langsung, tetapi memberikan konteks penentuan posisi absolut (yang biasanya Anda masukkan langsung ke bentuk).
Paul
73

Robert Rossney memiliki solusi yang bagus. Inilah solusi alternatif yang pernah saya gunakan di masa lalu yang memisahkan "Hamparan" dari konten lainnya. Solusi ini memanfaatkan properti terlampir Panel.ZIndexuntuk menempatkan "Hamparan" di atas segalanya. Anda dapat mengatur Visibilitas "Hamparan" dalam kode atau menggunakan a 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>
Metro Smurf
sumber
Hamparan ini akan mencakup seluruh jendela, bukan hanya area tertentu.
Metro Smurf
Solusi terbaik yang pernah ada! Terima kasih!
Pengembang
Persis apa yang saya butuhkan untuk meletakkan "layar privasi" di seluruh jendela aplikasi saya (misalnya untuk menyembunyikan informasi sensitif jika pengguna berjalan menjauh dari mejanya), dengan kode yang sangat sedikit. Luar biasa!
Whitzz
39

Kontrol di sel yang sama dari Grid diberikan kembali ke depan. Jadi cara sederhana untuk meletakkan satu kontrol di atas yang lain adalah dengan meletakkannya di sel yang sama.

Berikut ini adalah contoh yang berguna, yang memunculkan panel yang menonaktifkan segala sesuatu dalam tampilan (yaitu kontrol pengguna) dengan pesan sibuk saat tugas jangka panjang dijalankan (yaitu saat BusyMessageproperti terikat bukan nol):

<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>
Robert Rossney
sumber
23

Letakkan kontrol yang ingin Anda bawa ke depan di akhir kode xaml Anda. Yaitu

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

Ini adalah fungsi umum Adorners di WPF. Penghias biasanya muncul di atas semua kontrol lain, tetapi jawaban lain yang menyebutkan z-order mungkin lebih sesuai dengan kasus Anda.

CodeNaked
sumber
3
<Canvas Panel.ZIndex="1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="570">
  <!-- YOUR XAML CODE -->
</Canvas>
Devam Mehta
sumber