Setting Z-Index in DataBound items on a Canvas
I am trying to bind a list of items to an ItemsControl
, using a Canvas
layout, where the item has multiple "levels". This is easiest to explain using an image:
My lower level is a drop-shadow in this case. Because I assumed the drop shadow would be attached to the main element (a Button
), I created another visual element, a Border, which sits behind the Button and has the shadow attached. What I would like is for all of my shadow elements to be at the same overall ZIndex
, and all of the Button elements to be above them.
In practice, it appears that WPF renders the contents of my template as a single UI element, essentially flattening the ZIndex
es within it. Is there any way I can make it so that the ZIndex
values are not flattened?
I have created a sample below which shows the problem:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="250" Width="600" Background="White">
<Window.Resources>
<DropShadowEffect Color="Blue" BlurRadius="75" x:Key="ActionDropShadow" />
<XmlDataProvider x:Key="myData" XPath="Data/Items">
<x:XData>
<Data xmlns="">
<Items>
<Item X="50" Title="AAA" />
<Item X="100" Title="BBB" />
<Item X="150" Title="CCC" />
</Items>
</Data>
</x:XData>
</XmlDataProvider>
<DataTemplate x:Key="BoxTemplate">
<Grid>
<Border Background="Black" BorderThickness="1" Effect="{StaticResource ActionDropShadow}" />
<Button Background="White" BorderThickness="1">
<TextBlock Text="{Binding XPath=@Title}" />
</Button>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ItemsControl Grid.Column="0" x:Name="list" ItemTemplate="{StaticResource BoxTemplate}" ItemsSource="{Binding Source={StaticResource myData},XPath=*}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding XPath=@X}" />
<Setter Property="Canvas.Top" Value="50" />
<Setter Property="Width" Value="50" />
<Setter Property="Height" Value="80" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<Canvas Grid.Column="1">
<Border Panel.ZIndex="5" Canvas.Top="50" Canvas.Left="50" Width="50" Height="80" Backgr开发者_如何学运维ound="Black" BorderThickness="1" Effect="{StaticResource ActionDropShadow}" />
<Button Panel.ZIndex="10" Canvas.Top="50" Canvas.Left="50" Width="50" Height="80" Background="White" BorderThickness="1">
<TextBlock Text="AAA" />
</Button>
<Border Panel.ZIndex="5" Canvas.Top="50" Canvas.Left="100" Width="50" Height="80" Background="Black" BorderThickness="1" Effect="{StaticResource ActionDropShadow}" />
<Button Panel.ZIndex="10" Canvas.Top="50" Canvas.Left="100" Width="50" Height="80" Background="White" BorderThickness="1">
<TextBlock Text="BBB" />
</Button>
<Border Panel.ZIndex="5" Canvas.Top="50" Canvas.Left="150" Width="50" Height="80" Background="Black" BorderThickness="1" Effect="{StaticResource ActionDropShadow}" />
<Button Panel.ZIndex="10" Canvas.Top="50" Canvas.Left="150" Width="50" Height="80" Background="White" BorderThickness="1">
<TextBlock Text="CCC" />
</Button>
</Canvas>
<TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center">Databinding Version</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center">What it should look like</TextBlock>
</Grid>
</Window>
Thanks in advance for any ideas you can offer!
Since the bound objects are wrapped in a ContentPresenter
all internal ZIndex
settings will be ignored, so you cannot do what you described. You might be better off creating an ItemsControl
for each layer.
Get the parent ContentPresenter
and set ZIndex
on that.
E.g:
var parent = (UIElement) VisualTreeHelper.GetParent((UIElement) sender);
parent.SetZIndex(parent, z);
精彩评论