36 votes

Avancer l’élément (index Z) dans Silverlight / WPF

L'ensemble de la documentation et des exemples, je suis la recherche en ligne pour le réglage de Z-Index pour apporter un élément de l'avant dans Silverlight sont à l'aide d'une Toile de l'élément conteneur.

Mes produits sont des éléments de Frontière à l'intérieur d'un ItemsControl le récipient dans un DataTemplate. Je suis en utilisant le MouseEnter et MouseLeave pour déclencher une animation sur le ScaleTransform.Les propriétés ScaleX et ScaleTransform.ScaleY, afin qu'ils grandissent lors de son survol. Comme ils sont redimensionnées et occuper le même espace que d'autres éléments dans le conteneur(s), le plus récemment ajouté les éléments sont imbriqués les éléments anciens (par opposition à la actuellement de redimensionnement de l'objet). Est-il un moyen PROPRE à ramener le point de l'avant dans le code où je déclencheur de mon animation, de sorte qu'elles se chevauchent, tous les autres éléments lorsqu'ils sont redimensionnées?

34voto

user127111 Points 311

J'ai eu affaire avec ce.

Disons que vous avez un ItemsControl avec un ItemTemplate définie à une instance d'un contrôle personnalisé. Au sein de ce contrôle, vous n'en Toile.SetZIndex(ce, 99). Ça ne marchera pas, parce que "cela" n'est pas l'enfant immédiat de la ItemsControl de ItemsPanel. Le ItemsControl crée un ContentPresenter pour chaque élément, que des gouttes dans le ItemsPanel, et rend l'ItemTemplate dans le ContentPresenter.

Donc, si vous voulez changer le ZIndex à l'intérieur de votre contrôle, vous avez à trouver son ContentPresenter, et de changer le ZIndex sur que. Une façon est...

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

15voto

Robert Macnee Points 6998

Dans WPF, il y a le Panneau.ZIndex de la propriété que vous pouvez définir dans un trigger:

<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>

Dans l' Style pour ContentPresenter nous avons mis l' Panel.ZIndex à 99999 lorsqu' IsMouseOver est true. Il doit être sur le qui - ContentPresenter et pas l' Border parce que l' ContentPresenters sont des enfants de l' ItemsControls'panneau.

Malheureusement, je ne pense pas que cette propriété a fait à Silverlight encore...

3voto

Michał Suliga Points 21

Pour un contrôle qui utilise la grille en tant que LayoutRoot, vous pouvez simplement faire quelque chose d'aussi simple que cela dans un contrôle lui-même:

 Canvas.SetZIndex(this, 999);
 

3voto

Commencez par trouver le ZIndex maximal de tous ses éléments enfants, puis définissez le nouveau ZIndex.

 private int MaxZIndex()
{
    int iMax = 0;
    foreach (UIElement element in JIMSCanvas.Children)
    {            
        int iZIndex=Canvas.GetZIndex(element);
        if(iZIndex>iMax)
        {
            iMax = iZIndex;
        }
    }
    return iMax+1;
}
 

Puis assigner

 Canvas.SetZIndex(child, MaxZIndex());
 

2voto

Sorskoot Points 5882

Tout d'abord, la propriété attachée Zindex est défini dans la Toile et n'est donc pas disponible dans d'autres dérivés du Panneau.

Le ItemsControl ordres, les sous-éléments selon l'ordre de la liste. Le premier Élément en bas de la pile, et la dernière sur le dessus. Avec cette donnée, tout ce que vous avez à faire est de s'assurer que l'élément sélectionné est en bas de la liste.

D'abord créer une interface pour la commande. Comme ceci:

interface IOrderable
    {
        int theZOrder{get;set;}
    }

Maintenant implémenter dans la classe que vous nous présentez.

Lorsque vous souhaitez mettre un point à l'avant, de lui donner un nombre élevé et de donner à tous les autres, un faible nombre.

Al y est à gauche est l'ordre réel. Ajouter quelque chose comme cela, et vous êtes fixés:

ItemsCont.ItemsSource = 
            ItemsCont.Items.OrderByDesc(t=>((IOrderable)t).theZOrder);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X