我用C#做的纸牌游戏,窗体上方放的菜单,然后放的一个Panel,用作游戏操作区,然后最下面放的几个label,用来显示分数之类的。我的纸牌全是继承的label,所有纸牌的MouseMove事件都是关联的同一个Cards_Move方法,之前没捕获鼠标,拖动纸牌时鼠标都不能拖动快了,不然纸牌会卡住不动。现在在移动方法中添加了SelectCard.Capture=true,纸牌就能很流畅的拖动了,即使拖动时鼠标移出了Panel的区域,但只要没移出窗体,也能够触发纸牌的移动事件,但只要鼠标一移出窗体,就不能触发纸牌的鼠标事件了。有什么办法可以解决?我是用的VS2008。

解决方案 »

  1.   

    本身移动事件就是在Form内啊,如果在From外,需要别的技术
    我觉得啼的逻辑是不是有问题啊,本来就该限制在Form内,才能拖动,不然你准备整到哪里啊
      

  2.   

    你玩过XP或者VISTA里自带的那个纸牌游戏吗?我就是仿那个做的,游戏里纸牌都可以随便拖动的,拖动的时候鼠标也能够拖出窗体外。
      

  3.   

    你一直拖着,应该没有问题,到form边缘把纸牌隐藏就可以,主要是跟踪鼠标的位置(坐标),当鼠标拖动,回到From范围之类,重新计算纸牌位置
      

  4.   


     if (selectedCard != null)
                    {
                        if (selectedCard.Capture == false)
                        {
                            selectedCard.Capture = true;
                        }
                     //实现拖动效果
                        mousePos1 = MousePosition;    //获取鼠标在屏幕上的坐标
                        mousePos2 = this.PointToScreen(PanelFace.Location);   //获取窗体面板相对于屏幕的坐标
                        mousePos = new Point(mousePos1.X - mousePos2.X, mousePos1.Y - mousePos2.Y);   //前两坐标之差即为鼠标在窗体中相对于窗体的坐标
                       mousePos.Offset(-mouseOffset.X, -mouseOffset.Y);
                        for (int i = 0; i < cardsmove_list.Count; i++)
                        {
                            _cardmove = (CardsItems)cardsmove_list[i];
                            _cardmove.Location = new Point(mousePos.X, mousePos.Y + i * fuzhu_jiange);
                        
                        }
                    PanelFace.Update();
                        
                    }
      

  5.   

    单纯的拖动自己绘制的控件需要进行处理,因为你每次鼠标动了一下,控件都需要全部重新绘制,而且鼠标超出了绘制区域控件就会无法绘制。
    楼主不妨可以考虑下toolstripdropdown这个控件,用它可以实现类似QQ的好友可以任意拖动,QQ的表情选择框之类的都可以用它实现,因为这个控件本身就可以在超出窗体之外绘制,而且他相当于是一个载体,只要将你要显示的纸牌放进去就可以了。
      

  6.   

    lZ 你这个东西做完后速度如何阿?我也正在研究纸牌游戏方面的东西,不过思路和你不太一样,偶是使用 cards.dll 来实现的,但是感觉很难操控。
      

  7.   

    CSDN上有控件拖动的源码下载 去找找
      

  8.   

    不是控件本身的问题,我重新弄了个程序,一样的放个panel,里面放了个label和picturebox,都添加了mousedown mousemove和mouseup事件,移动方法还是我自己原来的。结果两个控件都能顺利拖动,而且鼠标也能移动到窗体外,一样能触发鼠标事件。这下更糊涂了。等待解答!
      

  9.   

    Private Declare Function SetCapture Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function ReleaseCapture Lib "user32" () As Long
        <DllImport("user32.dll", EntryPoint:="SendMessage")> _
    Public Function SendMessage(ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    Const SC_MOVE = &HF012sub Cards_Move(Sender as object)
    SetCapture(Sender.Handler)
    SendMessage(Sender.Hander,SC_MOVE,0,0)
    ReleaseCapture
    end sub
      

  10.   

    效果: 拖动时鼠标可拖动区域被限制在Label的父容器内.
      

  11.   

    我的纸牌全是继承的label ,为什么不使用 pictureBox 装载图片呢?我这有扑克图片,要不:
    http://download.csdn.net/source/1442002另外,拖放控件,以下代码可供参考:        private bool isMove = false;
            private Point M;
            private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
            {
                isMove = true;
                M = new Point(e.X, e.Y);
            }
            private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
            {
                isMove = false;
            }
            private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
            {
                //this.Text = e.X + "   " + e.Y;
                if (isMove)
                {
                    pictureBox1.Location = new Point(pictureBox1.Location.X + e.X - M.X, pictureBox1.Location.Y + e.Y - M.Y);            }
            }
      

  12.   

    我把代码恢复到以前的样子了(就多了mouseenter和mouseleave事件,进入时就让纸牌的borderstyle设成fixedsingle,离开时设成BorderStyle.None),只是在移动时设置了纸牌的captrue=true,很不喜欢这样设,因为纸牌重叠时(移动到一起,比如:红8黑7),鼠标进入8,8变成有fixedsingle,再慢慢移动到7时,7也fixedsingle但8的边框没消失,也就没出发它的mouseleave事件.这种有点奇怪,我可以拖动纸牌,即使鼠标移动到窗体外。但如果下一次拖动这次一样的牌的话,鼠标移动出窗体纸牌就不走了;如果是拖动不同的牌,又很顺利,没问题;还有如果两次都拖动同一张,只要拖动一下后,点击一下panel,再去拖动这张纸牌,又没问题。想不通怎么回事哦。
    还请大家多指教!
      

  13.   

    panel的click事件里就只写了 if (selectedCard != null)
                    {
                        cardsmove_list.Clear();
                        selectedCard.BorderStyle = BorderStyle.None;
                        selectedCard = null;
                    }
      

  14.   

    我最终还是让拖动的时候让鼠标不能移出窗体:  Cursor.Clip = this.Bounds;初始化时记录鼠标的默认移动范围:        Rectangle cur = Cursor.Clip;
    当鼠标按下时限制鼠标:  Cursor.Clip = this.Bounds;
    mouseup后撤销限制,恢复鼠标移动:        Cursor.Clip = cur;再次感谢你们的回复!结帖!