Reputation: 371
I am having a problem with DataTemplates used in a WPF ItemsControl. I want to be able to "bring forward" any of the items in the list so that they are on top of everything else in the list, but haven't had any luck.
Here's a simple example that illustrates the problem. What I want to see is achieved in the example using a WrapPanel and a bunch of colored blocks:
The first block overlaps the second. Good. When I try to do the same thing with the ItemsControl, the first block falls underneath the second, despite its ZIndex:
How can I make the first block overlap all the others in the ItemsControl?
From my understanding of the ZIndex property, I am assuming that I need to set the ZIndex higher up in the Visual Tree than the Border inside of the DataTemplate, but don't know how or where to do that.
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MainViewModel x:Key="mainViewModel" />
<DataTemplate DataType="{x:Type local:FireFighter}">
<Border Background="Pink" Padding="8" Panel.ZIndex="10" Margin="4">
<Border.RenderTransform>
<TranslateTransform X="18" Y="4"/>
</Border.RenderTransform>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"/>
</StackPanel>
</Border>
</DataTemplate>
<DataTemplate DataType="{x:Type local:PoliceOfficer}">
<Border Background="Orange" Padding="8" Margin="4">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"/>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ItemsControl DataContext="{StaticResource mainViewModel}"
ItemsSource="{Binding People}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<WrapPanel Margin="0,10,0,0">
<Border Background="Blue" Width="30" Height="30" Margin="4" Panel.ZIndex="10">
<Border.RenderTransform>
<TranslateTransform X="18" Y="4"/>
</Border.RenderTransform>
</Border>
<Border Background="Green" Width="30" Height="30" Margin="4"/>
<Border Background="Green" Width="30" Height="30" Margin="4"/>
</WrapPanel>
</StackPanel>
Upvotes: 4
Views: 5209
Reputation: 3774
I was looking for something similar and this is what did it for me. Use a UniformGrid as your ItemsPanelTemplate, then change the margins on your DataTemplate to overlap as much as you want.
<Grid Grid.Row="1"
Grid.ColumnSpan="2">
<Grid.Resources>
<local:PointsToPathConverter x:Key="pointsToPathConverter"/>
</Grid.Resources>
<Image
Source="{Binding Bmp}"
Stretch="Fill"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
<ItemsControl ItemsSource="{Binding AllTraceLines}"
VerticalAlignment="Stretch"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path Margin="0,-20,0,-20" Data="{Binding Converter={StaticResource pointsToPathConverter}}" Stroke="Red" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Fill"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Upvotes: 0
Reputation: 371
I found an answer that will work for my situation right here:
https://stackoverflow.com/a/9687758/4912801
It turns out that setting the Panel.ZIndex property wasn't working because WPF inserts a ContentPresenter element for each item in the ItemsControl. In my application, I was trying to get whatever element the mouse is hovering over to come to the front, so applying a style to all ContentPresenters in the ItemsControl allowed me to bring them to the front when the mouse was over them.
Upvotes: 1