找回密码
 立即注册

QQ登录

只需一步,快速开始

credream

中级会员

110

主题

296

帖子

828

积分

中级会员

积分
828

活字格认证

credream
中级会员   /  发表于:2015-11-23 10:07  /   查看:6488  /  回复:3
现有两本程序,其中一本在MultiRow的Header部用鼠标单击的时候,会先触发CellClick事件,然后才会发生光标迁移。

另外一本,在MultiRow的Header部用鼠标单击的时候,会把光标迁移到点击列的第一行的单元格(RowIndex=0),然后才会触发CellClick事件。

请问这个迁移和CellClick事件的触发时机是如何控制的?我们现在想要实现第一种效果,如何可以做到?

下面的运行时的堆栈信息可以参考下,但是为什么一个要呼出MouseDown,一个呼出MouseUp我们分析不了。能不能给讲解下。


参考资料:

第一种动作的堆栈信息:
        CGHT003A.exe!CGHT003A.HT003A01.mlsScanOrder_CellClick(Object sender, GrapeCity.Win.MultiRow.CellEventArgs e) 行 1115        Basic
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Cell.OnMouseClick(GrapeCity.Win.MultiRow.CellMouseEventArgs e)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.j.OnMouseClick(System.Windows.Forms.MouseEventArgs e)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.bj.GrapeCity.Framework.Views.IInputable.MouseClick(System.Windows.Forms.MouseEventArgs arguments, GrapeCity.Framework.Views.bu context)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.bh.NotifyMouseMessage(GrapeCity.Framework.Views.ba unit, GrapeCity.Framework.Views.bz m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.d.InnerProcess(GrapeCity.Framework.Views.bz m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.a7.InnerProcess(GrapeCity.Framework.Views.bz m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.Windows.ElementContainerControl.a.SynchronouslyDispatch(GrapeCity.Framework.Views.ax message, object args)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.Windows.ElementContainerControl.OnMouseClick(System.Windows.Forms.MouseEventArgs e)        不明
        System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks)        不明
>        System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m)        不明

        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Forms.FrameworkControl.WndProc(ref System.Windows.Forms.Message m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.Windows.ElementContainerControl.WndProc(ref System.Windows.Forms.Message m)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.GcMultiRow.WndProc(ref System.Windows.Forms.Message m)        不明
        System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam)        不明
        System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiTouch.as.WndProc(ref System.Windows.Forms.Message m)        不明
        System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam)        不明
        [ネイティブからマネージへの移行]        
        [マネージからネイティブへの移行]        
        System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData)        不明
        System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context)        不明
        System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context)        不明
        Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()        不明
        Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()        不明
        Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine)        不明



第二种动作的堆栈信息:        
CGMM065A.exe!CGMM065A.MM065A01.mlsRegiDeptSet_NewCellPositionNeeded(Object sender, GrapeCity.Win.MultiRow.NewCellPositionNeededEventArgs e) 行 589        Basic
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.m.a(ref GrapeCity.Win.MultiRow.InternalCellPosition A_0, GrapeCity.Win.MultiRow.InternalCellPosition A_1, GrapeCity.Win.MultiRow.MoveStatus A_2)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.m.a(ref GrapeCity.Win.MultiRow.InternalCellPosition A_0, bool A_1, GrapeCity.Win.MultiRow.MoveStatus A_2)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.m.a(System.Collections.Generic.List<int> A_0, GrapeCity.Win.MultiRow.Models.c A_1, bool A_2)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.MultiRowController.SelectColumnHeaderCell(GrapeCity.Win.MultiRow.InternalCellPosition headerCellPosition, GrapeCity.Win.MultiRow.MultiRowSelectionMode selectionMode, GrapeCity.Win.MultiRow.Models.c action, bool isShiftSelect)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.MultiRowController.ProcessMouseDownCell(GrapeCity.Win.MultiRow.InternalCellPosition cellLocation)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.MultiRowController.ProcessMouseDownForSelection(System.Windows.Forms.MouseEventArgs e)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.MultiRowController.BeginMouseDrag(System.Windows.Forms.MouseEventArgs e)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.b.OnPreviewMouseDown(System.Windows.Forms.MouseEventArgs e, GrapeCity.Framework.Views.bu context)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Controllers.MultiRowController.OnPreviewMouseDown(System.Windows.Forms.MouseEventArgs e, GrapeCity.Framework.Views.bu context)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.Views.y.OnPreviewMouseDown(System.Windows.Forms.MouseEventArgs e, GrapeCity.Framework.Views.bu context)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.bj.GrapeCity.Framework.Views.IInputable.MouseDown(System.Windows.Forms.MouseEventArgs arguments, GrapeCity.Framework.Views.bu context)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.bh.NotifyMouseMessage(GrapeCity.Framework.Views.ba unit, GrapeCity.Framework.Views.bz m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.d.InnerProcess(GrapeCity.Framework.Views.bz m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.a7.InnerProcess(GrapeCity.Framework.Views.bz m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.Windows.ElementContainerControl.a.SynchronouslyDispatch(GrapeCity.Framework.Views.ax message, object args)        不明
        
GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.Windows.ElementContainerControl.OnMouseDown(System.Windows.Forms.MouseEventArgs e)        不明
        System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseDown(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks)        不明
         
               System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Forms.FrameworkControl.WndProc(ref System.Windows.Forms.Message m)        不明
        GrapeCity.Framework.MultiRow.v23.dll!GrapeCity.Framework.Views.Windows.ElementContainerControl.WndProc(ref System.Windows.Forms.Message m)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiRow.GcMultiRow.WndProc(ref System.Windows.Forms.Message m)        不明
        System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam)        不明
        System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m)        不明
        GrapeCity.Win.MultiRow.v80.dll!GrapeCity.Win.MultiTouch.as.WndProc(ref System.Windows.Forms.Message m)        不明
        System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam)        不明
        [ネイティブからマネージへの移行]        
        [マネージからネイティブへの移行]        
        System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData)        不明
        System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context)        不明
        System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context)        不明
        Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()        不明
        Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()        不明
        Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine)        不明

3 个回复

倒序浏览
Carl
版主   /  发表于:2015-11-23 16:01:00
沙发
没理解楼主的意思,第一个调用堆栈是CellClick事件的断点,第二个调用堆栈是NewCellPositionNeeded事件的断点,两个没有可比性啊。
楼主说“其中一本在MultiRow的Header部用鼠标单击的时候,会先触发CellClick事件,然后才会发生光标迁移。”不知道是什么样的Case,正常情况下不会这样的。

CellClick事件的设计是参考WinForm的Control.Click事件。当鼠标在一个Cell上按下的时候,触发CellMouseDown,当鼠标松开的时候,先触发CellClick,再触发CellMouseUp事件。
只有当CellMouseDown和CellMouseUp都发生在同一个Cell上的时候,才会有CellClick事件。
Case1:在Cell1上按下左键,移动到Cell2,松开左键。Cell1触发CellMouseDown,Cell2触发CellMouseUp,没有CellClick。
Case2:在Cell1上按下左键,移动到Cell2,再移动回Cell1,松开左键。Cell1依次触发CellMouseDown,CellClick,CellMouseUp。

CurrentCell的变化发生在PreviewMouseDown的时机,也就是给用户发送的CellMouseDown事件之前。
内部逻辑会先触发NewCellPositionNeeded事件,拿到新的CurrentCell,然后触发SelectionChanged事件和CurrentCellChanged事件。
然后是给用户发送的CellMouseDown事件。
这个时候如果用户松开了鼠标,发送CellClick和CellMouseUp,选择结束;
如果用户没有松开而是移动鼠标,那么持续触发CellMouseMove和SelectionChanged,会有选择一个区域的Cell的效果。松开鼠标时再触发CellMouseUp。

也就是说,CurrentCellChanged是在CellMouseDown之前触发的。你按下鼠标之后,CurrentCell和Selection效果就已经改变了。
如果你遇到CellClick之后又发生了“光标迁移”,那么可能是别的逻辑再次修改了CurrentCell。

评分

参与人数 1金币 +999 收起 理由
Alice + 999 奖励金币

查看全部评分

愿 Engine 归于沉寂,Timer 停止运动,Message Queue 不再流淌,Data Source 为我掌握
回复 使用道具 举报
credream
中级会员   /  发表于:2015-11-27 13:15:00
板凳
回复 2楼Carl的帖子
没理解楼主的意思,第一个调用堆栈是CellClick事件的断点,第二个调用堆栈是NewCellPositionNeeded事件的断点,两个没有可比性啊。

两个处理的事件都是一样的,都有CellClick事件以及NewCellPositionNeeded事件。
两个处理的ColumnHeader都是标准的ColumnHeaderCell.Enabled=False,Selectable=False
第一个处理,点击ColumnHeader,会触发CellClick事件,这时候e.RowIndex=-1.执行完CellClick事件,会继续触发NewCellPositionNeeded事件,通过EventArgs得知,光标要迁移到点击列的第一行。

第二个处理,不知道什么原因,直接触发了NewCellPositionNeeded事件。

我们希望通过CellCLick事件判断点击Header的时候,通过逻辑可以实现单击ColumnHeader的时候,光标迁移到当前显示的第一行(FirstDisPlayCellPosion)

楼主说“其中一本在MultiRow的Header部用鼠标单击的时候,会先触发CellClick事件,然后才会发生光标迁移。”不知道是什么样的Case,正常情况下不会这样的。

就是上面说的,普通的Enabled=False Selectable=False的ColumnHeaderCell。
回复 使用道具 举报
Carl
版主   /  发表于:2015-11-27 15:15:00
地板
了解楼主的问题了。
鼠标点击ColumnHeaderCell时,策略是这样的:
如果CurrentCell没有包含在这个HeaderCell对应的Column里面,那么会把CurrentCell移动到这个Column的第一个Cell。
如果CurrentCell已经包含在这个Column中(无论是哪一行),那么不再移动CurrentCell。

第一种情况的执行顺序是:PreviewMouseDown -&gt; SelectColumnHeaderCell -&gt; Move CurrentCell -&gt; Raise NewCellPositionNeeded -&gt; CellMouseDown -&gt; CellClick
第二种情况的执行顺序是:CellMouseDown -&gt; CellClick,不会触发NewCellPositionNeeded。

如果你要自己在点击ColumnHeaderCell的时候自己移动CurrentCell,可以自己设置一个Flag来判断这次CurrentCell的移动是MultiRow自动触发的,还是你的代码设置CurrentCell触发的,再分别处理。
愿 Engine 归于沉寂,Timer 停止运动,Message Queue 不再流淌,Data Source 为我掌握
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部