在Silverlight/WPF中使元素向前(Z索引)

Ric*_*ich 36 c# silverlight wpf xaml

我在网上找到的用于设置Z-Index以在Silverlight中引入元素的所有文档和示例都使用Canvas元素作为容器.

我的项目是DataTemplate中ItemsControl容器内的Border元素.我正在使用MouseEnter和MouseLeave事件在ScaleTransform.ScaleX和ScaleTransform.ScaleY上触发动画,以便它们在悬停时生长.由于它们已调整大小并占据与容器中其他项目相同的空间,因此最近添加的项目与旧项目重叠(与当前调整大小的项目相对).有没有一种清洁方法可以将当前项目转发到我触发动画的代码中,以便它们在调整大小时重叠所有其他项目?

小智 34

我不得不处理这件事.

假设您有一个ItemsControl,其中ItemTemplate设置为自定义控件的实例.在该控件中,您可以执行Canvas.SetZIndex(this,99).它不起作用,因为"this"不是ItemsControl的ItemsPanel的直接子节点.ItemsControl为每个项目创建一个ContentPresenter,将其放入ItemsPanel,并在ContentPresenter中呈现ItemTemplate.

因此,如果要在控件中更改ZIndex,则必须找到其ContentPresenter,并更改其上的ZIndex.一种方法是......

        public static T FindVisualParent<T>( this DependencyObject obj )
        where T : DependencyObject
    {
        DependencyObject parent = VisualTreeHelper.GetParent( obj );
        while ( parent != null )
        {
            T typed = parent as T;
            if ( typed != null )
            {
                return typed;
            }
            parent = VisualTreeHelper.GetParent( parent );
        }
        return null;
    }
                ContentPresenter foo = this.FindVisualParent<ContentPresenter>();
            Canvas.SetZIndex( foo, 99 );
Run Code Online (Sandbox Code Playgroud)


Rob*_*nee 15

在WPF中,您可以在触发器中设置Panel.ZIndex属性:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid.Resources>
        <x:Array x:Key="colors" Type="{x:Type Color}">
            <Color>Green</Color>
            <Color>Red</Color>
            <Color>Blue</Color>
            <Color>Orange</Color>
            <Color>Yellow</Color>
            <Color>Violet</Color>
        </x:Array>
        <DataTemplate DataType="{x:Type Color}">
            <Border x:Name="brd" Height="20" Width="20">
                <Border.Background>
                    <SolidColorBrush Color="{Binding}"/>
                </Border.Background>
                <Border.RenderTransform>
                    <ScaleTransform CenterX="10" CenterY="10"/>
                </Border.RenderTransform>
                <Border.Style>
                    <Style TargetType="{x:Type Border}">
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="BorderThickness" Value="2"/>
                                <Setter Property="BorderBrush" Value="Black"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
                <Border.Triggers>
                    <EventTrigger RoutedEvent="Border.MouseEnter">
                        <BeginStoryboard>
                            <Storyboard>
                               <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleX" To="1.5"/>
                               <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="1.5"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="Border.MouseLeave">
                        <BeginStoryboard>
                            <Storyboard>
                               <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleX" To="1"/>
                               <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="1"/>
                            </Storyboard>
                        </BeginStoryboard>
                  </EventTrigger>
                </Border.Triggers>
            </Border>
        </DataTemplate>
    <Style TargetType="{x:Type ContentPresenter}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Panel.ZIndex" Value="99999"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    </Grid.Resources>
    <ItemsControl ItemsSource="{StaticResource colors}" Margin="20" Width="40">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)

StyleContentPresenter我们设置Panel.ZIndex到99999的时候IsMouseOvertrue.它必须在ContentPresenter而不是Border因为ContentPresenters是ItemsControl小组的孩子.

不幸的是,我不认为这个属性做了它对Silverlight的还...

  • 很好的回答 - 这对我帮助很大. (3认同)

Sor*_*oot 2

首先,附加属性 Zindex 是在Canvas中定义的,因此在 Panel 的其他衍生产品中不可用。

ItemsControl 根据列表的顺序对子元素进行排序。第一个项目位于堆栈底部,最后一个项目位于顶部。有了这个,您所要做的就是确保所选项目位于列表底部。

首先创建一个用于订购的接口。像这样:

interface IOrderable
    {
        int theZOrder{get;set;}
    }
Run Code Online (Sandbox Code Playgroud)

现在在您所展示的课程中实现这一点。

当您想要将某个项目放在前面时,请为其指定一个较高的数字,并为所有其他项目指定一个较低的数字。

剩下的就是实际的订购了。添加类似这样的内容就可以了:

ItemsCont.ItemsSource = 
            ItemsCont.Items.OrderByDesc(t=>((IOrderable)t).theZOrder);
Run Code Online (Sandbox Code Playgroud)