鼠标悬停在 ItemTemplate 中的 WPF 列表框显示按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/206495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Listbox Show Button in ItemTemplate on MouseOver
提问by Matt Hamilton
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 I am using is below. Thanks
我有一个包含图像和按钮的列表框。默认情况下,该按钮是隐藏的。每当我将鼠标悬停在列表框中的项目上时,我都想让该按钮可见。我正在使用的 XAML 如下。谢谢
<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>
回答by Matt Hamilton
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
.
所以我使用带触发器的样式来查看可视化树,直到找到 a ListBoxItem
,当它的IsMouseOver
属性翻转为 时,True
我将 thebutton
的可见性设置为Visible
.
See if it's close to what you want.
看看它是否接近你想要的。
回答by David Schmitt
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
可以满足您的需求。鼠标悬停时,按钮仅在指针悬停在 上时才可见ListBoxItem
。特殊的技巧是绑定到TemplatedParent
for 到达IsMouseOver
并TargetName
在 上使用Setter
以仅影响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>
回答by Jobi Joy
@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.
@David 展示了正确的方式,但我对您的 XAML 架构有一个建议。如果按钮上没有任何数据绑定,最好将其放入 ListBoxItem 样式而不是如下所示的 DataTemplate。
<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>
回答by Jobi Joy
One solution to find what item was clicked is to add the following Event setter
查找单击的项目的一种解决方案是添加以下事件设置器
XAML
XAML
C# void ListBoxItem_MouseEnter(object sender, MouseEventArgs e) { _memberVar = (sender as ListBoxItem).Content; }
C# void ListBoxItem_MouseEnter(object sender, MouseEventArgs e) { _memberVar = (sender as ListBoxItem).Content; }
回答by donovan
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:
要回答 Brian 的问题,在按钮单击处理程序中,您可以沿着可视化树向上查找包含该按钮的项目:
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.
}