none
WPF listview item mouse enter/over popup

    Question

  •  

    Hi,

     

    I have a listview that when you mouse over an item it changes the background color of that item. I am trying to make a popup that gives more information to the right of the listview when you mouse enter/over I added a handler to the listviewitem but the source is the listview so I cant get the data I need for that row. Any help would be awesome

     

     

    Code Block

    <ListView x:Name="ActivityMonitor"

    IsSynchronizedWithCurrentItem="True"

    Margin="9,41,15,129"

    FontFamily="./..\Fonts\#Myriad Pro"

    FontWeight="Bold"

    FontSize="11"

    BorderThickness="0,0,0,0"

    Loaded="ActivityMonitor_Loaded"

    ItemContainerStyle="{StaticResource myItemStyle}"

    ScrollViewer.HorizontalScrollBarVisibility="Disabled"

    ScrollViewer.VerticalScrollBarVisibility="Visible"

    VirtualizingStackPanel.IsVirtualizing="True"

    ScrollViewer.CanContentScroll="True"

    SelectionMode="Single"

    Foreground="#FF0246FA"

    ItemsPanel="{DynamicResource ActivityItemStyle}"

    ItemTemplate="{DynamicResource ActivityDataTemplate}">

    <ListView.View>

    <GridView x:Name="grd_Activity"

    ColumnHeaderContainerStyle="{DynamicResource OperationsGridViewColumnHeaderStyle}">

    <GridViewColumn Width="60" Header="Start">

    <GridViewColumn.CellTemplate>

    <DataTemplate>

    <TextBlock TextAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=A1}" TextWrapping="Wrap" Background="{x:Null}" Width="Auto" Height="20" FontFamily="Myriad Pro" Foreground="#FF000000"/>

    </< FONT>DataTemplate>

    </< FONT>GridViewColumn.CellTemplate>

    </< FONT>GridViewColumn>

    <GridViewColumn Width="60" Header="End" >

    <GridViewColumn.CellTemplate>

    <DataTemplate>

    <TextBlock TextAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=A2}" TextWrapping="Wrap" Background="{x:Null}" Width="Auto" Height="20" FontFamily="Myriad Pro" Foreground="#FF000000"/>

    </< FONT>DataTemplate>

    </< FONT>GridViewColumn.CellTemplate>

    </< FONT>GridViewColumn>

    <GridViewColumn Width="250" Header="Activity">

    <GridViewColumn.CellTemplate>

    <DataTemplate>

    <TextBlock TextAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=ActivityTypeName}" Padding="2,0,0,0" Width="Auto" TextWrapping="Wrap" Background="{x:Null}" Height="20" FontFamily="Myriad Pro" Foreground="#FF000000"/>

    </< FONT>DataTemplate>

    </< FONT>GridViewColumn.CellTemplate>

    </< FONT>GridViewColumn>

    <GridViewColumn Width="40" Header=" " >

    <GridViewColumn.CellTemplate>

    <DataTemplate>

    <Button x:Name="btnDeleteActivity" Visibility="Visible" Style="{DynamicResource OperationsDeleteButtonStyle}" BorderBrush="{x:Null}" Background="{x:Null}" Command="local:ActivityCommands.DeleteItem" CommandParameter="{Binding ActivityID}" >

    <Image Cursor="Hand" Source="/images/delete.png" Height="15" Width="15"/>

    </< FONT>Button>

    </< FONT>DataTemplate>

    </< FONT>GridViewColumn.CellTemplate>

    </< FONT>GridViewColumn>

    </< FONT>GridView>

    </< FONT>ListView.View>

    </< FONT>ListView>

     

     

     

    Code behind

     

    Code Block

    Private Sub ActivityMonitor_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)

    Dim ActivityList As System.Windows.Controls.ListView = CType(e.Source, System.Windows.Controls.ListView)

    ActivityList.SelectedIndex = Nothing

    ActivityList.AddHandler(ListViewItem.MouseEnterEvent, New RoutedEventHandler(AddressOf testit))

    End Sub

     

     

     

     

     

    Tuesday, January 15, 2008 6:38 PM

Answers

  • 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

    Thursday, January 17, 2008 3:59 AM

All replies

  • Have you tried looking at the OriginalSource property from the event arguments?

     

    Tuesday, January 15, 2008 6:59 PM
  • yes it is the "listview" for source and originalsource

    Tuesday, January 15, 2008 8:28 PM
  • Does anyone know if this can even be done?

    Wednesday, January 16, 2008 5:06 PM
  • OK what about If you click on the listview I want to get that row and find a control on it so I can change the visibility on it

     

    Can someone please help me? I have worked on this for 3 days and really need some kind of answer even a yes it can or no it cant will help me

    Wednesday, January 16, 2008 11:25 PM
  • 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

    Thursday, January 17, 2008 3:59 AM