Кнопка просмотра списка WPF в ItemTemplate на MouseOver
У меня есть список, содержащий и изображение, и кнопку. По умолчанию кнопка скрыта. Я хочу, чтобы кнопка отображалась всякий раз, когда я наводил курсор на элемент в списке.
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>
Ответы
Ответ 1
Хорошо, попробуйте это в объявлении кнопки:
<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>
Итак, я использую стиль с триггером, чтобы посмотреть на визуальное дерево, пока не найду ListBoxItem
, и когда его свойство IsMouseOver
перейдет на True
, я установил видимость button
на Visible
.
Посмотрите, насколько это близко к тому, что вы хотите.
Ответ 2
Этот Style
делает то, что вам нужно. При наведении мыши кнопка становится видимой только тогда, когда указатель находится над ListBoxItem
. Особым трюком является привязка к TemplatedParent
для достижения 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>
Ответ 3
@Давид показывает правильный путь,
Но у меня есть одно предложение для вашей архитектуры XAML. Если у вас нет DataBinding на Button, лучше поместить это в стиль 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>
Ответ 4
Одним из решений для поиска того, что был нажат элемент, является добавление следующего средства настройки событий
XAML
С#
void ListBoxItem_MouseEnter (отправитель объекта, MouseEventArgs e) { _memberVar = (отправитель как ListBoxItem).Content; }
Ответ 5
Просто интересно, если мы используем технику выше, как определить, на какой элемент нажата кнопка?
Чтобы ответить на вопрос Брайана, в обработчике нажатия кнопки вы можете подойти к визуальному дереву, чтобы найти элемент, содержащий кнопку:
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.
}