4

问题:

任何人都可以在任何地方指向一篇关于如何在 TStringGrid 中提供编辑和范围选择的文章或代码示例吗?

是的,我知道有第三方网格可以做到这一点,但令人沮丧的是内置网格缺乏这种基本功能。

背景:

期望能够编辑网格中的单元格以及选择一系列单元格(例如用于复制操作)是很正常的。

交付时,TStringGrid 不这样做。这是非此即彼的。实际上,文档向我们介绍了网格选项:“选项中包含goeding,gorangeSelect没有效果”。

但是,看起来无论如何都可以在 TStringGrid 中进行编辑和范围选择!!!通过仔细使用 mousedown、mouseup、selectcell 和 exit 事件,您可以通过在正确的时间打开和关闭编辑元素来接近。但我仍然没有完美,而且只包括鼠标的使用,而不是键盘的变化。

4

2 回答 2

3

我没有使用过TStringGrid这个,所以我不能提供一个具体的答案。但是我是否正确地假设您可以手动(在代码中)启动正在编辑的单元格?该链接意味着即使网格未goEditing包含在其Options. (如果不是这样,请参阅下文以解决此问题。)

如果是这样,我建议采用以下方法:

组合选择和编辑行为

我发现这是一种很好的 Windows 标准行为方法:

  • 让网格处于选择模式,以便鼠标和键盘交互选择单元格

  • 根据某些标准触发自己正在编辑的单元格(我认为您正在按照您在上一段中所说的内容执行此操作。)触发编辑的常用方法,以下标准是我的程序在何时遵循的他们对其他控件执行类似操作:

    • 选择是正常的。即单击选择、单击并拖动进行多选、使用键盘箭头和 Shift 或 Control 进行选择等。

    • 单元格在以下任一情况下进入编辑模式

      1. 选择了一个单元格,用户按下EnterF2F2是标准的“重命名”或“编辑”快捷方式,适用于许多程序)

      2. 用户“慢速双击”一个单元格——即慢速双击以选择和编辑,或在暂停后再次单击已选择的单元格。这模仿了资源管理器的行为,如果选择了一个文件并且您稍后单击它,它将进入内联编辑/重命名模式。要实现这一点,请记录最后一次单击(并选择)单元格的时间。如果再次单击它,并且如果时间大于GetDoubleClickTime则它们单击了两次,慢慢地,然后进入编辑模式。这使您可以区分第一次单击以选择、双击(执行某种操作)和缓慢的第二次单击以进入编辑模式。

        我也倾向于检查鼠标位置,因此如果一个对象被慢速双击并且它不是首先被选择的(即,这既选择了对象,然后进入编辑模式)我验证鼠标没有移动得很很多。我GetSystemMetrics用来查找双击距离,并检查慢速双击是否在此框内。(因为它不是真正的双击,我实际上检查了距离乘以 2。我的操作代码是:

        const int iMAX_MOVE_AMOUNT = ::GetSystemMetrics(SM_CYDOUBLECLK) * 2;(对不起,C++ 不是 Delphi,但应该很容易转换!)

        但我实际上不确定这是否完全 100% 符合 Windows 指南。但在实践中,用户会发现它按预期工作。)

这应该可以让您在适当的时间使用键盘和鼠标在选择和编辑之间进行切换。

杂念

TStringGrid通过子类化和创建新组件,您可能会发现其中一些更简洁、更容易实现。这将允许您在普通代码中实现这一点并覆盖内置行为(而不是事件处理程序),同时使其对表单代码不可见。与简单地通过诸如OnMouseDown. goEditing最后,如果在 中包含时显示编辑器有问题Options,这将允许您更改该行为。如果您希望代码响应发生的某些事情,例如创建OnBeginEdit事件,您也可以添加自己的事件。

创建自己的组件通常被认为是一个高级的 Delphi 主题,但是一旦您知道如何操作,它实际上非常容易! 这个站点有一些很好的主题,可以向您介绍该主题,如果您走这条路并遇到问题,Stack Overflow 当然是提问的好地方 :) Embarcadero Delphi » VCL » 编写组件新闻组 /论坛也是一个很好的资源,实际上对于这个特定主题甚至可能比 SO 更好。

希望有帮助!

于 2010-05-19T02:08:45.617 回答
1

是的,这是旧帖子,但问题仍然存在于 Delphi XE3 上。为了管理这个特性,我在 SelectCell 过程中使用了下一个“技巧”: if (ARow = StringGridParam.Row) then begin StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect]; end else begin StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing]; end;

于 2015-11-24T14:29:37.293 回答