You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3/UWP中是否有类似ListView InsertionMark的功能?

WinUI3/UWP中实现类似ListView InsertionMark的拖放插入功能

WinUI3/UWP没有内置与WinForms的ListView.InsertionMark完全匹配的功能,但可以通过拖放事件结合自定义逻辑,实现获取拖放插入位置索引并显示插入标记的效果。

实现步骤

1. 配置ListView的拖放属性

给目标ListView开启拖放支持:

<ListView x:Name="TargetListView" AllowDrop="True"
          DragEnter="TargetListView_DragEnter"
          DragOver="TargetListView_DragOver"
          Drop="TargetListView_Drop">
    <!-- 你的ItemTemplate和数据源配置 -->
</ListView>

2. 计算拖放插入位置索引

在DragOver事件中,通过鼠标位置判断插入的目标索引:

private int _insertionIndex = -1;

private void TargetListView_DragOver(object sender, DragEventArgs e)
{
    var listView = sender as ListView;
    if (listView == null) return;

    // 获取鼠标在ListView内的位置
    Point position = e.GetPosition(listView);
    // 找到鼠标下方的列表项容器
    var itemContainer = listView.ContainerFromPosition(position) as ListViewItem;

    if (itemContainer != null)
    {
        // 获取该项对应的数据源索引
        int itemIndex = listView.IndexFromContainer(itemContainer);
        // 获取容器的边界
        GeneralTransform transform = itemContainer.TransformToVisual(listView);
        Rect itemRect = transform.TransformBounds(new Rect(0, 0, itemContainer.ActualWidth, itemContainer.ActualHeight));
        
        // 判断鼠标位置是在项的上半部分还是下半部分,决定插入位置
        if (position.Y < itemRect.Top + itemRect.Height / 2)
        {
            _insertionIndex = itemIndex;
        }
        else
        {
            _insertionIndex = itemIndex + 1;
        }
    }
    else
    {
        // 鼠标不在任何项上,插入到列表末尾
        _insertionIndex = listView.Items.Count;
    }

    // 更新插入标记的显示位置
    UpdateInsertionMarkerPosition(_insertionIndex);
}

3. 自定义插入标记UI

在ListView的布局中添加用于显示插入线的元素(如Rectangle),通过UpdateInsertionMarkerPosition方法调整其位置:

private void UpdateInsertionMarkerPosition(int index)
{
    if (index < 0 || index > TargetListView.Items.Count)
    {
        InsertionLine.Visibility = Visibility.Collapsed;
        return;
    }

    InsertionLine.Visibility = Visibility.Visible;
    ListViewItem targetItem = null;

    if (index < TargetListView.Items.Count)
    {
        targetItem = TargetListView.ContainerFromIndex(index) as ListViewItem;
    }
    else
    {
        // 插入到末尾时,基于最后一项的位置计算
        targetItem = TargetListView.ContainerFromIndex(TargetListView.Items.Count - 1) as ListViewItem;
    }

    if (targetItem != null)
    {
        GeneralTransform transform = targetItem.TransformToVisual(TargetListView);
        Rect itemRect = transform.TransformBounds(new Rect(0, 0, targetItem.ActualWidth, targetItem.ActualHeight));
        
        // 调整插入线的位置(示例为垂直插入线,可根据布局修改为水平)
        InsertionLine.Margin = new Thickness(index == 0 ? 0 : itemRect.Left, itemRect.Top, 0, itemRect.Height);
        InsertionLine.Width = 2;
        InsertionLine.Fill = new SolidColorBrush(Colors.Blue);
    }
}

4. 完成拖放插入操作

在Drop事件中,使用计算好的_insertionIndex完成数据插入:

private async void TargetListView_Drop(object sender, DragEventArgs e)
{
    if (e.DataView.Contains(StandardDataFormats.Text)) // 根据实际拖放的数据类型调整
    {
        string draggedItem = await e.DataView.GetTextAsync();
        var itemsSource = TargetListView.ItemsSource as ObservableCollection<string>;
        if (itemsSource != null && _insertionIndex >= 0 && _insertionIndex <= itemsSource.Count)
        {
            itemsSource.Insert(_insertionIndex, draggedItem);
        }
    }
    // 隐藏插入标记
    InsertionLine.Visibility = Visibility.Collapsed;
}

内容的提问来源于stack exchange,提问作者yonutix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 06:23:14