估计是没人会的dgv问题

zhouzixian 2008-07-29 09:05:10
问了两次,懂了我的问题的只有一人。所以很是郁闷。
重新来一次,说的再白一点,希望有第二个理解的。当然希望有能解决的。

DataGridView的MultiSelect有两种方式:一:所选单元格在同一个矩形区域内,直接从矩形任一角的单元格拖动到对角线上的单元格,鼠标(或键盘)松开,完成选择;二:按住Ctrl一个一个的选,此方法可包含“方法一”,也就是选中的可以是单个单元格,也可以是矩形区域的单元格组。

如果上面这一段没听懂,就自己去搞个看看。我实在是没力气了。

在上述方式一中,假设“从矩形任一角的单元格(A,B)拖动到对角线上的单元格(C,D)”,在拖动过程中(注意:鼠标并未弹起,所以与MouseUp事件无关),DataGridView的焦点(怕你们不懂,就是CurrentCell)一直保持为鼠标移动到的单元格,也就是从(A,B)沿鼠标轨迹移动到(C,D)。

上一段是DataGridView默认的方式,而我想要的就是在这个拖动过程中CurrentCell一直保持在(A,B)不动。 之前怕大家不懂,所以拿MS Excel作比较,因为Excel就是这样,可是发现,很多回复者对Excel很白。

最后提示三点:1、DataGridView里有个MultiSelect事件,该事件对这个拖动过程没反应。
2、如果你想在DataGridView默认的方式之上再把焦点移动到(A,B),恐怕是不行的;并且我希望对Dgv使用RowEnter事件,所以就算你按这个方式完成了,RowEnter事件也将因此被废掉。
3、该行为不仅由鼠标拖动完成,键盘上的方向键也是同样的效果,因此应当同时考虑键盘完成的可行性。
...全文
292 38 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanlongwuhui 2008-08-07
  • 打赏
  • 举报
回复
既然这么难实现,建议还是调整功能需求吧。看能否放弃一些功能要求或是弱化某些功能要求
zhouzixian 2008-08-07
  • 打赏
  • 举报
回复
感谢35楼大哥的指点!
相比30、31、34楼的废话。要好不知道多少倍。

我之所以要实现这样的功能,一:我希望它具有多选的功能。二:我希望使用RowEnter事件获取数据。所以希望多选的时候焦点不变。三:(次要)觉得这对控件性能影响不小,重写但愿可以提升性能。


看来要实现这功能,只有等微软改写了。
llsus 2008-08-07
  • 打赏
  • 举报
回复
我提示楼主几点:
1、MultiSelect事件仅仅当MultiSelect属性的值发生改变时才发生,不是用在这个地方的
2、不要企图对CurrentCell属性进行赋值,应为赋值后,你将丢失所有已经选择的内容,DBV中选中的内容将变成你赋值后的那个单元格
3、如果你要是在拖选的过程中,继续访问第一个被选择的单元格,请使用:DataGridView1.SelectedCells(DataGridView1.SelectedCells.Count - 1)
4、如果你仅仅是要显示的效果,就是有虚框的那个单元格停留在你拖选的第一个单元格上,我目前没找到方法,好像DBV并没有提供拖选过程的事件(我反正没找到),但是提供了拖选完成的事件(SelectionChanged),但是由于不能对CurrentCell赋值,所以不能在托选完成后移动虚框的焦点,在托选过程中是可以对CurrentCell赋值的,但是托选后,会被DBV重新设置CurrentCell,也就是说,设置了也没用
我暂时就发现这些,希望对你有所帮助。

以下是我测试的代码:

Public Class Form1

Dim msdown As Boolean = False

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For i As Integer = 1 To 10
DataGridView1.Rows.Add(i * 1, i * 2, i * 3, i * 4, i * 5, i * 6)
Next
End Sub

Private Sub DataGridView1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseDown
msdown = True
End Sub

Private Sub DataGridView1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseUp
If msdown Then
'DataGridView1.CurrentCell = DataGridView1.SelectedCells(DataGridView1.SelectedCells.Count - 1)
msdown = False
End If
End Sub

Private Sub DataGridView1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseMove
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MsgBox(DataGridView1.CurrentCell.Value)
End Sub

Private Sub DataGridView1_CellMouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseUp
' DataGridView1.CurrentCell = DataGridView1.SelectedCells(DataGridView1.SelectedCells.Count - 1)
End Sub

Private Sub DataGridView1_CellMouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseMove
If msdown Then
If DataGridView1.SelectedCells(0) IsNot Nothing Then
' DataGridView1.CurrentCell = DataGridView1.SelectedCells(DataGridView1.SelectedCells.Count - 1)
TextBox1.Text = DataGridView1.SelectedCells(DataGridView1.SelectedCells.Count - 1).Value
' TextBox2.Text = DataGridView1.CurrentCell.Value
End If
End If

End Sub

Private Sub DataGridView1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGridView1.SelectionChanged
DataGridView1.CurrentCell = DataGridView1.SelectedCells(DataGridView1.SelectedCells.Count - 1)
TextBox2.Text = DataGridView1.CurrentCell.Value
End Sub
End Class
zhouzixian 2008-08-07
  • 打赏
  • 举报
回复
恩恩。只能如此了。
chillystar 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 zhouzixian 的回复:]
用别的控件是下下策了。不过我觉得还是可以有办法的。只要咱努力顶着。

有一个现象不知道大家碰到过没有。就是DataGridView在多重选择的时候感觉闪烁很厉害,不像其他什么表单一样清爽,不知道是因为VB.NET效率的问题还是别的什么原因。我觉得跟这个焦点变动有一定关系。
[/Quote]

闪烁是因为存在着界面多次刷新,您在选定的过程是对datagridview界面刷新,同时如果捆绑动态数据源时也会刷新数据源,如果刚好两者同时发生,就产生闪烁。
另外如果您想从datagridview得到您想要的效果,我想是没有办法了。因为datagridview中有类似数据表的“当前游标”的概念,即当前选择在“哪条记录的哪个字段”上,这与datagridview捆绑数据源的特性有关,试想下如果您选到cell(C,D),而当前游标仍停留在cell(A,B),在更改记录时就会产生不测后果。
从您的需求来看,要模拟界面要比方便数据操作高得多,不妨换个角度来做;用个界面处理较好的表格控件,msflexgrid与datagridveiw比较起来,在显示和操作数据时仅是多出几个判断行列的语句而已,既不影响到功能效果,又能达到理想的界面效果,不正是您要追求的目的?条条大道通罗马,为何一定要将自己捆绑在datagridview上钻牛角尖?
paulin 2008-08-06
  • 打赏
  • 举报
回复
关注~
zhouzixian 2008-08-06
  • 打赏
  • 举报
回复
用别的控件是下下策了。不过我觉得还是可以有办法的。只要咱努力顶着。

有一个现象不知道大家碰到过没有。就是DataGridView在多重选择的时候感觉闪烁很厉害,不像其他什么表单一样清爽,不知道是因为VB.NET效率的问题还是别的什么原因。我觉得跟这个焦点变动有一定关系。
chillystar 2008-08-06
  • 打赏
  • 举报
回复
如果实在不行,建议楼主使用Msflexgrid试试,与Excel非常类似。多重选择方面与楼主提出的要求完全一致。
但有个缺点也和Excel一样,就是最大行数的限制,Excel一个工作表最大行数是65536行,msflexgrid也是;此外VB6中的msflexgrid与datagridview不同的地方在于msflexgrid是表格而不是数据表格,它的数据绑定与datagridview有所不同,好像不能直接绑定ADO;另外其不能直接编辑,要通过加载一个Text框进行处理。这些在vb.net不知道有没有改善。
taick 2008-08-06
  • 打赏
  • 举报
回复
这个问题跟人为什么一定要用嘴巴吃饭一样
而尝试使用屁股吃饭的人简直就是白痴

我不排除以后的datagridview会有在右键拖选时不改变当前单元格的功能
也不排除可能有人现在就能做到,牛人还是有的,不过再牛也要按别人的规则来走,除非你自己写个datagridview.
但请你记住,如果现在这个方法不行,是可以换一种方法来实现你最终的功能的.
而且在现在的datagridview来看,即使能做到这点,可能会影响其它的一些事件或方法的使用,因此不建议硬来.

退一步,如果现在的datagridview能做到你的要求,假如有人想要把当前单元格自动设为最后的单元格,又或者中间的单元格(汗~~~),无语...
困困 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用楼主 zhouzixian 的帖子:]

我想要的就是在这个拖动过程中CurrentCell一直保持在(A,B)不动。…
[/Quote]
为什么? 能不能解释一下,
(仅仅是为了好看?还是别的程序上的问题?)
如果是为了别处程序上的问题,
可以试着换个思路,去改“别处程序”。
困困 2008-08-06
  • 打赏
  • 举报
回复
给客户定个规定:
“选择的时候必须从(C,D)反着开始选,到(A,B)结束。”
这样currentCell就是(A,B)了。
kouti 2008-08-06
  • 打赏
  • 举报
回复
楼主说的我是不懂。但不代表其他人不会。很多时候,别人不会解答你的问题,不是因为没有人懂,也不是因为没有人碰到过。而是因为楼主表述不清楚,举个例子,同一个问题,有些人在百度一搜就出来结果了。但是有很多人搜上十天八天的也搜不出来。为什么,因为他们输入的关键字不一样,他们还不会将所需要解答的事物用正确的逻辑语言表述出来。别人连他想干吗都不知道,该怎么回答呀?就拿这个为例吧。楼主可以把你的部分代码贴出来,又或者截个图什么的。让大家可以看的更清楚一些,更容易理解问题。
zhouzixian 2008-08-05
  • 打赏
  • 举报
回复
22楼的思路我大概懂了,但以之前失败的经验看,你这样的方式可能的结果是CurrentCell先移动到(C,D),再移动到(A,B)。因为移动到(C,D)这段程序会在MouseMove事件之前执行。

我先去试试看。再说。
zhouzixian 2008-08-05
  • 打赏
  • 举报
回复
Friend MultiCellX As Integer, MultiCellY As Integer

Private Sub DGV_CellMouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles Me.CellMouseDown
MultiCellX = e.RowIndex
MultiCellY = e.ColumnIndex
End Sub

Private Sub DGV_CellMouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles Me.CellMouseMove
If sender.MouseButtons = Windows.Forms.MouseButtons.Left Then
Me.CurrentCell = Me(MultiCellY, MultiCellX)
End If
End Sub
以上是我根据22楼的思路写的,暂且不考虑细枝末节。
这样写了后还是没能实现,因为发现在CellMouseMove事件处理完成后,DataGridView才完成那个默认的将CurrentCell设置为(C,D)的操作。
所以25楼说的重写是肯定的。但关键问题是,根据我的判断,需要重写其中某个基函数才能实现。

破咖啡罐子 2008-08-05
  • 打赏
  • 举报
回复
看来只有重写一个dagagridview控件,然后自己定义个属性来保存这个单元格位置了。
不过如果你说的能实现,那CurrentCell这个属性要如何变化呢?
chillystar 2008-08-04
  • 打赏
  • 举报
回复
上一段是DataGridView默认的方式,而我想要的就是在这个拖动过程中CurrentCell一直保持在(A,B)不动。 ……

上面是楼主的要求吧?
我觉得楼主可以建立一个locate(X,Y)结构,在mousedown时将开始(即cell(A,B)的行列坐标赋予locate,即x=col,y=row),在mousemove事件处理代码的最后将活动单元格重新定位;
如果重新定位会影响拖拽的选定范围,还可以多定义一个size(Xs,Ys)结构,在mousemove时判断拖拽所到达的行列数量,在末期执行上步后,再设定一下行列选择范围。
以上的解释不知道楼主是否明白,不明白可以给出具体的演示代码。
akenny0423 2008-08-04
  • 打赏
  • 举报
回复
自己继续顶。
zhouzixian 2008-08-02
  • 打赏
  • 举报
回复
自己继续顶。
dstmt 2008-08-01
  • 打赏
  • 举报
回复
真不会,帮顶
andy_15810137572 2008-08-01
  • 打赏
  • 举报
回复
呵呵呵呵
我也不会
我替你顶一下
加载更多回复(18)

16,722

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧