这是关于Delphi字符串网格的前一个问题Delphi TStringGrid multi select, determining selected rows的后续内容。这是一个不同的问题。
我正在密切关注ONSelectCell事件 对象的TSelectCellEvent = procedure(Sender:TObject; ACol,ARow:Longint; var CanSelect:Boolean);
我注意到TStringGrid.Selection.Top,Bottom属性不一定准确(在事件本身内)。基本上,如果有人从选择多行到只有一行,则选择。*属性不会更新,而如果选择多行,则会更新。
无论是否选择了一行或多行,ARow参数都会更新,但只有在我确定选择了一行且只有一行时,这才会对我有所帮助。
例如,如果只选择了一行,则使用Arow参数,如果有多行,则使用Selection。*属性来确定当前选择的行。
必须有一种更简单的方法......
谢谢!
答案 0 :(得分:4)
我认为,部分问题在于使用的术语。在您完全理解正在发生的事情之前,找到'select'用于表示'highlight'和'focus'。在这种特殊情况下,两者之间应该有区别。
在我继续之前,我希望您记住,聚焦单元格也可以(并且实际上)突出显示,但突出显示的单元格不是必然是专注的。
现在,OnSelectCell
事件与聚焦有关。单击单元格或尝试使用导航键在其上导航时会触发处理程序。简而言之,当尝试聚焦一个单元格时,会调用该处理程序。您可以通过重置CanSelect
参数来禁止对单元格进行聚焦(同样,这意味着基本上是 CanFocus ,因为可以选择单元,即突出显示,而不是专注,你无法用OnSelectCell
)控制它。
另一方面,goRangeSelect
选项和TDrawGrid.Selection
属性与选择突出显示有关。前者允许您(用户)突出显示多个单元格,而后者指向突出显示的单元格范围。
现在我的主要观点。在调用有问题的处理程序时,Selection
从不准确,即它与ACol
&传递给处理程序的ARow
个参数。 Selection
包含在调用处理程序之前突出显示的单元格范围,并且它永远不会在处理程序中自行更改。无论是一个单元格还是多个单元格,Selection
都会保持相同,直到处理程序退出。当发生这种情况时(处理程序退出)Selection
发生变化(结果取决于您是否重置CanSelect
,顺便说一下)。
因此,总而言之,您无法使用OnSelectCell
来确定实际Selection
作为用户最新操作的结果。相反,我会建议遵循@Sam的建议并使用OnMouseUp
* 事件。它还允许您控制选择:如果您认为用户选择了“太多”,您可以更正最终范围。在后一种情况下,我可能会考虑使用OnMouseMove
,因为它可以让你通过“动态”修正范围来更顺畅地回应。
OnDrawCell
似乎也很好,只要您只需要确定选择。
* 在您发表评论之后,我必须补充一点,您还必须使用OnKeyUp
来处理使用键盘进行的选择。
答案 1 :(得分:0)
for RowIndex := StringGrid1.Selection.Top to StringGrid1.Selection.Bottom do
begin
DoSomethingWithRow(RowIndex);
end;
是的,我明白你的意思了。似乎在 OnSelectCell事件之后更新了Selection属性,所以在事件内你只有旧值(即在select事件之前)。答案是将上面的代码移动到stringgrid的OnMouseUp事件。它似乎工作正常。
答案 2 :(得分:0)
我能够自己解决这个问题,我使用OnDrawCell事件和onSelectCell事件结束了 - 我认为这将是一团糟,但事实并非如此糟糕。
以下是针对遇到同样问题的其他人的解决方案的摘要。以下是两个关键事实:
public previousHighlightCount : integer; //flag to ensure that the necessary code within the onDraw only gets called once per row selection(s). Initialize to '1' in onFormCreate. procedure Grid.OnDrawCell(...) begin ... SelectionCount := Grid.Bottom - Grid.Top;** if ((SelectionCount = 1) AND (previousHighlightCount 1)) then begin GridUpdateEdits; //your routine to update the grid properly for one row.* previousHighlightCount := 1; end else previousHighlightCount := PrtEdtGrid.SelectionCount; //the routine for multiply selected rows is in the onSelectCell Event and onSeelctCell works for multiple selections. .... end;
感谢那些回复!!
答案 3 :(得分:0)
StringGrid1.Selection.Top to StringGrid1.Selection.Bottom 因为我使用onkeypress事件来选择/取消选择内容,所以对我来说是完美的。