Question

I'm trying to determine if a user has right clicked on an existing listbox entry or the empty portion, to enable or disable context menuitems.

In WinForms (for a datagridview) i was able to do

var result = DGVTasks.HitTest(e.X, e.Y);
bool existingRowSelected = result .Type == DataGridViewHitTestType.Cell;

in a datagridview. Now in WPF i've tried

Point pt = e.GetPosition((UIElement)LBXWorkflow);
HitTestResult result = VisualTreeHelper.HitTest(LBXWorkflow, pt);

Result.VisualHit shows textbox if i click on existing text, but border if i click on blank space before or after the text on an existing line (which would return a false negative if i use it to determine if an entry was right clicked).

Any ideas, for both Listbox and DataGrid?

Was it helpful?

Solution

pls check the code below; it's an MouseRightButtonUp event handler for a listbox control which prints the item name under the mouse pointer if it's there

private void listBox1_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
    object item = GetElementFromPoint(listBox1, e.GetPosition(listBox1));
    if (item!=null)
        Console.WriteLine(item);
    else
        Console.WriteLine("no item found");
}

private object GetElementFromPoint(ItemsControl itemsControl, Point point)
{
    // you can use either VisualTreeHelper.HitTest or itemsControl.InputHitTest method here; both of them would work
    //UIElement element = VisualTreeHelper.HitTest(itemsControl, point).VisualHit as UIElement;
    UIElement element = itemsControl.InputHitTest(point) as UIElement;
    while (element!=null)
    {
        if (element == itemsControl)
            return null;
        object item = itemsControl.ItemContainerGenerator.ItemFromContainer(element);
        if (!item.Equals(DependencyProperty.UnsetValue))
            return item;
        element = (UIElement)VisualTreeHelper.GetParent(element);
    }
    return null;
}

this should be working fine for the listbox regards

OTHER TIPS

If memory serves, the RightClick event bubbles from the element that is actually clicked up to the root element of the page. If you attach the event handler to the items themselves instead of the ListBox, you will be able to handle the click on the individual items and prevent it from bubbling any further. If the event reaches the ListBox handler, the click occurred on a blank region of the control.

Alternatively you can try checking the OriginalSource property of the event args, but I have had some trouble with that in the past.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top