Delphi 编辑TTreeView节点时如何停止对话框的默认和取消行为

Delphi 编辑TTreeView节点时如何停止对话框的默认和取消行为,delphi,Delphi,我有一个对话框,上面有一个TTreeView控件和一个OK和Cancel按钮。按钮的默认和Canel属性分别设置为true,并且ModalResult设置正确 用户可以使用内置的控件功能编辑树节点的标题 如果用户在编辑树节点时点击escape或enter,对话框将消失,而不仅仅是取消或接受对节点标题的编辑 例如,在escape的情况下,我希望按一下escape可以编辑标题,然后再按一下escape取消对话框 处理这种情况的最佳方法是什么 TMemo有WantReturns属性来处理此问题,但我看

我有一个对话框,上面有一个TTreeView控件和一个OK和Cancel按钮。按钮的默认和Canel属性分别设置为true,并且ModalResult设置正确

用户可以使用内置的控件功能编辑树节点的标题

如果用户在编辑树节点时点击escape或enter,对话框将消失,而不仅仅是取消或接受对节点标题的编辑

例如,在escape的情况下,我希望按一下escape可以编辑标题,然后再按一下escape取消对话框

处理这种情况的最佳方法是什么


TMemo有WantReturns属性来处理此问题,但我看不到TTreeView的任何内容。

您应该从按钮中删除默认属性和取消属性,而应该在form keyDown上对按下的键设置大小写,然后执行OK或Cancel

编辑:
您还需要将keypreview设置为true。

不要只在“确定”和“取消”按钮上设置ModalResult属性,而是创建一个OnClick事件处理程序并使用

if not(TreeView1.IsEditing) then ModalResult:=mrOk

或者分别使用mrCancel

在TTreeView.OnEditing中将默认值和Cancel临时设置为False,并在TTreeView.OnEdited中将其恢复为True可能会有所帮助。没有OnCancelEdit-这可能是个问题。

在这种情况下,我要做的是在窗体中添加一个OnCloseQuery事件处理程序,如果TTreeView是焦点控件,它将阻止窗体关闭。

我想我找到了最好的解决方案。一点理论:但是点击Escape按钮是在
TButton.CMDialogKey
中启动的,该按钮由
TCustomForm.CMDialogKey
通过继承方法
TWinControl.CMDialogKey
调用,该方法只调用其所有控件的WndProc和给定消息。 所以我们所要做的就是重写form的方法:

// Ignore ESCAPE when TV is in edit mode
procedure TForm1.CMDialogKey(var Msg: TWMKey);
begin
  if (Msg.CharCode = VK_ESCAPE) and (KeyDataToShiftState(Msg.KeyData) = []) and
     (ActiveControl = tvTree) and tvTree.IsEditing
    then // do nothing
    else inherited; // continue as usual
end;

这个覆盖就是你所需要的,
ModalResult
s按钮和
Cancel
道具保持不变。

TreeView1.IsEditing bee是一个更好的检查吗?这有助于防止表单关闭,但是“Cancel”处理仍然会消耗ESC,所以现在按键什么也不做(用户希望取消他们的树节点编辑)保罗·扬:说得好。也许你需要像Wael建议的那样对其进行扩充?你应该将此作为功能请求提交给QC。我更新了代码,很抱歉我没有检查它。我使用了此代码,但我必须在你的if…else语句周围添加一个“if not TreeView.I编辑”复选框。你能更新你的anwser以包括这个,然后我可以接受它。此外,如果按钮后面没有逻辑,您可以只设置ModalResult而不调用CancelClick和OnClickthem@Jamie:像Wael Dalloul那样调用CancelClick和OkClick,而不是直接分配ModalResult,不是更健壮吗?如果您想稍后修改CancelClick怎么办?您是否意识到/记得您正在别处分配ModalResult?是的,但是如果您没有任何事件处理程序,那么您就没有什么可调用的了?也许打电话给TButton.Click会更好?这似乎和Mason Wheeler的回答有同样的问题。对话框不会关闭,但编辑也不会提交或回滚最好将ModalResult代码放入事件处理程序中,即使事件没有其他代码。如果以后需要添加到事件中,则更容易更新/查找。
// Ignore ESCAPE when TV is in edit mode
procedure TForm1.CMDialogKey(var Msg: TWMKey);
begin
  if (Msg.CharCode = VK_ESCAPE) and (KeyDataToShiftState(Msg.KeyData) = []) and
     (ActiveControl = tvTree) and tvTree.IsEditing
    then // do nothing
    else inherited; // continue as usual
end;