Ask a questionAsk a question
 

AnswerListBox (Double)Click Event

  • Tuesday, July 17, 2007 4:04 PMtwisterjosh Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hello, I've been having some trouble here for the past hour or two and can't figure out a solution...

     

    I have a ListBox defined in my XAML page, and I've also created an ItemsTemplate in the page that is populated with a datatable that I have.

     

    I wanted to see when an item was double clicked, so I created an event handler.

     

    The problem is this: the event is raised whether or not an actual item is clicked.  This is to be expected since it's an event for the whole ListBox.

     

    My question is how does one check to see whether or not there was actually an item clicked?

    e.Source returns the ListBox instance.  e.OriginalSource returns the actual TextBlock that was defined in the ItemsTemplate, if it was clicked, or it may return the Border defined in the ItemsTemplate, or it may return the Border for ListBox, or the Border for a scroll button in the ListBox, etc...

     

    So how can I check if it's an item? 

    I wondered if FrameworkElement.IsAnscestorOf() or IsDescendantOf() would help me here but couldn't figure out how to use them.

    I tried things like ((UIElement)e.OriginalSource).IsDescendantOf( - couldn't figure out what to put here - )

     

    I feel like I'm close... does anyone have any ideas?  Thanks,

     

    josh

Answers

  • Tuesday, July 17, 2007 6:47 PMlee dModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    try this (list1 is listbox)

    Code Snippet

    void lbi_MouseDoubleClick(object sender, MouseButtonEventArgs e)

    {

    object item = null;

    item = GetElementFromPoint(list1,e.GetPosition(list1));

    if (item == null)

    MessageBox.Show("did not click on item");

    else

    MessageBox.Show(item.ToString());

    }

    private object GetElementFromPoint(ListBox box, Point point)

    {

    UIElement element = (UIElement)box.InputHitTest(point);

    while (true)

    {

    if (element == box)

    {

    return null;

    }

    object item = box.ItemContainerGenerator.ItemFromContainer(element);

    bool itemFound = !(item.Equals(DependencyProperty.UnsetValue));

    if (itemFound)

    {

    return item;

    }

    element = (UIElement)VisualTreeHelper.GetParent(element);

    }

    }

     

All Replies

  • Tuesday, July 17, 2007 4:28 PMlee dModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    you can handle listboxItem's Mousedoubleclick event

    <ListBox Name="list1" ListBoxItem.MouseDoubleClick="lbi_MouseDoubleClick"></ListBox>

    void lbi_MouseDoubleClick(object sender, MouseButtonEventArgs e)

    {

    }

  • Tuesday, July 17, 2007 5:01 PMtwisterjosh Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    A couple of weird things when I tried that:

     

    1) Intellisense does not show ListBoxItem.MouseDoubleClick - when you type ListBoxItem. it only shows two events, "Selected" and "UnSelected".  However, it will still compile with ListBoxItem.MouseDoubleClick

     

    2) Same behavior even with ListBoxItem.MouseDoubleClick - the event is raised when you double click outside of an item, such as the scroll bar.

     

    Thanks, but still no luck.

  • Tuesday, July 17, 2007 5:12 PMlee dModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    1. you can ignore

    2. may be check the selecteditem[] of the listbox

  • Tuesday, July 17, 2007 5:43 PMtwisterjosh Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    2. No, that doesn't work.  Here's why:

    The user may have the first item selected, but want to scroll down to see the rest of the items, so the user quickly presses the down arrow button of the scrollbar - which is then interpreted as a "DoubleClick" event and is then raised.

    I could just disable it altogether.

    But I would rather it:

    1. ) Raise (as it should) the DoubleClick event.  If there was a DoubleClick on an item, do . . . otherwise, do nothing.

     

    Unfortunately I cannot tell whether an item was double clicked or the button of the scroll bar.  It's always raised, even with ListBoxItem.MouseDoubleClick.

     

    Thanks for your help,

    josh

  • Tuesday, July 17, 2007 6:39 PMKayakyakr Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    does your list box item get passed through as the sender of the double click event? if you can differentiate between senders using if(sender is ListBoxItem), then you can handle that case and ignore the rest.

    Otherwise, are your listviewitems templated? if so, you could set up the doubleclick even for the largest panel under the control template or even individual items therein.
  • Tuesday, July 17, 2007 6:47 PMlee dModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    try this (list1 is listbox)

    Code Snippet

    void lbi_MouseDoubleClick(object sender, MouseButtonEventArgs e)

    {

    object item = null;

    item = GetElementFromPoint(list1,e.GetPosition(list1));

    if (item == null)

    MessageBox.Show("did not click on item");

    else

    MessageBox.Show(item.ToString());

    }

    private object GetElementFromPoint(ListBox box, Point point)

    {

    UIElement element = (UIElement)box.InputHitTest(point);

    while (true)

    {

    if (element == box)

    {

    return null;

    }

    object item = box.ItemContainerGenerator.ItemFromContainer(element);

    bool itemFound = !(item.Equals(DependencyProperty.UnsetValue));

    if (itemFound)

    {

    return item;

    }

    element = (UIElement)VisualTreeHelper.GetParent(element);

    }

    }

     

  • Saturday, November 07, 2009 6:56 PMInfax01 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I understand the question has been properly answered. I stumbled upon this thread, however, and it helped me a lot. In the end, though, I used a very simple line inside lbi_MouseDoubleClick: if (listBox1.SelectedItem == null) return;

    Any reason this should not be a proper solution?