WPF 样式中的路径鼠标悬停触发器

问题描述 投票:0回答:1

我正在使用 DataTemplateSelector 根据枚举值选择 ListBox 项目的 DataTemplates。

public class MenuBarDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        DataTemplate template = null;

        var element = container as FrameworkElement;


        MenuItemModel model = (MenuItemModel)item;
        switch (model.ItemType)
        {
            case MenuItemType.Home:
                template = element.FindResource("MenuItemHome") as DataTemplate;
                break;

            case MenuItemType.Contacts:
                template = element.FindResource("MenuItemContacts") as DataTemplate;
                break;
        }

        return template;
    }
}

每个数据模板都有一个用于显示图标的 Path 和一个 TextBlock。它们之间的唯一区别是显示图像的路径根据枚举而不同。

ListBox 的 ItemContainerStyle 有一个触发器来处理 IsMouseOver 影响以更改前景色,当我将鼠标悬停在列表项上时,我可以看到前景色发生变化。顶部的路径样式也有类似的触发器,但只有当鼠标位于路径本身上方时才会改变颜色。 <UserControl.Resources> <cls:MenuBarDataTemplateSelector x:Key="menuTemplateSelecor"/> <Style x:Key="pathStyle" TargetType="{x:Type Path}"> <Setter Property="Height" Value="22" /> <Setter Property="Width" Value="22" /> <Setter Property="Fill" Value="Gray" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="Stretch" Value="Fill" /> <Setter Property="Margin" Value="5" /> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Fill" Value="SteelBlue"/> </Trigger> </Style.Triggers> </Style> <DataTemplate x:Key="MenuItemHome"> <StackPanel Orientation="Horizontal"> <Path x:Name="path" Data="{StaticResource homeIcon}" Style="{StaticResource pathStyle}"/> <TextBlock Text="{Binding MenuItemName}" FontSize="14" VerticalAlignment="Center"/> </StackPanel> </DataTemplate> <DataTemplate x:Key="MenuItemContacts"> <StackPanel Orientation="Horizontal"> <Path x:Name="path" Data="{StaticResource personIcon}" Style="{StaticResource pathStyle}"/> <TextBlock Text="{Binding MenuItemName}" FontSize="14" VerticalAlignment="Center"/> </StackPanel> </DataTemplate> </UserControl.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> </Grid.RowDefinitions> <ListBox Grid.Row="0" ItemsSource="{Binding MenuItems}" SelectedItem="{Binding SelectedMenuItem}" ItemTemplateSelector="{StaticResource menuTemplateSelecor}"> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="Margin" Value="3"/> <Setter Property="Height" Value="40"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="Background" Value="Tan"/> </Trigger> </Style.Triggers> </Style> </ListBox.ItemContainerStyle> </ListBox> </Grid>

这似乎是我在错误的地方有正确的代码。正确的做法是什么?

triggers listbox datatemplate
1个回答
0
投票
将 MouseOver 触发器更改为
    StackPanel
  1. :这将确保整个
    ListBoxItem
    响应悬停事件。
    使用隐藏代码处理 
  2. Path
  3. 悬停:使用
    MouseEnter
    MouseLeave
    事件更改悬停时
    Path
    的颜色。
    
    
  4. 在你的xml中:

<DataTemplate x:Key="MenuItemHome"> <StackPanel Orientation="Horizontal" MouseEnter="OnMouseEnter" MouseLeave="OnMouseLeave"> <Path x:Name="path" Data="{StaticResource homeIcon}" Fill="Gray" Height="22" Width="22" Margin="5"/> <TextBlock Text="{Binding MenuItemName}" FontSize="14"/> </StackPanel> </DataTemplate> <DataTemplate x:Key="MenuItemContacts"> <StackPanel Orientation="Horizontal" MouseEnter="OnMouseEnter" MouseLeave="OnMouseLeave"> <Path x:Name="path" Data="{StaticResource personIcon}" Fill="Gray" Height="22" Width="22" Margin="5"/> <TextBlock Text="{Binding MenuItemName}" FontSize="14"/> </StackPanel> </DataTemplate>

在你的 C# 中:

private void OnMouseEnter(object sender, MouseEventArgs e) { var stackPanel = sender as StackPanel; var path = stackPanel?.Children.OfType<Path>().FirstOrDefault(); if (path != null) path.Fill = Brushes.SteelBlue; } private void OnMouseLeave(object sender, MouseEventArgs e) { var stackPanel = sender as StackPanel; var path = stackPanel?.Children.OfType<Path>().FirstOrDefault(); if (path != null) path.Fill = Brushes.Gray; }

	
© www.soinside.com 2019 - 2024. All rights reserved.