How to do a programed search and highligth found words in cxGrid?
Thank you !
HB
Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Basically, you can use an incremental search functionality which can be enabled via the View’s OptionsBehavior.IncSearch property (see the ExpressQuantumGrid “TcxCustomGridTableOptionsBehavior.IncSearch” help topic). You can use this feature in code as it is shown in the “TcxCustomGridTableController.IncSearchingText” help topic and its example. To adjust the style of the highlighted text, please try the View’s Styles.IncSearch property. I also suggest that you review our knowledge base article “How to adjust the grid so that an end-user can use the incremental search feature for any column” at <http://www.devexpress.com/kb1676>. I hope this will help you.
Thank you !
It did dnot work on RichEdit field in grid … should it ???
Best regards
HB
Here is a snippet from the Express DataController’s “TcxDataControllerSearch Object” help topic:
Note: some controls do not support incremental searching performed via the TcxDataControllerSearch object due to complex data representation structures. An example of such a control is a tree list. This control provides its own methods that enable programmatic incremental searching.
As for TcxRichEdit control, it does not support this feature as well. The TcxRichEdit supports own searching methods. The code below shows how you can find a proper text within the TcxRichEdit via its FindText function and highlight it.
var
FoundPos: integer;
begin
FoundPos := cxRichEdit1.FindText('Text', 0, Length(cxRichEdit1.Text), [stMatchCase]);
if not (FoundPos < 0) then
begin
cxRichEdit1.SelStart := FoundPos;
cxRichEdit1.SelLength := Length('Text');
SendMessage(cxRichEdit1.InnerControl.Handle,EM_SCROLLCARET, 0, 0);
end;
end;
Thank you for example of using FindText but please also show how to do this when RichEdit is in a cxGrid ?
Thank you!
HB
In the Grid, the in-place editor is created when you invoke the cell’s editing. To implement the text search within TcxRichEdit column, you should iterate the View rows, open the in-place editor for a proper column and find the text within the editor as shown in the code below. The main idea is that View’s Controller.EditingController.Edit property represents the TcxRichEdit control.
var
I, FoundPos: integer;
AColumn : TcxGridDBColumn;
AText : String;
begin
AText := 'Blue Sports';
with cxGrid1DBTableView1 do
begin
AColumn := GetColumnByFieldName('Company');
for I := 0 to ViewData.RecordCount - 1 do
if ViewData.Rows[I].IsData then
begin
ViewData.Rows[I].Focused := True;
with Controller.EditingController do
begin
ShowEdit(AColumn);
FoundPos := TcxRichEdit(Edit).FindText(AText, 0, Length(TcxRichEdit(Edit).Text), [stMatchCase]);
if not (FoundPos < 0) then
begin
TcxRichEdit(Edit).SelStart := FoundPos;
TcxRichEdit(Edit).SelLength := Length( AText);
SendMessage(TcxRichEdit(Edit).InnerControl.Handle,EM_SCROLLCARET, 0, 0);
Break;
end
else
AColumn.Editing := False;
end;
end;
end;
end;
Thank you !
I get following error when trying to compile your example:
[Error] KK_A_U1.pas(23581): Incompatible types: 'TSearchType' and 'TRichSearchType'
Line 23581:
FoundPos := TcxRichEdit(Edit).FindText(AText, 0, Length(TcxRichEdit(Edit).Text), [stMatchCase]);
Best regards
HB
Hello!
The missing type is declared in the ComCtrls.pas unit. Please try to add the “uses ComCtrls;” clause to your code and let us know your results. I hope this will help you.
ComCtrls .pas
unit ComCtrls;
…
TSearchType = (stWholeWord, stMatchCase);
Thank you !
ComCtrls already in uses…
Just replaced stMatchCase with [] but then got acces violation rturning this:
function TcxCustomRichEdit.GetInnerRich: TcxRichInnerEdit;
begin
Result := TcxRichInnerEdit(InnerControl);
Best regards
HB
end;
Sorry, I have failed to replicate the problem using Quantum Grid 5.12 under Delphi7. Attached is a sample project specially created to test this problem. It works fine for me, please run it on your machine and let us know your results. Please also specify which Delphi you are using and its exact Build number? Or could you please attach your sample project?
Thank you !
Your sample runs fine, but when doing exactly the same mine give same access violation as before!
Anny suggestion on a efficient way on finding the reason for this?
Actually customer want all found words highlighted like Google?
(I already have done a filter so all rows have at least one matching word).
Thank you !
HB
Please post here a sample project which demonstrates this issue, we will investigate it and try to resolve this problem. Or could you please attach a call stack of your app? I am looking forward to hearing from you.
Thank you !
Here is the call stack:
TcxCustomRichEdit.GetInnerRich
TcxCustomRichEdit.FindText('È^K'#3'šN@'#0'§kùwˆø'#$12#0'Lþ'#$12#0'¤ø'#$12#0'`ø'#$12#0' ̃û'#$12#
TForm1.VisText('KANIN','Komentar')
TForm1.D_SeekBClick($25966B0)
Best regards
HB
For now, we cannot diagnose this problem. What is the text you try to find within cxRichEdit and how do you transmit it in to the FindText? Sorry, but I have to ask you to send a sample project to us again. I am looking forward to hearing from you.
Thank you!
Please fin the code I use bellow, I do not understand why the string seems to be corrupted when reurned by findtext, code is from you example where it runs fine with same modification.
Customer want every found word in posibly several rows to be higlighted could I use CustomDrawCell and the change font color for found word.
(Its read only)
Thank you!
HB
Procedure TForm1.VisText(Finn,FN : String);
var
I, FoundPos : integer;
AColumn : TcxGridDBColumn;
// AText : String;
begin
// AText := Trim(Finn);
// ShowMessage(AText);
// with KKLoggGDBTableView1 do
with cxGridDBTableView1 do
begin
AColumn := GetColumnByFieldName(FN);
for I := 0 to ViewData.RecordCount - 1 do
if ViewData.Rows[I].IsData then
begin
ViewData.Rows[I].Focused := True;
with Controller.EditingController do
begin
ShowEdit(AColumn);
FoundPos := TcxRichEdit(Edit).FindText(Finn, 0, Length(TcxRichEdit(Edit).Text), []);
if not (FoundPos < 0) then
begin
TcxRichEdit(Edit).SelStart := FoundPos;
TcxRichEdit(Edit).SelLength := Length( Finn);
SendMessage(TcxRichEdit(Edit).InnerControl.Handle,EM_SCROLLCARET, 0, 0);
Break;
end
else
AColumn.Editing := False;
end;
end;
end;
end;
As for your problem, I assume that you apply our code for the column with its Options.Editing set to False whereas the cell’s editor should be activated when using the RichEdit’s FindText. As for the several rows to be highlighted, you can implement it via the OnCustomDrawCell event handler as described in our knowledge base article "How to color a Grid cell at runtime", http://www.devexpress.com/kb55. But it is a complicated task to highlight several words using these event handlers. I suggest that you try to restrict editing via the View’s OnEditing event handler and its AAllow var-parameter. This will allow to restrict editing for users and allow it when implementing the search within editor. To highlight several words which were found, you can use the following approach.
Once the word was found, you should set the proper background color and continue the search from the end of found word.
To change the background color, you can use the Win32 API functions as our TcxRichEdit is based on the TRichEdit from the standard Delphi VCL. See the sample code below. InGrid the RichEdit column’s Properties.PlainText should be True. We do not support formatted text within a View at this time.
uses ComCtrls,RichEdit;
…
I, FoundPos: integer;
AColumn : TcxGridDBColumn;
AText : String;
Format: CHARFORMAT2;
begin
…
FoundPos := TcxRichEdit(Edit).FindText(AText, 0, Length(TcxRichEdit(Edit).Text), [stMatchCase]);
if not (FoundPos < 0) then
begin
TcxRichEdit(Edit).SelStart := FoundPos;
TcxRichEdit(Edit).SelLength := Length( AText);
SendMessage(TcxRichEdit(Edit).InnerControl.Handle,EM_SCROLLCARET, 0, 0);
// Here is code for the approach
FillChar(Format, SizeOf(Format), 0);
with Format do
begin
cbSize := SizeOf(Format);
dwMask := CFM_BACKCOLOR;
crBackColor := clYellow; //<<<<<<<define background color
TcxRichEdit(Edit).InnerControl.Perform(EM_SETCHARFORMAT, SCF_SELECTION, Longint(@Format));
end;
…
end;
…
end;
After highlighting the first word, you can try to search another word. The main idea is to use the FindText’s StartPos parameter set to FoundPos + Length(AText), the Length parameter should be also corrected.
FoundPos := TcxRichEdit(Edit).FindText(AText, FoundPos + Length(AText), Length(TcxRichEdit(Edit).Text)- FoundPos , [stMatchCase]);
If FoundPos differ from -1, we can highlight the next founded word again.
In common, your task can be completed as follows.
1) Determine the records in which the RichEdit’s column contains proper text.
2) Highlight the cells via appropriate color using the OnGetContentStyle or OnCustomDrawCell event handlers.
3) If a user wishes to see the words, you can activate the editor and show them as described above.
I hope this will help you.