在Canvas上的DataBound项目中设置Z-Index

时间:2011-01-31 16:32:39

标签: wpf data-binding canvas z-index

我正在尝试使用ItemsControl布局将项目列表绑定到Canvas,其中项目有多个“级别”。使用图像最容易解释:

Problem

在这种情况下,我的较低级别是一个阴影。因为我假设投影将附加到主元素(Button),我创建了另一个视觉元素,一个边框,它位于Button后面并附有阴影。我想要的是我的所有阴影元素都在同一个整体ZIndex,并且所有的Button元素都在它们之上。

在实践中,似乎WPF将我的模板内容呈现为单个UI元素,基本上将其中的ZIndex展平。我有什么方法可以使ZIndex值不被展平?

我在下面创建了一个示例,显示了问题:

<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" Background="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>

提前感谢您提出的任何想法!

2 个答案:

答案 0 :(得分:3)

由于绑定对象包含在ContentPresenter中,所有内部ZIndex设置都将被忽略,因此您无法执行所描述的操作。您可能最好为每个图层创建ItemsControl

答案 1 :(得分:0)

获取父ContentPresenter并在其上设置ZIndex

E.g:

var parent = (UIElement) VisualTreeHelper.GetParent((UIElement) sender);
parent.SetZIndex(parent, z);