开发者

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:

Setting Z-Index in DataBound items on a Canvas

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 ZIndexes 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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜