views:

44

answers:

1

Is there a way to access the text entered in a Devart (Core Lab) TCRDBGrid search bar?

I tried implementing the OnKeyDown event but the event didn't happen during entry in the search fields, only when the grid itself was selected. There are no other events that look relevant.

The text appears to go into a TEdit which is part of a TCRGridTitleEdit, which is part of TCRDBGrid but is private.

Is there a way to get the search text?

Example TCFGBGrid:

+---------+------------+
| UserId  |  UserName  | <- Column titles
+---------+------------+
|[987654] | [        ] | <- Search bar (searching for UserId 987654)
+---------+------------+
| 123456  |  Wile Cau  | <- Data
+---------+------------+
|   ...   |    ...     | <- More data

If UserId 987654 doesn't exist, I want to prompt something like "Create new user 987654?" and potentially create a new record with UserId set to 987654.

+3  A: 

TCRDBGrid is distributed with source code. You can modify source code:

declare the event type:

  TOnTextChanged = procedure (Sender: TObject; Text: string) of object;

add event declaration in the TCRGridTitleEdit class:

private 
    FOnFilterChanged: TOnTextChanged;
    FOnSearchChanged: TOnTextChanged;

public
    property OnFilterChanged: TOnTextChanged read FOnFilterChanged write FOnFilterChanged;
    property OnSearchChanged: TOnTextChanged read FOnSearchChanged write FOnSearchChanged;

call this event in the ProcessEdit procedure:

procedure TCRGridTitleEdit.ProcessEdit;
begin
  if (FActiveColumn = nil) or (CRDBGrid = nil) or not FEdit.Modified then
    Exit;

  if FAsFilter then
    with CRDBGrid do begin
      try
        TCRColumn(FActiveColumn).GetFilterExpression(FEdit.Text);
        FFilterExpressions[FActiveColumn.Index] := FEdit.Text;
        Self.Caption := FFilterExpressions[FActiveColumn.Index];
        if Assigned(FOnFilterChanged) then
          FOnFilterChanged(self, FEdit.Text);
      except
        on EConvertError do begin
          FEdit.SelectAll;
          raise;
        end;
      end;
    end
  else
    try
      with FActiveColumn.Field do
        DataSet.Locate(FieldName, {$IFDEF CLR}Variant{$ENDIF}(FEdit.Text), [loCaseInsensitive,loPartialKey]);
      if Assigned(FOnSearchChanged) then
        FOnSearchChanged(self, FEdit.Text);
    except
      on EConvertError do
        Exit;
    end;
end;

and add event declaration in the TCRDBGrid class:

private
  function GetOnFilterChanged: TOnTextChanged;
  procedure SetOnFilterChanged(Value: TOnTextChanged);
  function GetOnSearchChanged: TOnTextChanged;
  procedure SetOnSearchChanged(Value: TOnTextChanged);

published
  property OnFilterChanged: TOnTextChanged read GetOnFilterChanged write SetOnFilterChanged;
  property OnSearchChanged: TOnTextChanged read GetOnSearchChanged write SetOnSearchChanged;

implementation

function TCRDBGrid.GetOnFilterChanged: TOnTextChanged;
begin
  Result := CRGridTitleEdit.OnFilterChanged;
end;

procedure TCRDBGrid.SetOnFilterChanged(Value: TOnTextChanged);
begin
  CRGridTitleEdit.OnFilterChanged := Value;
end;

function TCRDBGrid.GetOnSearchChanged: TOnTextChanged;
begin
  Result := CRGridTitleEdit.OnSearchChanged;
end;

procedure TCRDBGrid.SetOnSearchChanged(Value: TOnTextChanged);
begin
  CRGridTitleEdit.OnSearchChanged := Value;
end;
bork
@bork, thank you for including the code in your reply, much appreciated :)
WileCau