web-dev-qa-db-fra.com

WPF Listbox Afficher le bouton dans l'élémentTemplate sur MouseOver

J'ai une liste contenant et une image et un bouton. Par défaut, le bouton est masqué. Je veux rendre le bouton visible chaque fois que je vols sur un élément de la liste de liste. Le xaml que j'utilise est ci-dessous. Merci

<Window.Resources>
        <Style TargetType="{x:Type ListBox}">
    <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Border BorderBrush="Black" BorderThickness="1" Margin="6">
                                <StackPanel Orientation="Horizontal">
                                    <Image Source="{Binding Path=FullPath}" Height="150" Width="150"/>
                                    <Button x:Name="sideButton" Width="20" Visibility="Hidden"/>
                                </StackPanel>
                            </Border>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
        </Style>
    </Window.Resources>
33
NabilS

OK, essayez ceci dans votre déclaration de votre bouton:

<Button x:Name="sideButton" Width="20">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Visibility" Value="Hidden" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsMouseOver}" Value="True">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

Donc, j'utilise un style avec un déclencheur pour détourner la sauvegarde de l'arbre visuel jusqu'à la recherche d'un ListBoxItem, et lorsque sa propriété IsMouseOver passe sur True je fixe le button 's visibilité à Visible.

Voir si c'est proche de ce que vous voulez.

43
Matt Hamilton

Ce Style fait ce dont vous avez besoin. Sur la souris sur, le bouton devient visible uniquement lorsque le pointeur est sur le ListBoxItem. L'astuce spéciale est de se lier au TemplatedParent pour atteindre IsMouseOver et utiliser TargetName sur le Setter pour affecter uniquement le Button.

<Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Border BorderBrush="Black"
                        BorderThickness="1"
                        Margin="6">
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding Path=FullPath}"
                               Height="150"
                               Width="150" />
                        <Button x:Name="sideButton"
                                Width="20"
                                Visibility="Hidden" />
                    </StackPanel>
                </Border>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding IsMouseOver,RelativeSource={RelativeSource TemplatedParent}}"
                                 Value="True">
                        <Setter Property="Visibility"
                                TargetName="sideButton"
                                Value="Visible" />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>
14
David Schmitt

@David montre la bonne façon, mais j'ai une suggestion à votre architecture XAML. Si vous n'avez pas de banquets de données sur le bouton, il est préférable de mettre cela dans le style ListboxItem que celui de DataTemplate comme ci-dessous.

  <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Border BorderBrush="Black"
                    BorderThickness="1"
                    Margin="6">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="{Binding Path=FullPath}"
                           Height="150"
                           Width="150" />                             
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </Setter.Value>
        </Setter>            
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Grid Background="Transparent">
                        <Button x:Name="sideButton" Width="20" HorizontalAlignment="Right" Visibility="Hidden" />
                        <ContentPresenter/>                            
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger  Property="IsMouseOver" Value="True">
                            <Setter Property="Visibility"
                            TargetName="sideButton"
                            Value="Visible" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>            
    </Style>
5
Jobi Joy

Vous vous demandez simplement que si nous utilisons la technique ci-dessus, comment déterminons-nous quel élément a été cliqué sur le bouton?

Pour répondre à la question de Brian, dans le bouton, cliquez sur le gestionnaire, vous pouvez monter l'arborescence visuelle pour trouver l'élément contenant le bouton:

        DependencyObject dep = (DependencyObject)e.OriginalSource;
        while ((dep != null) && !(dep is ListBoxItem))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }

        if (dep != null)
        {
            // TODO: do stuff with the item here.
        }
0
donovan

Une solution pour trouver ce que l'article a été cliqué est d'ajouter le setter d'événements suivant

Xaml

C # void listboxItem_MOutenter (Expéditeur d'objet, Mouseeventargs e) {_membervar = (expéditeur en tant que ListboxItem) .Content; }

0
brianbruff