开发者

WPF: ListBox unselecting

开发者 https://www.devze.com 2022-12-18 02:13 出处:网络
When the user clicks on a item in my singl开发者_高级运维e-select ListBox, the item is selected.
  1. When the user clicks on a item in my singl开发者_高级运维e-select ListBox, the item is selected.
  2. When the user clicks on a item the second time, the item is not unselected unless they are holding the control key.

What is the recommended way to change #2 to not require the control key?


Make sure the selection mode is Multiple. By selecting multiple:

you can use the mouse to select and deselect any item(s) you want with just a mouseclick. But if you want only 1 selected item at a time, you'll have to deselect the other items in code in the SelectionChanged event.

Source

Private Sub MainList_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
    If e.AddedItems.Count > 0 Then
        Dim valid = e.AddedItems(0)
        For Each item In New ArrayList(MainList.SelectedItems)
            If item IsNot valid Then MainList.SelectedItems.Remove(item)
        Next
    End If
End Sub


Sorry by resurrecting this topic...

But the accepted answer didn't cover well all my needs, so I improved it a little. I have dozens of ListBox and it all needs this unselection on click behavior.

Because of it, I created a custom control, overriding the SelectionModeProperty (setting its default value to SelectionMode.Multiple) and also tracking the SelectionChanged event automatically. Lets show the code:

public class UnselectableListBox : ListBox
{
    public UnselectableListBox() : base()
    {
        SelectionChanged += new SelectionChangedEventHandler((sender, e) =>
        {
            if (e.AddedItems.Count > 0)
            {
                var last = e.AddedItems[0];
                foreach (var item in new ArrayList(SelectedItems))
                    if (item != last) SelectedItems.Remove(item);
            }
        });
    }

    static UnselectableListBox()
    {
        SelectionModeProperty.OverrideMetadata(typeof(UnselectableListBox),
            new FrameworkPropertyMetadata(SelectionMode.Multiple));
    }
}

Then, I only need to replace my XAML with:

<local:UnselectableListBox ... />

No more need to code SelectionChanged for each ListBox on each Window.


Not trying to beat a dead horse but I had this same problem and couldn't use any of the methods used in answers here... hope someone can benefit from my answer:

I have selection mode set to single. I have double click events which makes multiple select mode not so desirable and hard to get double clicks to work.

SelectionChanged only fires if the selected item is different. Easy way: Use PreviewLeftMouseDownClick and PreviewLeftMouseUpClick. Store MyListBox.SelectedIndex into an object variable in the preview mouse down event.

In the preview mouse up event compare that variable from the down event to MyListBox.SelectedIndex and if they are the same set MyListBox.SelectedIndex = -1.

The item will be deselected if it is the same because the changing of index numbers happens after the preview down and before the preview up!


Using the Control key is the recommended way to do this. It's a UI gesture which is consistent across all of Windows. You should be wary of changing this behavior.


I found that Ctrl-CLick is a non-intuitive way to unselect a listbox item and fixed the behavior by simply adding a MouseDown and KeyDown event in my XAML (.net Core 5) and creating event handlers like this:

private void lboxScanList_MouseDown(object sender, MouseButtonEventArgs e) {
    // user clicked on a non-item - deselect all
    lboxScanList.UnselectAll();
}

private void lboxScanList_KeyDown(object sender, KeyEventArgs e) {
    if (e.Key == Key.Escape) {
        lboxScanList.UnselectAll();
    }
}

This gives you unselection with Esc or a mouse click off of any item but on the listbox which I feel is much more intuitive.

0

精彩评论

暂无评论...
验证码 换一张
取 消