WPF Listbox Show Button in ItemTemplate on MouseOver

后端 未结 5 1501
既然无缘
既然无缘 2020-12-23 09:56

I have a listbox containing and image and a button. By default the button is hidden. I want to make the button visible whenever I hover over an item in the listbox. The XAML

相关标签:
5条回答
  • 2020-12-23 10:02

    One solution to find what item was clicked is to add the following Event setter

    XAML

    C# void ListBoxItem_MouseEnter(object sender, MouseEventArgs e) { _memberVar = (sender as ListBoxItem).Content; }

    0 讨论(0)
  • 2020-12-23 10:07

    This Style does what you need. On mouse over, the button becomes only visible when the pointer is over the ListBoxItem. The special trick is to bind to the TemplatedParent for reaching IsMouseOver and use TargetName on the Setter to only affect the 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>
    
    0 讨论(0)
  • 2020-12-23 10:09

    Just wondering, if we use the technique above, how do we determine what item the button was clicked on?

    To answer Brian's question, in the button click handler you can walk up the visual tree to find the item that contains the button:

            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 讨论(0)
  • 2020-12-23 10:10

    Ok, try this in your button declaration:

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

    So I'm using a style with a trigger to look back up the visual tree until I find a ListBoxItem, and when its IsMouseOver property flips over to True I set the button's visibility to Visible.

    See if it's close to what you want.

    0 讨论(0)
  • 2020-12-23 10:24

    @David is showing the right way, But I have one suggestion to your XAML architecture. If you don't have any DataBinding on the Button it is better to put that in to the ListBoxItem style than the DataTemplate as bellow.

      <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>
    
    0 讨论(0)
提交回复
热议问题