【问题标题】:Can ShortCut-Key, that has been processed by Delphi TAction, be allowed to propagate further to other components?是否允许 Delphi TAction 处理的 ShortCut-Key 进一步传播到其他组件?
【发布时间】:2019-08-26 10:16:30
【问题描述】:

核心问题:我不喜欢 TcxGrid 删除(由 TcxGrid 的默认 Ctrl+Del 快捷键或 cx-navigator 的 Delete 按钮启动)的工作方式:它简单直接调用底层数据集的删除,cxGrid 或 cxGridDataView 没有 TcxGrid(/DataController).OnDelete(Sender: TObject, var AHandled: Boolean) 事件。从https://www.devexpress.com/Support/Center/Question/Details/Q308755/tcxgrid-deleting-record我了解到我只能配置确认消息,但我无法控制删除本身,即我无法实现自定义删除,因此我什至不尝试要求直接解决方案问题。我的问题是关于解决方法。

这就是为什么我拒绝使用 cx-navigator 并选择引入 TAction 来处理整个表单的 Ctrl+Del 快捷键。我在表单上有多个网格,每个网格都有自己有问题的删除过程,应该由自定义过程以非标准方式处理。

这就是为什么我的 DeleteAction 最初确定 ActiveControl (TcxGridSite, TcxGrid) 然后调用相关的 Delete 过程。这一切都很好。但是其他一些组件(例如 TcxDBTextEdit)也具有默认的 Ctrl+Del 处理,并且处理非常非常好。但是如果快捷键 Ctrl+Del 被动作处理(并且即使在找不到活动网格的情况下也被标记为已处理,因此即使在 ActionExecute 没有做任何有用的事情的情况下),则停止进一步的传播。这可以从经验上观察到,从理论上可以从http://edn.embarcadero.com/article/38447 看出。

但也许仍然有一些解决方法,如果它们是 Active 控件,则 ActionExecute 处理的快捷键仍然可以进一步传播到默认组件。

我知道 TAction 用于(窗体范围的全局)菜单功能,但 TcxGrid 的可扩展性不够,这就是为什么也应该尝试扩展 Delphi TAction 设计的原因。

【问题讨论】:

  • 为什么在使用 OnBeforeDelete 事件时不能实现自定义删除例程?我想您仍然可以编写自己的删除例程,从该事件中触发并调用Abort作为事件中的最后一次调用,以防止调用默认的删除例程。

标签: delphi devexpress keyboard-shortcuts tcxgrid


【解决方案1】:

可能会有多种方法来实现您所需的处理,在关键处理期间您可以在很多地方进行干预,正如您已经从问题中链接的彼得·弗兰克的文章中读到的那样。

我能想到的将所有部分组合在一起的干预位置是表单的IsShortCut 方法。这种方法的一个可能的缺点可能是您必须在您希望更改其键处理行为的所有表单上实现它。

通常,只有在没有快捷键处理的情况下才会继续进行键处理。下面的解决方案报告了由于该原因未处理的快捷方式,但随后必须手动执行操作。可以看出,我使用常规编辑测试了代码,但我想它应该没有任何区别。

function TForm1.IsShortCut(var Message: TWMKey): Boolean;
begin
  if (ActiveControl is TEdit) and (Message.CharCode = VK_DELETE) and
      (KeyDataToShiftState(Message.KeyData) = [ssCtrl]) then begin
    Result := False; // if you don't require the action to be executed, just exist here 

    ActionList1.IsShortCut(Message); // executes the action, ignore result 

    // returning false will result in main form's shortcut handler to be called
    // below is only required if this is the main form
    if Application.MainForm = Self then
      Message.CharCode := 0;
  end else
    Result := inherited IsShortCut(Message);
end;

【讨论】:

    猜你喜欢
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 2012-06-05
    • 2023-03-24
    相关资源
    最近更新 更多