WPF Listbox remove selection by clicking on a blan

2019-02-11 03:01发布

问题:

I have a wpf listbox with a custom item template which contains a rectangle. The each item in the listbox can be selected (only one at a time). I want to add a behavior in which when a user clicks on a place which isn't the item (for instance, a blank spot on the listbox, which is not an item), the selected item will become deselected.

Any ideas? Thanks.

For example with a simple listbox: item 1 item 2

The behavior that I'm looking for is when the user clicks on pixel 500 (which is a part of the listbox but not on an item), the currently selected item will be deselected.

回答1:

The simple solution is to data bind a property to the ListBox.SelectedItem property and set it to null whenever you want to clear the selection:

<ListBox ItemsSource="{Binding YourItems}" SelectedItem="{Binding SelectedItem}" 
    SelectionMode="Single" />

Then in code, you can just do this to clear the selection:

SelectedItem = null;

And when would you do that? You can attach a handler to the PreviewMouseLeftButtonDown event of the Window, or any other control in your UI. In the handler method, you could do a hit test to see what the item the user clicked on was:

HitTestResult hitTestResult = 
    VisualTreeHelper.HitTest(controlClickedOn, e.GetPosition(controlClickedOn));
Control controlUnderMouse = hitTestResult.VisualHit.GetParentOfType<Control>();

See the VisualTreeHelper.HitTest Method (Visual, Point) for more help with this part.

Then maybe something like this:

if (controlUnderMouse.GetType() != typeof(ListBoxItem)) SelectedItem = null;

Of course, there are many ways to do this, and you'll have to fill in the few blank spots that I left, but you should get the idea.


EDIT >>>

The generic GetParentOfType method is a custom Extension Method that is defined in a separate class named DependencyObjectExtensions:

public static class DependencyObjectExtensions
{
    public static T GetParentOfType<T>(this DependencyObject element) 
        where T : DependencyObject
    {
        Type type = typeof(T);
        if (element == null) return null;
        DependencyObject parent = VisualTreeHelper.GetParent(element);
        if (parent == null && ((FrameworkElement)element).Parent is DependencyObject) 
            parent = ((FrameworkElement)element).Parent;
        if (parent == null) return null;
        else if (parent.GetType() == type || parent.GetType().IsSubclassOf(type)) 
            return parent as T;
        return GetParentOfType<T>(parent);
    }

    ...
}


回答2:

For The each item in the listbox can be selected (only one at a time).

You can come up with one of followings

1- Disable the item after it is selected.

2- Maintain a list at backend to mark each index selectable or unselectable.



回答3:

To assure that only one item is selected put this in the listbox:

SelectionMode="Single"

then for the unselect when clicking somewhere, you can try to check this events

PreviewMouseLeftButtonUp
LostFocus()

Regards,



回答4:

Try ensuring your ListBox's background color is 'Transparent'



标签: c# wpf listbox