[Info] Filtering TRichViewEdit column of ExpressQuantumGrid

Demos, code samples. Only questions related to the existing topics are allowed here.
Post Reply
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

[Info] Filtering TRichViewEdit column of ExpressQuantumGrid

Post by Sergey Tkachenko »

This topic shows how to implement filtering in TRichViewEdit column of TcxGrid (a grid VCL control by DevExpress).

Let's take the demo in DevExpress\VCL\Demos\ExpressQuantumGrid\Delphi\FilterDemo as a base.

At the first step, we change the type of "Product" column to TRichViewEdit, and value type to Markdown.
In the Object Inspector, we select TableViewProduct.Properties = "TRichViewEdit", and set TableViewProduct.Properties.EditValueSaveFormat = cxrvvfUnicodeMarkdown.
Also, we set TableView.OptionsView.CellAutoHeight = True.

TRichView in TcxGrid.png
TRichView in TcxGrid.png (32.3 KiB) Viewed 6799 times

Now we have "Product" column displayed and edited using TRichViewEdit. Initially, values are stored as plain text, but if you edit some value, it will be saved back as Markdown.

The demo does not have user interface for formatting text, but you can paste text from another rich text editor (such as our RichViewActions demo, or WordPad, or Microsoft Word)

You can see the filter "Express*" (that is created in code), and it works for plain text values. But if you paste a formatted text in some row, like "ExpressFlowChart", it will not match.
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Filtering by display text. Filter created in code. How to activate filtering

Post by Sergey Tkachenko »

The filter is not matched because the grid compares the filter string not with the display text, but with the raw value. In our case, with Markdown code.
How to match a filter with a display text instead of a raw value?
We need to assign

Code: Select all

  TableView.DataController.Filter.CompareByDisplayValues := True;
This property is public, not published, so we assign it in code, in TfrmMain.FormCreate.


You can see, the filter works now:

TRichView in TcxGrid - Filter by display text.png
TRichView in TcxGrid - Filter by display text.png (30.86 KiB) Viewed 6794 times

However, we only started making progress. Actually, filtering is not enabled in TRichViewEdit columns by default, and only a filter created by code works.
You can see:
  • there is no a filter icon in "Product" header
  • the filter string is in the filter row (the top grid row) is read-only
  • if you click the filter customization button ("Customize", bottom right corner), you will not see the condition for "Product".
To enable filtering, assign TableViewProduct.Properties.AllowFilteriing = True.

Why is it not enabled by default?
Because it makes sense to use TRichViewEdit for non-plain-text date, and it should be filtered by display text, and it requires Filter.CompareByDisplayValues := True.
But this setting affects the whole grid, not only our column. It may cause problems with filtering other, non-text, columns
(I think this is the reason why CompareByDisplayValues is not published, and why a built-in DevExpress rich edit column does not implement filtering).

Nevertheless, let's proceed.
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Filter Builder dialog

Post by Sergey Tkachenko »

Now we can modify the filter in the Filter Builder dialog:

Filter Builder.png
Filter Builder.png (5.41 KiB) Viewed 6782 times

And it works for Markdown data:

Filter Builder - Applied.png
Filter Builder - Applied.png (16.41 KiB) Viewed 6782 times
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Custom Filter dialog

Post by Sergey Tkachenko »

Let's try another dialog: Custom filter.
To display it, we need to remove a date-related condition (to make a filter simpler), to click on the filter icon in "Product" header, and select the "(Custom...)" item.

CustomFilter.png
CustomFilter.png (3.02 KiB) Viewed 6782 times
And it works for Markdown data:

CustomFilter - Applied.png
CustomFilter - Applied.png (30.05 KiB) Viewed 6782 times
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Filtering using check list box

Post by Sergey Tkachenko »

Let's try to check items in the list that is shown when you click a filter icon.
You can see two "ExpressFlowChart" items. Let's check one of them:

CheckListBox.png
CheckListBox.png (23.81 KiB) Viewed 6763 times

Oops. Nothing is matched.

It happens because CompareByDisplayValues setting does not affect content of this list box.
As a result:
  • you can see two "ExpressFlowChart" in the list; they have the same display string, but different raw values (one is Markdown, another one is a plain text)
  • the grid compares the raw value of the item (Markdown) with the display text of data, and they are not equal.
I think this is a flaw of CompareByDisplayValues implementation in the grid.

But there is a workaround: we can use OnGetFilterValues event for our column to update values of items in this list: to make raw values equal to their display text, and to remove possible duplicates.
To do it, we can use UpdateFilterValues procedure from the new cxTRichViewFilter.pas unit:

Code: Select all

uses 
  cxTRichViewFilter;

procedure TfrmMain.TableViewProductGetFilterValues(
  Sender: TcxCustomGridTableItem; AValueList: TcxDataFilterValueList);
begin
  UpdateFilterValues(AValueList,
    fcoCaseInsensitive in TableView.DataController.Filter.Options);
end;
We did it!

CheckListBox - Fixed.png
CheckListBox - Fixed.png (28.35 KiB) Viewed 6763 times
CheckListBox - Result.png
CheckListBox - Result.png (19.32 KiB) Viewed 6763 times
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Filter row

Post by Sergey Tkachenko »

And the last problem is a filtering row (an optional top row in the grid where you can enter filter values).
If you try to type something above the product values, nothing is matched the updated filter string.

The reason is similar to the problem with the check list items. The grid creates TRichViewEdit to type the filter condition, and compares its raw data (Markdown in our case) with display text of data. One more problem with CompareByDisplayValues implementation!

Fortunately, OnGetProperties event can help us: we can create a plain text editor for filtering row of our column.

Let's add cxTextEdit in uses, and FilterProps field to our form:

Code: Select all

    FilterProps: TcxTextEditProperties;
The code for OnGetProperties is

Code: Select all

procedure TfrmMain.TableViewProductGetProperties(Sender: TcxCustomGridTableItem;
  ARecord: TcxCustomGridRecord; var AProperties: TcxCustomEditProperties);
begin
  if (ARecord is TcxGridFilterRow) and (AProperties is TcxRVProperties) then
  begin
    if FilterProps = nil then
    begin
      FilterProps := TcxTextEditProperties.Create(nil);
      FilterProps.Assign(AProperties);
    end;
    AProperties := FilterProps;
  end;
end;
We can destroy FilterProps when the form is freed:

Code: Select all

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  inherited;
  FilterProps.Free;
end;
Result:

Filter row.png
Filter row.png (21.37 KiB) Viewed 6757 times
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Sorting

Post by Sergey Tkachenko »

That's all about filtering. This information can be found (in a compact form) in the comments at the beginning of cxTRichViewFilter.pas.

PS: by the way, you can see one more new feature: sorting.
Unlike filtering, it just works. TRichViewEdit columns are sorted by display text (by default).
Sort.png
Sort.png (31.02 KiB) Viewed 6748 times
Post Reply