C#学习 WinForm ListView实现拖动更换项的位置

WinForm本身ListView没有拖动更换选项位置的功能,有一些公开的库可以实现,但是我只是需要实现一个简单的功能,一般库文件都包含大量扩展和引用,导致一个只要简单功能的程序臃肿不堪,搜索到的资料也大都不全或者问题多多,所以就自己网罗了一些资料加上自己的一些理解来实现。

我实现该功能的过程如下

  1. 首先需要定义一个bool类型的变量表示我鼠标是否被按下,一个ListViewItem变量来存储我需要拖动的选项

private ListViewItem dragItem = null;
private bool isMouseDown = false;
  1. 拖动首先是肯定要左键按下鼠标,并且确保鼠标的位置是有选项的,而不是空的,所以,先绑定ListView的鼠标按下事件并判断鼠标所处位置是否有选项

private void listView1_MouseDown(object sender, MouseEventArgs e)
{
    // 判断鼠标按下的是否是左键
    if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
    {
        isMouseDown = true; //设置鼠标被按下
        dragItem = listView1.GetItemAt(e.X, e.Y); //根据鼠标坐标来获取需要移动的选项
        if (null != dragItem) //判断是否获取到选项
            Cursor = Cursors.HSplit; //如果获取到选项,设置鼠标样式
    }
}
  1. 为了防止鼠标在按下的过程中离开了窗体,但依然保持着按下的状态,需要绑定ListView的鼠标离开控件事件

 private void listView1_MouseLeave(object sender, EventArgs e)
{
        Cursor = Cursors.Default; // 重置鼠标样式
        isMouseDown = false; // 重置鼠标被按下状态
        dragItem = null; // 清空移动项
}
  1. 这个时候我开始移动并放开鼠标,来移动选项的位置,所以,我需要绑定ListView的鼠标的放下事件,我需要根据鼠标放开的位置,来获取我移动到哪个选项附近,并实现移动选项

private void listView1_MouseUp(object sender, MouseEventArgs e)
{
    // 判断鼠标是否被按下
    if (isMouseDown)
    {
        ListViewItem selItem = listView1.GetItemAt(e.X, e.Y); //根据鼠标坐标获取鼠标坐标下的选项
        // 判断鼠标位置是否有选项
        if (null == selItem)
        {
            // 如果没有选项,判断鼠标的Y轴位置,是否比选项中最后一个位置的选项要大
            // 如果是,则判断为鼠标位置在选项的最后一个位置
            // 如果不是,则判断为鼠标位置在选项的第一个位置
            // 保证放松鼠标后能正确移动选项
            if (e.Y > listView1.Items[listView1.Items.Count - 1].ListView.GetItemRect(0).Y)
                selItem = listView1.Items[listView1.Items.Count - 1];
            else
                selItem = listView1.Items[0];
        }
        
        // 判断需要移动的选项和鼠标放松位置的选项,是否是同一个选项
        if (dragItem.Index != selItem.Index)
        {
            listView1.Items.RemoveAt(dragItem.Index); // 移除ListView需要移动的选项
            int selH = selItem.ListView.GetItemRect(0).Size.Height; // 获取插入位置选项的矩形高度
            int selY = selItem.Position.Y + selH / 2; // 计算插入位置选项的中心位置
            int insert = 0; // 插入的位置
            // 判断鼠标位置是否在选项的下半部分
            // 如果是,则设定插入位置为选项的下一个位置
            // 如果不是,则设定插入位置为选项的当前位置
            if (e.Y > selY)
                insert = selItem.Index + 1;
            else
                insert = selItem.Index;
            
            listView1.Items.Insert(insert, dragItem); // 将需要移动的选项插入到指定位置
            dragItem = null; // 清空移动项
        }
        Cursor = Cursors.Default; // 重置鼠标样式
        isMouseDown = false; // 重置鼠标被按下状态
    }
}

以上,一个简易的,基于原生ListView中选项用鼠标拖动来改变位置的功能就实现了,不过功能比较简单和单一,没有动画效果,鼠标样式用的也是自带的,内容不复杂,就只贴个源码了,不放Demo了

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值