在StringGrid中插入新行

时间:2016-01-08 00:38:27

标签: delphi vcl

我有一个StringGrid,它能够使用OnDraw方法绘制新行。

它工作正常,但现在我希望用户可以使用键盘输入新行。目前,多行文本必须被复制到StringGrid中。

每次按下VK_RETURN,StringGrid都会离开编辑模式。我该怎么办才能避免这种情况?

对于新行,我想要Ctrl + Return,就像它在Skype中一样。

procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key = VK_RETURN) and (ssCtrl in Shift) then // Ctrl+Return = New Line
  begin
    // TODO: Do NOT cancel edit mode
    // TODO: Insert #13#10 at current cursor position
  end;
end;

1 个答案:

答案 0 :(得分:3)

TStringGrid的内置单元格编辑器不支持多行文本(它是TCustomMaskEdit的后代,它是单行的)。您必须使用单独的UI控件(例如TMemo)来编辑多行文本。有几种不同的方法可以实现这一目标:

  1. 停用网格的内置编辑器(从网格的goEditing属性中删除Options标记),并在TMemo附近放置TStringGrid TForm。当用户选择单元格(并可选择单击按钮/菜单)时,将其当前文本分配到备忘录中。如果用户进行了任何更改(并可选择单击其他按钮/菜单),请将新文本指定回单元格。

  2. 上述内容的变体:设计一个单独的TMemo,其上有ShowModal()和保存按钮。当用户选择单元格(或按下按钮/菜单)时,将单元格的当前文本分配给表单的备忘录,然后通过调用其ModalResult方法显示该表单。如果用户单击“保存”按钮,请通过将其mrOk属性设置为ShowModal()来关闭“表单”。如果mrOk返回Invalidate(),请将备忘录的当前文本分配给正在编辑的单元格,然后ShowModal()网格以触发重新绘制。如果TStringGrid返回任何其他内容,则不执行任何操作。

  3. 上述内容的一种变体:启用网格的内置编辑器,并按上述方式设计单独的表单,然后配置TStringGrid以自动触发表单,而无需以以任何方式更改UI的其余部分

    1. GetEditStyle()派生一个新类,让它覆盖虚拟esEllipsis方法以返回esSimple(默认返回CreateEditor()),并覆盖虚拟TInplaceEditList方法返回TInplaceEdit派生类的新实例(默认情况下返回TInplaceEditList个对象)。这将导致单元格在编辑时显示按钮而不是编辑字段。

    2. 让您的UpdateContents()派生类拥有您的Form的实例,然后覆盖虚拟DoEditButtonClick()方法以检索当前的单元格文本并将其分配给Form?#s备注,并覆盖虚拟ShowModal()方法以模态方式显示表单并相应地响应template <typename F, typename Tuple, size_t... I> decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence<I...>) { return forward<F>(f)(get<I>(forward<Tuple>(t))...); } template <typename F, typename Tuple> decltype(auto) apply(F&& f, Tuple&& t) { using Indices = make_index_sequence<tuple_size<decay_t<Tuple>>::value>; return apply_impl(forward<F>(f), forward<Tuple>(t), Indices{}); } 的返回值。