简体   繁体   English

TStringGrid与BOTH编辑和范围选择?

[英]TStringGrid with BOTH editing AND range selection?

Question: 题:

Can anyone point to an article or code samples anywhere on how to provide BOTH editing AND range selection in a TStringGrid? 任何人都可以指向如何在TStringGrid中提供BOTH编辑和范围选择的文章或代码示例吗?

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. 交付时,TStringGrid不会这样做。 It's either/or. 它是/或。 In fact, the docs tell us about the grid Options, "When goEditing is included in Options, goRangeSelect has no effect". 事实上,文档告诉我们关于网格选项,“当goEditing包含在选项中时,goRangeSelect没有效果”。

However, it looks like it may be possible to do editing and rangeselects in a TStringGrid anyway!!! 但是,看起来无论如何都可以在TStringGrid中进行编辑和范围选择! 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. 通过仔细使用mousedown,mouseup,selectcell和exit事件,您可以通过在正确的时间打开和关闭编辑元素来关闭。 But I still don't have it perfect, and that only covers mouse use, not keyboard changes. 但我仍然没有完美,只能用于鼠标,而不是键盘更改。

I have not used the TStringGrid for this, so I can't provide a specific answer. 我没有使用过TStringGrid ,所以我无法提供具体的答案。 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 . 该链接意味着即使网格没有在其Options包含goEditing也是可能的。 (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: 我发现这是一种很好的,Windows标准行为的方法:

  • 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. 即,单击选择,单击并拖动以进行多选,使用键盘箭头和Shift或Control进行选择等。

    • 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) 选择一个单元格,用户按EnterF2 EnterF2是标准的“重命名”或“编辑”快捷键,可在多个程序中使用)

      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. 要实现此功能,请记录上次单击(并选择)单元格的时间。如果再次单击该单元格,并且如果时间大于GetDoubleClickTime则它们会慢慢单击两次,然后进入编辑模式。 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. 我使用GetSystemMetrics查找双击距离,并检查慢速双击是否在此框内。 (Because it's not a true doubleclick, I actually check the distance times 2. My action code is: (因为它不是真正的双击,我实际检查距离时间2.我的动作代码是:

        const int iMAX_MOVE_AMOUNT = ::GetSystemMetrics(SM_CYDOUBLECLK) * 2; (sorry, C++ not Delphi, but should be convertable easily enough!) (对不起,C ++不是Delphi,但应该可以轻松转换!)

        but I'm actually not certain if this is completely and utterly 100% to Windows guidelines. 但我实际上不确定这是否完全和完全100%的Windows指南。 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. 通过TStringGrid并创建新组件,您可能会发现其中一些更TStringGrid ,更容易实现。 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 . 它还将为您提供对鼠标事件或Windows消息的低级访问,而不仅仅是通过OnMouseDown等事件公开。 Finally, if there are problems with showing the editor when goEditing is included in Options , this will allow you to change that behaviour. 最后,如果在Options包含goEditing时显示编辑器时出现问题,这将允许您更改该行为。 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. 如果您希望代码响应某些事情,例如创建OnBeginEdit事件,您也可以添加自己的事件。

Creating your own components is normally regarded as an advanced Delphi topic, but it's actually remarkably easy once you know how! 创建自己的组件通常被认为是一个高级Delphi主题,但一旦你知道如何 ,它实际上非常容易! 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. 这个网站有一些很好的主题,一般会向你介绍这个主题,如果你走这条路并遇到问题,Stack Overflow当然是一个提问的好地方:) Embarcadero Delphi»VCL»Writing Components新闻组/论坛也是一个很好的资源,实际上甚至可能比这个特定主题的SO更好。

Hope that helps! 希望有所帮助!

Yes it's old post, but the problem still exist on Delphi XE3. 是的,这是旧的帖子,但问题仍然存在于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; 为了管理这个功能,我在SelectCell过程中使用了下一个“技巧”: if (ARow = StringGridParam.Row) then begin StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect]; end else begin StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing]; end; if (ARow = StringGridParam.Row) then begin StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect]; end else begin StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing]; end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM