2006. november 13., hétfő

How to start a search upon an [Enter] key press in a TEdit


Problem/Question/Abstract:

I have a series of 6 edit boxes that users type info in that are then passed to params in my SQL TQuery. The search query is started by clicking on a button. However, users have asked that if they type in one of the edit boxes and then press 'Enter' that the system searches. I can use Key Press event to trigger it and then if key = #13 to make sure its the enter key but then i want it to trigger the procedure that does the search, usually triggered by the tool button. Any ideas?

Answer:

Solve 1:

The best solution is to use actions, which I'll describe below. But if you don't want to use actions, do this:

Move your search procedure into a separate procedure, and then call that from both the toolbutton OnClick and edit OnKeyPress events, like this:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ToolWin, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    procedure ToolButton1Click(Sender: TObject);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
  private
    {Private Declarations}
    procedure PerformSearch;
  public
    {Public declarations}
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ToolButton1Click(Sender: TObject);
begin
  PerformSearch;
end;

procedure TForm1.PerformSearch;
begin
  { Do search here }
  ShowMessage('Search performed');
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
  begin
    PerformSearch;
    Key := #0;
  end;
end;

end.

To use actions, place a TActionList component onto your form, then create an action called something like "SearchAction". Then assign SearchAction to the ToolButton's Action property. Finally, call the action's Execute method from the edit, like this:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ToolWin, StdCtrls, ActnList;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ActionList1: TActionList;
    SearchAction: TAction;
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure SearchActionExecute(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
  begin
    SearchAction.Execute;
    Key := #0;
  end;
end;

procedure TForm1.SearchActionExecute(Sender: TObject);
begin
  { Do search here }
  ShowMessage('Search performed');
end;

end.

Solve 2:

I'll go one further than Rick. All event handlers should only delegate (unless they're one line long in which case they are delegating). In other words if you have

procedure TForm1btnSearch.Click(Sender: TObject);
begin
  {...many lines of code that actually implement the search}
end;

Change this to:

procedure TForm1btnSearch.Click(Sender: TObject);
begin
  FindInformation;
end;

procedure TForm1.FindInformation;
begin
  {...many lines of code that actually implement the search.}
end;

There are, of course, exceptions to this rule, however, for the greater part, you will not do wrong to treat an event handler as a proxy rather than placing the code directly in it. For one thing, it makes it easier to move the domain code into a separate object, so you could end up with:

procedure TForm1btnSearch.Click(Sender: TObject);
begin
  MyInformationFinder.Execute;
end;

Nincsenek megjegyzések:

Megjegyzés küldése