拖拽并选择ListBox中的项目?

3
如何在列表框中选择项目,如果从一个项目开始拖动到拖动结束?

这个默认情况下对你不起作用吗? - Cody Gray
1
你的意思是像Windows Explorer中的框选功能吗? - decyclone
如果我从第5个元素拖动到第10个元素,我想将这些项目标记为已选择。 - Kishore Kumar
你可以按住Shift键并选择。将listBox的SelectionMode设置为“Extended”,否则你必须通过获取每个项目的命中测试来手动选择项目。 - Prince Ashitaka
1个回答

5
我在msdn上看到了这种方法,但是我现在找不到它的链接了。无论如何,这个方法非常好用,唯一的问题是当同时拖动和滚动时,可能会错过一些项目。我创建了一个名为MultiSelectLibrary的自定义控件库,您可以像这样使用它:
添加对MultiSelectLibrary的引用,可以从这里下载(源代码在此)。
添加命名空间和SelectionMode="Extended"的MultiSelectListBox,它应该可以工作。
xmlns:mslb="clr-namespace:MultiSelectLibrary.MultiSelectListBox;assembly=MultiSelectLibrary"

<mslb:MultiSelectListBox SelectionMode="Extended" .../>

如果你更喜欢使用一些背后的代码,你可以这样做(与库执行相同的操作)。
<ListBox SelectionMode="Extended"
         ...>
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <EventSetter Event="PreviewMouseUp" Handler="ListBoxItem_PreviewMouseUp"/>
            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBoxItem_PreviewMouseLeftButtonDown"/>
            <EventSetter Event="PreviewMouseMove" Handler="ListBoxItem_PreviewMouseMove"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

在代码后端中,
private object _anchor, _lead;
private Boolean _inMouseSelectionMode;
private List<object> _selectedItems = new List<object>();

private void ListBoxItem_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    _selectedItems.Clear();
    _inMouseSelectionMode = false;
    _anchor = null;
    _lead = null;
}

private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
        return;

    _anchor = sender;
    _inMouseSelectionMode = true;
    _selectedItems.Clear();
    _selectedItems.Add(sender);
}
private void ListBoxItem_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (!_inMouseSelectionMode)
        return;

    if (_lead != sender)
    {
        var last = _lead;
        _lead = sender;

        if (_selectedItems.Contains(_lead))
            _selectedItems.Remove(last);
        else
            _selectedItems.Add(_lead);
    }

    foreach (var item in _selectedItems)
        ((ListBoxItem)item).IsSelected = true;
}

感谢分享,Meleak。我会深入研究代码,因为我想要类似的东西。 - Dick Lampard
我如何在所选内容上绘制一个边框? - Shimmy Weitzhandler
@Anders Rune Jensen:你说得对,不确定发生了什么。我会调查一下! - Fredrik Hedblad
@@Anders Rune Jensen:目前似乎遇到了MediaFire的问题...我重新上传并更新了链接,让我们看看是否会有所帮助。 - Fredrik Hedblad
这里有一个问题。如果你拖动得太快,选择区域中会出现空隙! - James L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接