Кнопка Показать список WPF в ItemTemplate на MouseOver - PullRequest
33 голосов
/ 16 октября 2008

У меня есть список, содержащий и изображение и кнопку. По умолчанию кнопка скрыта. Я хочу, чтобы кнопка отображалась при наведении курсора на элемент в списке. Я использую 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>

Ответы [ 5 ]

41 голосов
/ 16 октября 2008

Хорошо, попробуйте это в объявлении вашей кнопки:

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

Посмотрите, близко ли это к тому, что вы хотите.

14 голосов
/ 16 октября 2008

Это 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>
5 голосов
/ 16 октября 2008

@ Дэвид показывает верный путь, Но у меня есть одно предложение к вашей архитектуре XAML. Если у вас нет DataBinding на кнопке, лучше поместить это в стиль 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>
0 голосов
/ 11 февраля 2010

Просто интересно, если мы используем вышеописанную технику, как мы можем определить, на каком объекте была нажата кнопка?

Чтобы ответить на вопрос Брайана, в обработчике нажатий кнопок вы можете пройти по визуальному дереву, чтобы найти элемент, содержащий кнопку:

        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 голосов
/ 22 декабря 2009

Одним из решений, позволяющих определить, по какому элементу щелкнули, является добавление следующего установщика событий

XAML

C # void ListBoxItem_MouseEnter (отправитель объекта, MouseEventArgs e) { _memberVar = (отправитель как ListBoxItem) .Content; }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...