在Delphi TStringGrid中检测单个和多个选择 [英] Detecting single vs multiple selections in Delphi TStringGrid

查看:1136
本文介绍了在Delphi TStringGrid中检测单个和多个选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我以前的问题的追踪 Delphi TStringGrid多选,确定选定的行关于Delphi字符串网格。这是一个不同的问题。



我更加关注ONSelectCell事件
TSelectCellEvent = procedure(Sender:TObject; ACol,ARow:Longint; var CanSelect:我注意到,TStringGrid.Selection.Top,Bottom属性不一定准确(在事件本身内)。对象的布尔值;



基本上,如果有人从多个行中选择一行,则选择。*属性不会被更新,而如果选择多个行,则它们会做。



无论选择了一行还是多行,ARow参数都会得到更新,但这只会帮助我,如果我可以确定选择了一行,只有一行。例如,如果只有一行被选中,则使用Arow参数,如果多个行然后使用Selection。*属性来确定哪些行是



必须有一个更简单的方法....



谢谢!

解决方案

我认为,部分问题在于使用术语。在您完全了解发生的情况之前,必须弄清楚如何使用'select'来表示'highlight''focus'。在这种特殊情况下,应该区分两者。



在开始之前,我希望您记住 单元格也可以(并且实际上是)突出显示,但突出显示的单元格不一定是重点的单元格。



现在,$ $ c> OnSelectCell 事件与聚焦有关。单击单元格或当您尝试使用导航键导航时,处理程序将触发。简而言之,当尝试 单元格时,调用处理程序。您可以通过重置 CanSelect 参数(这又意味着基本上意味着 CanFocus ),因为单元格可以被选择,即突出显示,而不被聚焦,您不能通过 OnSelectCell 控制它。



另一方面, goRangeSelect 选项和 TDrawGrid.Selection 属性必须与选择为突出显示。前者允许您(用户)突出显示多个单元格,而后者指向突出显示的单元格的范围。



现在我的要点在调用有问题的处理程序时,选择永远不会准确,即它与 ACol & ARow 传递给处理程序的参数。 选择包含在调用处理程序之前突出显示的单元格范围,并且它不会在处理程序中自己更改。一个单元格或多个单元格选择 保持不变,直到处理程序退出。而当这种情况发生时(处理程序退出), Selection 更改(结果取决于是否重置 CanSelect 或者不,顺便说一下)。



所以,总而言之,你不能使用 OnSelectCell 来确定实际的选择作为用户最近的 操作的结果。相反,我建议您遵循以下 @Sam 并且使用 OnMouseUp * 事件。它还允许您控制选择:如果您认为用户选择了太多,则可以更正最终范围。在后一种情况下,我可能会考虑使用 OnMouseMove ,但是,它允许您通过更正更新范围来更顺利地响应。

$只要您需要确定选择,只要您只需要确定选项即可,但

OnDrawCell






* 在你的评论之后,我必须补充一下,你也必须使用 OnKeyUp ,以处理用键盘进行的选择。


This is a follow up to my previous question Delphi TStringGrid multi select, determining selected rows regarding Delphi String Grids. It's a different question.

I was looking more closely at the ONSelectCell Event TSelectCellEvent = procedure (Sender: TObject; ACol, ARow: Longint; var CanSelect: Boolean) of object;

I noticed that the TStringGrid.Selection.Top,Bottom properties are not necessarily accurate (within the event itself). Basically, if someone goes from selecting multiple rows to just one row, the selection.* properties do not get updated, whereas if one selects multiple rows, they do.

The ARow parameter does get updated regardless of whether one or more rows are selected, but this will only help me if I can determine that one and only one row was selected.

Eg, If it's just one row that was selected, then use Arow parameter, if more than one row then use Selection.* properties to determine which row(s) are currently selected.

There must be an easier way....

Thank you!

解决方案

I think, part of the problem is in terminology used. Until you completely understand what is happening, it must be confusing to find how ‘select’ is used to mean both ‘highlight’ and ‘focus’. In this particular case there should be distinction between the two.

Before I proceed, I'd like you to keep in mind that the focused cell can also be (and actually is) highlighted, but a highlighted cell is not necessarily the focused one.

Now, the OnSelectCell event has to do with focusing. The handler is fired when the cell is clicked or when you are trying to navigate over it with navigation keys. In short, the handler is invoked when there's an attempt to focus a cell. You can prohibit focusing the cell by resetting the CanSelect parameter (which, again, means essentially CanFocus, because the cell can be selected, i.e. highlighted, without being focused, and you can't control that with OnSelectCell).

The goRangeSelect option and TDrawGrid.Selection property, on the other hand, have to do with selecting as highlighting. The former allows you (the user) to highlight more than one cell, while the latter points to the range of those cells highlighted.

Now to my main point. Upon invoking the handler in question, Selection is never accurate, i.e. it is not correlated with the ACol & ARow parameters that are passed to the handler. Selection contains the range of cells that were highlighted just before calling the handler, and it never changes by itself within the handler. Whether one cell or more than one, Selection stays the same until the handler exits. And it is when that happens (the handler exits) that Selection changes (and the result depends on whether you reset CanSelect or not, by the way).

So, in conclusion, you cannot use OnSelectCell to determine the actual Selection as the result of the user's most recent action. Instead I would suggest following @Sam's advice and use the OnMouseUp* event. It also allows you to have control over selection: you can correct the final range if you think the user has selected ‘too much’. In the latter case I would probably consider using OnMouseMove instead, though, as it allows you to respond more smoothly by correcting the range ‘on the fly’.

OnDrawCell seems fine too as long as you need just to determine the selection.


*Following your comment, I must add, that you'd also have to employ OnKeyUp as well, to handle selections made with the keyboard.

这篇关于在Delphi TStringGrid中检测单个和多个选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆