none
How to detect mouse click on ListBox ?

    Question

  • I used SelectionChanged event, but it didn't work when I clicked the same item.

    Then tried to use MouseLeftButtonDown event, but it didn't work at all.

    Saturday, May 09, 2009 10:12 AM

Answers

  • It's quite a pain...this is the simplest way I could find and it required replacing the ItemTemplate.

            <ListBox>
               
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid Loaded="Grid_Loaded" Background="Orange">
                            <TextBlock Text="{Binding}"/> // replace this with the way you want to display your content
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
               
                <ListBox.Items>
                    <sys:String>one</sys:String>
                    <sys:String>two</sys:String>
                    <sys:String>three</sys:String>
                </ListBox.Items>
            </ListBox>
            

            private void Grid_Loaded(object sender, RoutedEventArgs e)
            {
                // add a handler to the mouse event on the grid...
                // this will run once for each item in the list box so you'll add the same handler to every item
                Grid g = sender as Grid;
                g.MouseLeftButtonDown += Grid_MouseLeftButtonDown;

                // this code I borrowed from another post to stretch the item the full width of the listbox
                // the post is here http://silverlight.net/forums/p/18918/70469.aspx
                FrameworkElement t = sender as FrameworkElement;
                ContentPresenter p = VisualTreeHelper.GetParent(t) as ContentPresenter;
                p.HorizontalAlignment = HorizontalAlignment.Stretch;   
            }

            private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Grid g = sender as Grid;
                TextBlock tb = g.Children[0] as TextBlock;
                // ...
            }

    Saturday, May 09, 2009 2:22 PM

All replies

  • Hi,

    The selection changed event only fires when the selection changes, so if you click the same item it doesn't fire.

    In WPF the MouseLeftButtonDown event only fires in areas that wouldn't affect the functionality of the control (i.e. whitespace area between the last item and the horizontal scrollbar.  In Silverlight it doesn't seem to fire at all.

    You can use the MouseLeftButtonUp event if you really need to run some code if the user clicks the same item.  What are you trying to do that can't be handled by the SelectionChanged event?

    Saturday, May 09, 2009 2:11 PM
  • It's quite a pain...this is the simplest way I could find and it required replacing the ItemTemplate.

            <ListBox>
               
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid Loaded="Grid_Loaded" Background="Orange">
                            <TextBlock Text="{Binding}"/> // replace this with the way you want to display your content
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
               
                <ListBox.Items>
                    <sys:String>one</sys:String>
                    <sys:String>two</sys:String>
                    <sys:String>three</sys:String>
                </ListBox.Items>
            </ListBox>
            

            private void Grid_Loaded(object sender, RoutedEventArgs e)
            {
                // add a handler to the mouse event on the grid...
                // this will run once for each item in the list box so you'll add the same handler to every item
                Grid g = sender as Grid;
                g.MouseLeftButtonDown += Grid_MouseLeftButtonDown;

                // this code I borrowed from another post to stretch the item the full width of the listbox
                // the post is here http://silverlight.net/forums/p/18918/70469.aspx
                FrameworkElement t = sender as FrameworkElement;
                ContentPresenter p = VisualTreeHelper.GetParent(t) as ContentPresenter;
                p.HorizontalAlignment = HorizontalAlignment.Stretch;   
            }

            private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Grid g = sender as Grid;
                TextBlock tb = g.Children[0] as TextBlock;
                // ...
            }

    Saturday, May 09, 2009 2:22 PM
  • What does your listitem template look like: Did you put the leftmousebuttondown event on an element within your listboxitem?
    Saturday, May 09, 2009 2:32 PM
  •  

     Try this ListBox Template for the sake of simplicity I used only a TextBlock in this DataTemplate.
    1    <ListBox x:Name="lstCounts">
    2                <ListBox.ItemTemplate>
    3                    <DataTemplate>
    4                        <Border BorderBrush="Brown" CornerRadius="3" BorderThickness="2">
    5                            <TextBlock MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" Text="{Binding }"/>
    6                        </Border>
    7                    </DataTemplate>
    8    </ListBox.ItemTemplate>
    
     in Code Behind File I just populated a list of Numeric strings for ItemSource.
     
    1     List<string> s;
    2    s = new List<string>();
    3    for (int i = 0; i < 20; i++)
    4    {
    5       s.Add(i.ToString());
    6    }
    7    lstCounts.ItemsSource = s;
    
       
    1    private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    2            {
    3                TextBlock txt = sender as TextBlock;            
    4                MessageBox.Show(txt.Text);
    5            }
    
     
     
     

    Saturday, May 09, 2009 4:09 PM
  • > clint1222:
    > What are you trying to do that can't be handled by the SelectionChanged event?
    I'm trying to open a new page in browser on click on any item. So user could close new page and wanted to open it again. If there is one item only in the list user has no chance to open it twice at all.


    > SharpGIS:
    > Did you put the leftmousebuttondown event on an element within your listboxitem?
    I think so, but I didn't check it well.


    > MarkTap
    Your way works well.


    > inampaki
    Your way has trouble with stretch. If I could set stretch in XAML it might work I think. But I don't know how to do it, so I used MarkTap's way.

    Sunday, May 10, 2009 4:24 AM
  • > MarkTap

    Now I've got another trouble: Grid_MouseLeftButtonDown() is called when ListBox.SelectedItem is not set yet. So I can't use SelectedItem to know which item was selected. I've fixed it with an additional variable and checking (null == listBox.SelectedItem) but it doesn't seem to be sexy :)

    Sunday, May 10, 2009 4:53 AM
  • Could you use 'up' instead?

          Grid_Loaded(object sender, RoutedEventArgs e)
          {
                ...
                Grid g = sender as Grid;

                g.MouseLeftButtonUp   += Up;
            }

            void Up(object sender, MouseButtonEventArgs e)
            {
                Grid g = sender as Grid;

                TextBlock tb = g.Children[0] as TextBlock;

                int    index = listbox.SelectedIndex;
                object item  = listbox.SelectedItem;
            }
        }
    }
     

    Sunday, May 10, 2009 9:07 AM
  •  Thanks, my last question was pretty foolish.

    Besides that I have a little other question: I was using background="red" to see the stretch of the container, but since I've removed background from container mouse events are called for container's content only(image, text, etc). Now I'm using background="transparent" to fix it. But may be there is any other way without background option?

    Sunday, May 10, 2009 11:25 AM
  • Seems like an awful lot of work to get to the MouseLeftButtonUp event.  Why not just handle the MouseLeftButtonUp event on the listbox?

    If you want to open a new browser by clicking on an item in your listbox, why not make the list item a hyperlink button?  You could define it in the datatemplate.  That way you wouldn't have to worry about any listbox click events at all.

    Sunday, May 10, 2009 4:33 PM
  • Dear Grey Matter

    can u Plz send some ur xaml code so that it could be more clear what u want to do.

    Sunday, May 10, 2009 11:44 PM
  •  Thanks a lot for help. I've made HyperlinkButton. It works well.

    Monday, May 11, 2009 5:06 AM
  • In Silverlight 3 you can do this:

     lstList.AddHandler(FrameworkElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(lstList_MouseLeftButtonDown), true);
     To trap all events, even ones that have been handled. Don't know offhand if it works in earlier versions, though.
    Monday, September 07, 2009 10:05 AM
  • I was puzzling over this and then it dawned on me.  You really want to detect the mouse click on the ITEMS of the ListBox.

    I'm adding items to a listbox programmatically and I do this:

    ListBoxItem item = new ListBoxItem();
                    item.Tag = m[0];
                    item.Content = m[1];
                    item.MouseLeftButtonUp += new MouseButtonEventHandler(item_MouseLeftButtonUp);

    The event looks like this:

     void item_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                ListBoxItem item = sender as ListBoxItem;

    ... do something with the item ...

    }

    Thursday, September 24, 2009 7:29 PM
  • Thanks man!!

    But my question is, how did you figure this out?

    Saturday, April 28, 2012 7:23 AM