Блог


Последние записи


Теги

Информация

Delphi, DevExpress, примеры, решения

Фильтр по тегу: filter


TcxTreeList - фильтрация

Фильтрация Nod`ов в TcxTreeList/TcxDBTreeList

У Datacontroller`а есть Filter, но можно использовать другой способ.
Скрывать/отображать узлы в цикле с помощью свойства TcxTreeListNode.Visible

Примеры
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  ANode: TcxTreeListNode;
begin
  for I := 0 to cxDBTreeList1.AbsoluteCount - 1 do
  begin
    ANode := cxDBTreeList1.AbsoluteItems[I];
    if ANode.Values[cxDBTreeList1FilterColumn.ItemIndex] = 2 then
      ANode.Visible := false;
  end;
end;


procedure TForm1.Button2Click(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to cxDBTreeList1.AbsoluteCount - 1 do
    cxDBTreeList1.AbsoluteItems[I].Visible := true;
end;
добавлено: 17 авг 13 просмотры: 2304, комментарии: 0



Высота FilterRow увеличивается вместе с высотой всех строк cxGrid

Как оставить высоту строки FilterRow прежней при изменении высоты строк DataRow?

Решение непростое, но оно есть:
http://www.devexpress.com/Support/Center/Question/Details/Q332062

I am afraid there is no simple way to accomplish this task. The only possible solution is to create a custom View and override its FilterRowViewInfo.GetHeight method.
добавлено: 23 июл 12 просмотры: 2189, комментарии: 0



Пройтись в цикле по видимым записям cxGrid с учетом фильтрации

Если cxGrid отфильтрован, то всё равно цикл, использующий DataController, будет видеть все записи, даже отфильтрованные.
А как пройтись по всем видимым записям с учетом фильтрации, не зависимо от того, что там выделено?

Вот примерно так:

var
i: integer;
bagin

    with <TcxGridTableView>.DataController do
      begin
        BeginUpdate;
        for I := 0 to FilteredRecordCount - 1 do
          ShowMessage(VarToStr(Values[FilteredRecordIndex[i], column1.Index]));




Советую ещё в справке прочесть про ForEachRow()
добавлено: 16 июл 12 просмотры: 3401, комментарии: 0



Фильтрация в cxGrid

Программная фильтрация cxGrid
  try
    <cxGridDBTableView>.DataController.Filter.Active := false;
    actResetFilterGroupSortExecute(nil);
    iMaxID := 120;
    <cxGridDBTableView>..DataController.Filter.BeginUpdate;
    WITH <cxGridDBTableView>.DataController.Filter.Root do begin
      Clear;
      AddItem(<TcxGridDBClolumn>, foGreater, iMaxID, 'фильтрпо значению: ' + IntToStr(iMaxID));
    end;
    <cxGridDBTableView>.DataController.Filter.Active := true;
  finally
    <cxGridDBTableView>.DataController.Filter.EndUpdate;
  end;

{чтобы добавить условие ИЛИ
<cxGridDBTableView>.DataController.Filter.Root.BoolOperatorKind := fboOr
}



Как отменить фильтр в cxGrid программно?
<cxGridDBTableView>.DataController.Filter.Clear;



Показывать все значения фильтра или только доступные.
Выпадающие списки фильтров в заголовках показывают по умолчанию все значения вне зависимости от текущей фильтрации. А как оставлять в списках только те значения, которые доступны на момент после фильтрации?
Или так. Установлен фильтр по одному столбцу. Когда требуется еще и по второму столбцу отфильтровать, надо, чтобы в выпадающем списке фильтра выводились бы лишь те значения, которые есть в отфильтрованном наборе, а не все. Всё просто.
cxGridDBTableView.DataController.Filter.AutoDataSetFilter := True;



Ещё один метод фильтрации - TcxGridDBDataController FilterRecord
http://www.devexpress.com/Support/Center/Question/Details/Q321574

uses
  cxGridDBDataDefinitions;


procedure TForm1.Button1Click(Sender: TObject);
begin
  tvCustomer.DataController.OnFilterRecord := tvCustomerDataControllerFilterRecord;
end;

procedure TForm1.tvCustomerDataControllerFilterRecord(
  ADataController: TcxCustomDataController; ARecordIndex: Integer;
  var Accept: Boolean);
var
 ADetailRecordsCount: Integer;
 ADetailDataController: TcxGridDBDataController;
begin
 ADetailDataController :=  ADataController.GetDetailDataController(ARecordIndex, 0) as TcxGridDBDataController;
 Accept := ADetailDataController.RecordCount > 10;
end;
добавлено: 13 июл 12 просмотры: 7516, комментарии: 0



Фильтр в cxLookupCombobox

2 варианта



Как сделать фильтрацию в TcxLookupCombobox?


Кроме стандартных для cxLookupCombobox свойств (ListSource, KeyFieldNames, ListFieldNames), нужно установить следующие значения:
<cxLookupCombobox>.Properties.DropDownListStyle  := lsEditList;
<cxLookupCombobox>.Properties.IncrementalFiltering := false;



Далее выполняем разделение строки на слова
// Разбивка строки по словам
procedure SplitDelimitedString(AStrings: TStrings; AText, ADelimiter: string);
var
  p, n: integer;
  Text: PChar;
begin
  Text := PChar(AText);
  AStrings.Clear;
  n := Length(ADelimiter);
  while Assigned(Text) do
  begin
    p := Pos(ADelimiter, Text) - 1;
    if p < 0 then
      Break;
    AStrings.Add(Copy(Text, 1, p));
    Inc(Text, p + n);
  end;
  if Assigned(Text) and (Length(Text) > 0) then
    AStrings.Add(Text);
end;



// Установка фильтра для полей lookup-а, с разбивкой по словам и полям
procedure ApplySearchFilter(Controller: TcxDBDataController; Fields: string; Text: string);
var
  i, j: integer;
  ItemLink: TObject;
  Filter: TcxDataFilterCriteria;
  FL: TcxFilterCriteriaItemList;
  FieldList, TextWords: TStrings;
begin
  TextWords := TStringList.Create;
  FieldList := TStringList.Create;
  try
    Filter := Controller.Filter;
    Filter.BeginUpdate;
    try
      Filter.Active := false;
      Filter.Clear;
      Filter.Options := Filter.Options + [fcoCaseInsensitive];
      Filter.Root.BoolOperatorKind := fboOr;
      SplitDelimitedString(FieldList, Fields, ';');
      SplitDelimitedString(TextWords, Text, ' ');
      for i := 0 to FieldList.Count - 1 do
        if FieldList[i] <> '' then
        begin
          FL := Filter.Root.AddItemList(fboAnd);
          ItemLink := Controller.GetItemByFieldName(FieldList[i]);
          if Assigned(ItemLink) then
            for j := 0 to TextWords.Count - 1 do
              if TextWords[j] <> '' then
                FL.AddItem(ItemLink, foLike, '%' + TextWords[j] + '%', TextWords[j]);
        end;
      Filter.Active := true;
    finally
      Filter.EndUpdate;
    end;
  finally
    TextWords.Free;
    FieldList.Free;
  end;
end;


// вызов
procedure TForm1.cxDBLookupComboBox1PropertiesChange(Sender: TObject);
var
  S: TcxDBLookupComboBox;
begin
  S := TcxDBLookupComboBox(Sender);
  ApplySearchFilter(S.Properties.DataController, S.Properties.ListFieldNames, S.Text);

  // для тестирования
  Label1.Caption := S.Properties.DataController.Filter.FilterText;
end;





Второй вариант
А ещё можно сделать связку cxGridViewRepository (TcxGridDBTableView) + TcxExtLookupCombobox и получить в выпадающем списке полноценную сетку - cxGridDBTableView
добавлено: 13 июл 12 просмотры: 2960, комментарии: 0



cxLookupCombobox - Установка фильтра для полей по словам

Установка фильтра для полей lookup-а, с разбивкой по словам и полям

procedure ApplySearchFilter(Controller:  TcxDBDataController; Fields: string; Text: string);
var
  i, j: Integer;
  ItemLink: TObject;
  Filter: TcxDataFilterCriteria;
  FL: TcxFilterCriteriaItemList;
  FieldList, TextWords: TStrings;
begin
  TextWords := TStringList.Create;
  FieldList := TStringList.Create;
  try
    Filter := Controller.Filter;
    Filter.BeginUpdate;
    try
      Filter.Active := false;
      Filter.Clear;
      Filter.Options := Filter.Options + ;
      Filter.Root.BoolOperatorKind := fboOr;
      SplitDelimitedString(FieldList, Fields, ';');
      SplitDelimitedString(TextWords, Text, ' ');
      for i := 0 to FieldList.Count - 1 do
        if FieldList <> '' then
        begin
          FL := Filter.Root.AddItemList(fboAnd);
          ItemLink := Controller.GetItemByFieldName(FieldList);
          if Assigned(ItemLink) then
            for j := 0 to TextWords.Count - 1 do
              if TextWords <> '' then
                FL.AddItem(ItemLink, foLike, '%' + TextWords + '%', TextWords);
        end;
      Filter.Active := true;
    finally
      Filter.EndUpdate;
    end;
  finally
    TextWords.Free;
    FieldList.Free;
  end;
end;



// Разбивка строки по словам
procedure SplitDelimitedString(AStrings: TStrings; AText, ADelimiter: string); var
  p, n: Integer;
  Text: PChar;
begin
  Text := PChar(AText);
  AStrings.Clear;
  n := Length(ADelimiter);
  while Assigned(Text) do
  begin
    p := Pos(ADelimiter, Text) - 1;
    if p < 0 then
      Break;
    AStrings.Add(Copy(Text, 1, p));
    Inc(Text, p + n);
  end;
  if Assigned(Text) and (Length(Text) > 0) then
    AStrings.Add(Text);
end;
добавлено: 12 июл 12 просмотры: 1323, комментарии: 2