This is because the routing strategy of the Loaded event is Direct, which means that the routed event does not route though an element tree. This is why we are unable to catch the Loaded event from the ListViewItems. You can refer to the doucment of Loaded event to get more information about this. The following example shows how to do this. Code Block namespace ForumProjects { public partial class MainWindow : Window { public MainWindow() { this.Persons = new List<Person>() { new Person(){ID=1,Name="AAA",Comment="Comment AAA"}, new Person(){ID=2,Name="BBB",Comment="Comment BBB"}, new Person(){ID=3,Name="CCC",Comment="Comment CCC"}, new Person(){ID=4,Name="DDD",Comment="Comment DDD"}, }; InitializeComponent(); } public List<Person> Persons { get; private set; } } public class Person { public int ID { get; set; } public string Name { get; set; } public string Comment { get; set; } } public class PersonListView : ListView { protected override DependencyObject GetContainerForItemOverride() { return new PersonListViewItem(); } protected override bool IsItemItsOwnContainerOverride(object item) { return item is PersonListViewItem; } } public class PersonListViewItem : ListViewItem { public static readonly DependencyProperty PopupTextProperty = DependencyProperty.Register("PopupText", typeof(string), typeof(PersonListViewItem), new FrameworkPropertyMetadata(PopupTextChanged)); public static readonly DependencyProperty IsPopupOpenProperty = DependencyProperty.Register("IsPopupOpen", typeof(bool), typeof(PersonListViewItem), new FrameworkPropertyMetadata(IsPopupOpenChanged)); private Popup popup; private TextBlock textBlock; public PersonListViewItem() { this.textBlock = new TextBlock(); Grid grid = new Grid() { Background = Brushes.White }; grid.Children.Add(this.textBlock); this.popup = new Popup() { Child = grid, PlacementTarget = this, Placement = PlacementMode.Right }; } public string PopupText { get { return (string)GetValue(PopupTextProperty); } set { SetValue(PopupTextProperty, value); } } public bool IsPopupOpen { get { return (bool)GetValue(IsPopupOpenProperty); } set { SetValue(IsPopupOpenProperty, value); } } private static void IsPopupOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { PersonListViewItem item = d as PersonListViewItem; if (item != null) { item.popup.IsOpen = (bool)e.NewValue; } } private static void PopupTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { PersonListViewItem item = d as PersonListViewItem; if (item != null) { item.textBlock.Text = (string)e.NewValue; } } } } <Window x:Class="ForumProjects.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ForumProjects" x:Name="Window" Title="MainWindow" Height="700" Width="800"> <StackPanel> <local:PersonListView ItemsSource="{Binding ElementName=Window, Path=Persons}"> <local:PersonListView.View> <GridView> <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}"/> <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/> </GridView> </local:PersonListView.View> <local:PersonListView.ItemContainerStyle> <Style TargetType="local:PersonListViewItem"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="IsPopupOpen" Value="True"/> </Trigger> </Style.Triggers> <Setter Property="PopupText" Value="{Binding Comment}"/> </Style> </local:PersonListView.ItemContainerStyle> </local:PersonListView> </StackPanel> </Window> Best Regards, Wei Zhou
原文:WPF listview item mouse enter/over popup