ItemsControl中使用的WPF扩展器覆盖
本文关键字:WPF 扩展器 覆盖 ItemsControl | 更新日期: 2023-09-27 18:26:51
我已经搜索了一段时间,但我找到的所有解决方案都只解决了部分问题。我想要一个ItemsControl,每个项目都包含一个扩展器。展开时,扩展器的内容应显示为覆盖ItemsControl中的其他项,而不是向下移动它们。
下面的XAML代码正好解决了一个大问题:扩展器的内容不与其他项重叠,而是隐藏在它们后面。我想这是由于ZIndex,因为ItemsControl中的以下项目被添加到扩展器的内容之后。
我设法使用样式触发器将一个Expander的ZIndex设置为99,但这似乎是一个过于复杂且容易出错的解决方案。有什么想法吗?
<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<x:Array x:Key="items"
Type="sys:String"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String>One</sys:String>
<sys:String>Two</sys:String>
<sys:String>Three</sys:String>
<sys:String>Four</sys:String>
</x:Array>
<DataTemplate x:Key="template">
<Grid Background="Red" Margin="0,0,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding}" />
<Canvas Height="25" Grid.Row="1">
<Expander ExpandDirection="Down" Header="Header" Grid.Row="1">
<Expander.Content>
<TextBlock Height="80" Text="Content" Background="Yellow" />
</Expander.Content>
</Expander>
</Canvas>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<ScrollViewer>
<ItemsControl ItemsSource="{StaticResource items}"
ItemTemplate="{StaticResource template}"
HorizontalContentAlignment="Stretch">
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
用你尝试的方式实现这一点会很困难。问题是嵌套结构——因为每个Canvas
都嵌套在一个Grid
内,所以你将无法控制它相对于其他Canvas元素的z索引。为了说明这一点,下面是由当前标记创建的视觉树的示意图:
<StackPanel> <!-- items panel -->
<ContentPresenter> <!-- item wrapper -->
<Grid>
<Canvas>
</Canvas>
</Grid>
</ContentPresenter>
<ContentPresenter> <!-- item wrapper -->
<Grid>
<Canvas>
</Canvas>
</Grid>
</ContentPresenter>
</StackPanel>
参考以上内容,您的目标是使Canvas
元素出现在其父ContentPresenter
的同级元素前面。这在该层次结构中是不可能的,因为ZIndex
仅相对于同一父元素的同级元素应用。现在,可能有一些方法可以将以上内容按摩成一个平面结构,这样您就可以根据需要应用ZIndex扩展内容。
然而,我认为一种更简单、更自然的方法是将Popup
元素用于扩展的内容。Popup是一个位于视觉树之外的框架基元,它将始终位于其他内容之上。您可以使用ToggleButton或类似的东西来创建"展开"效果。例如:
<StackPanel Grid.Row="1">
<ToggleButton x:Name="PopupToggle" Content="Expand" />
<Popup IsOpen="{Binding IsChecked,ElementName=PopupToggle}">
<TextBlock Height="80" Text="Content" Background="Yellow" />
</Popup>
</StackPanel>