TStringGrid 具有编辑和范围选择功能?

发布于 2024-09-01 21:25:20 字数 442 浏览 4 评论 0原文

问题:

任何人都可以在任何地方指出一篇文章或代码示例来了解如何 在 TStringGrid 中提供编辑和范围选择?

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

背景:

期望能够编辑网格中的单元格是很正常的, 还可以选择一系列单元格,例如复制操作。

在交付时,TStringGrid 并没有这样做。这是非此即彼。事实上, 文档告诉我们有关网格选项的信息,“当 goEditing 包含在 选项,goRangeSelect没有效果”。

但是,看起来可能可以进行编辑和范围选择 无论如何在 TStringGrid 中!!!通过小心使用鼠标按下, mouseup、selectcell 和 exit 事件,您可以通过切换来关闭 在正确的时间打开和关闭编辑元素。但我还是没有 它完美,并且仅涵盖鼠标使用,而不涵盖键盘更改。

Question:

Can anyone point to an article or code samples anywhere on how to
provide BOTH editing AND range selection in a TStringGrid?

Yes, I KNOW there are third-party grids that do this, but it's
frustrating that the built-in grid lacks this basic capability.

Background:

It's pretty normal to expect to be able to both edit a cell in a grid,
and also to select a range of cells such as for a Copy operation.

As delivered, TStringGrid doesn't do that. It's either/or. In fact, the
docs tell us about the grid Options, "When goEditing is included in
Options, goRangeSelect has no effect".

However, it looks like it may be possible to do editing and rangeselects
in a TStringGrid anyway!!! Through careful use of the mousedown,
mouseup, selectcell and exit events, you can get dang close by switching
editing elements on and off at the right times. But I still don't have
it perfect, and that only covers mouse use, not keyboard changes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

前事休说 2024-09-08 21:25:20

我没有为此使用过TStringGrid,所以我无法提供具体的答案。但是我假设您可以 手动(在代码中)启动正在编辑的单元格,这是正确的吗?该链接意味着即使网格的 Options 中没有包含 goEditing 也是可能的。 (如果情况并非如此,请参阅下文来解决此问题。)

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

组合选择和编辑行为

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

这应该让你在适当的时候在选择和编辑之间进行切换 。键盘和鼠标的时间。

其他想法

您可能会发现,通过子类化 TStringGrid 并创建一个新组件,其中一些更清晰、更容易实现。这将允许您在普通代码中实现这一点并覆盖内置行为(而不是事件处理程序),同时保持它对表单代码不可见。与仅通过 OnMouseDown 等事件公开的方式相比,它还使您能够对鼠标事件或 Windows 消息进行较低级别的访问。最后,如果当 Options 中包含 goEditing 时显示编辑器出现问题,这将允许您更改该行为。如果您希望代码响应某些发生的事情,例如创建 OnBeginEdit 事件,您也可以添加自己的事件。

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

希望有帮助!

I have not used the TStringGrid for this, so I can't provide a specific answer. But am I right in assuming you can manually (in code) start a cell being edited? That link implies it is possible even if the grid doesn't have goEditing included in its Options. (See below to work around this if this is not true.)

If so, I'd suggest the following approach:

Combined selection and edit behaviour

I find this is a good, Windows-standard-behaviour sort of approach:

  • Leave the grid in selection mode, so mouse and keyboard interaction selects cells

  • Trigger a cell being edited yourself, based on certain criteria (I think you are on the way to doing this from what you said in your last paragraph.) There are common ways to trigger editing, and the following criteria are what my programs follow when they do something similar with other controls:

    • Selection is normal. Ie, click to select, click and drag to multi-select, use the keyboard arrows and Shift or Control to select, etc.

    • A cell enters edit mode when either:

      1. A cell is selected and the user presses Enter or F2 (F2 is the standard "Rename" or "Edit" shortcut, which works in a number of programs)

      2. The user "slow-double-clicks" on a cell - ie, slow-double-clicks to select and edit, or clicks again, after a pause, on an already-selected cell. This mimics Explorer's behaviour, where if a file is selected and you later click on it, it enters the inline edit/rename mode. To implement this, record when a cell was last clicked (and selected.) If it is clicked again, and if the time is greater than GetDoubleClickTime then they have clicked twice, slowly, and enter edit mode. This allows you to distinguish between the first click to select, a double-click (to perform some kind of action), and a slow second click, to enter edit mode.

        I also tend to check the mouse position, so that if an object is slow-double-clicked and it wasn't first selected (ie, this both selects the object and then enters edit mode) I verify the mouse hasn't moved very much. I use GetSystemMetrics to find the double-click distance, and check that the slow double click was within this box. (Because it's not a true doubleclick, I actually check the distance times 2. My action code is:

        const int iMAX_MOVE_AMOUNT = ::GetSystemMetrics(SM_CYDOUBLECLK) * 2; (sorry, C++ not Delphi, but should be convertable easily enough!)

        but I'm actually not certain if this is completely and utterly 100% to Windows guidelines. In practice users find it works as they expect, though.)

That should let you change between selecting and editing at the appropriate times with both the keyboard and the mouse.

Miscellaneous thoughts

You may find some of this is cleaner and easier to implement by subclassing TStringGrid and creating a new component. That will allow you to implement this in normal code and override the inbuilt behaviour (rather than event handlers) while keeping it invisible to the form code. It will also give you lower-level access to the mouse events or Windows messages than are exposed simply through events such as OnMouseDown. Finally, if there are problems with showing the editor when goEditing is included in Options, this will allow you to change that behaviour. You could also add your own events if you want your code to respond to certain things happening, such as creating an OnBeginEdit event, say.

Creating your own components is normally regarded as an advanced Delphi topic, but it's actually remarkably easy once you know how! This site has a few good topics that will introduce you to the subject in general, and if you go this route and encounter problems, Stack Overflow is of course a good place to ask questions :) The Embarcadero Delphi » VCL » Writing Components newsgroup / forum is also an excellent resource, in fact possibly even better than SO for this specific topic.

Hope that helps!

懒猫 2024-09-08 21:25:20

是的,这是旧帖子,但问题在 Delphi XE3 上仍然存在。
为了管理此功能,我在 SelectCell 过程中使用了下一个“技巧”:
<代码>
if (ARow = StringGridParam.Row) then
开始
StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect];
结束否则开始
StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing];
结束;

Yes it's old post, but the problem still exist on Delphi XE3.
To manage this feature I used next "trick" in SelectCell procedure :

if (ARow = StringGridParam.Row) then
begin
StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect];
end else begin
StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing];
end;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文