Jamie
Jamie

Reputation: 3172

How to stop a dialogs default and cancel behaviour when editing a TTreeView node

I have a dialog with a TTreeView control on it and an OK and Cancel button. The buttons have the Default and Canel properties set to true respectivly and the ModalResult has been set correctly.

The user is able to edit the captions of the tree nodes using the controls built in functionality.

If the user hits escape or enter while editing a tree node the dialog will disapper instead of just canceling or accepting the edit to the node caption.

In the case of escape, for example, I would expect to hit escape once to canel the edit of the caption and then hit escape a second time to cancel the dialog.

What is the best way to deal with this situation?

TMemo has the WantReturns property to deal with this but I can't see anything for TTreeView.

Upvotes: 5

Views: 2250

Answers (5)

Fr0sT
Fr0sT

Reputation: 3025

I think I found the most nice solution. A little bit of theory: buttn click on Escape press is launched in TButton.CMDialogKey which is called by TCustomForm.CMDialogKey via inherited method TWinControl.CMDialogKey that just calls WndProc of all its controls with the given message. So all we have to do is to override form's method:

// 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;

This override is all you need, ModalResults of buttons and Cancel props remain unchanged.

Upvotes: 1

Wael Dalloul
Wael Dalloul

Reputation: 22984

you should remove Default and Cancel properties from the buttons, instead you should case the key pressed on form keyDown and then perform OK or cancel.

Edit:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
if (Key = VK_ESCAPE)and not (TreeView1.IsEditing) then
  CancelClick(sender)
else
  if (Key = VK_RETURN) and not (TreeView1.IsEditing) then
    OkClick(sender);
end;

also you need to set keypreview to true.

Upvotes: 3

Mason Wheeler
Mason Wheeler

Reputation: 84540

What I'd do in this situation is add an OnCloseQuery event handler to the form that will keep it from closing if the TTreeView is the focused control.

Upvotes: 2

Uli Gerhardt
Uli Gerhardt

Reputation: 13991

Maybe it helps to temporarily set Default and Cancel to False in TTreeView.OnEditing and back to True in TTreeView.OnEdited. There's no OnCancelEdit - this might be a problem.

Upvotes: 1

Stijn Sanders
Stijn Sanders

Reputation: 36840

Don't set only the ModalResult property on OK and Cancel buttons, but create an OnClick event handler and use

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

or mrCancel respectively

Upvotes: 2

Related Questions