Блог


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


Теги

Информация

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

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


Программно открыть или закрыть TcxPopupEdit в TcxVerticalGrid

В cxVerticalGrid может быть строка, где Properties.EditProperties := PopupEdit
Как можно закрыть или открыть программно выпадающее окно.


procedure VerticalGridDropDownRow(vg: TcxVerticalGrid; aRow: TcxEditorRow; aDropedDown: boolean);
Var
  AEdit: TcxPopupEdit;
begin
  vg.SetFocus;
  vg.FocusedRow := aRow;
  vg.ShowEdit;
  if (vg.InplaceEditor <> nil) and (vg.InplaceEditor is TcxPopupEdit) then
  begin
    AEdit := TcxPopupEdit(vg.InplaceEditor);
    AEdit.DroppedDown := False;
  end;
end;


У TcxPopupEditProperties отсутствует метод или свойство, позволяющее открыть/закрыть Popup control.
Popup подразумевает работу только с ним. Нельзя открывать несколько Popup`ов одновременно. При потере фокуса Popup должен закрыться.
добавлено: 25 окт 16 просмотры: 2181, комментарии: 0



Выбор значения в cxExtLookupComboBox по щелчку (одинарный клик)

Есть TcxExtLookupComboBox, к которому привязан cxGrid из репозитория.
У cxExtLookupComboBox есть свойство FocusPopup типа boolean.
cxExtLookupComboBox1.Properties.FocusPopup := False;


Это свойство отвечает за то, что именно будет сфокусировано при выпадании списка: cxExtLookupComboBox или встроенный cxGridDBTableView? И от этого зависит, как будет происходить выбор нужной строки с помощью мышки: одним кликом или двумя. Если FocusPopup включен, то будет сфокусирован грид и выбор можно произвести двойным щелчком или клавишей Enter. Если FocusPopup отключен (False), то выбор можно произвести одним щелчком мышки.
добавлено: 20 июн 13 просмотры: 1501, комментарии: 0



Организация выпадающего дерева с помощью cxPopupEdit + cxDBTreeList

Как сделать так, чтобы в combobox`е было дерево с переключателями (CheckBox)?

Действующие лица: TcxPopupEdit и TcxDBTreeList.

В cxDBTreeList требуется включить отображение переключателей (<TcxTreeList>.OptionsView.CheckGroups). К сожалению, переключатели сами по себе не отобразятся, поэтому потребуется пройтись в цикле по всем узлам и принудительно показать CheckBox`ы (CheckGroupType или ncgRadioGroup), а также указать их состояния (cbsChecked, cbsUnChecked или cbsGrayed).

На форме панель или cxTabControl, на которой лежит дерево cxDBTreeList.
Также на cxTabControl лежит 4 кнопки: развернуть всё, свернуть всё, ОК и Отмена.

В настройках TcxPopupEdit выбираем в свойстве PopupControl наш заранее подготовленный cxTabControl с деревом и кнопками.

Дерево (cxDBTreeList) подключаем к НД (Набору Данных, DataSet`у). Создаём нужные колонки. Настраиваем дерево.
Панель или cxTabControl во время исполнения программы будет автоматически скрыто, невидимо, поэтому дополнительных телодвижений выполнять не нужно.

В базе, в каком-то спец. поле хранится список ID Через запятую. Тех узлов, которые отметил пользователь.

Как отобразить CheckGroups и указать состояние переключателей узлов дерева?

Подготавливаем дерево и отображаем чекбоксы:
Procedure PrepeareTree(Tree: TcxDBTreeList; ARootValue: Variant; const ASmartLoad: boolean; bChecks: boolean = true);
Var
 vNode:  TcxTreeListNode;
begin
  if tree = nil then
  begin
    MessageBox(constMsgErrorImportTree1, constError, MB_ICONSTOP or MB_OK);//показываем ошибку
    exit;
  end;

  if tree.DataController.DataSource = nil then
  begin
    MessageBox(constMsgErrorImportTree2, constError, MB_ICONSTOP or MB_OK);//показываем ошибку
    exit;
  end;

  try
    tree.DataController.BeginUpdate;//чтобы шибче работало

    //если нужна загрузка таблицы типов, то  НД нужно переоткрыть с нужным RootValue
    if ASmartLoad then// см. справку по ASmartLoad - это для загрузки, начиная с нужного нам узла, чтобы не грузить всё дерево
    begin
      if tree.DataController.DataSet.Active then
        tree.DataController.DataSet.Close;

      tree.RootValue              := ARootValue;//ID начальной записи из таблицы, будем грузить дочерние записи толького этого узла
      tree.OptionsData.SmartLoad  := ASmartLoad;//включить загрузку только указанного узла в RootValue
    end;//if ASmartLoad then


   if not tree.DataController.DataSet.Active then
     tree.DataController.DataSet.open;

    vNode := tree.Root;//получаем корневой узел

    //показываем чекбоксы или скрываем их
    if bChecks then
      while vNode <> nil do
      begin
        vNode.CheckGroupType := ncgCheckGroup;
        vNode.CheckState := cbsUnChecked;
        vNode := vNode.GetNext;//след. узел
      end;//while

  finally
    tree.FullCollapse;//сворачиваем все узлы
    tree.DataController.EndUpdate;//
  end;
end;


Теперь требуется пробежаться по всем узлам и отметить флажками нужные узлы.
Procedure SetCheckedNodes(Tree: TcxDBTreeList; const sRegionsIdList: string; iKeyCol: Integer);
Var
 sl: TStringList;
 i: integer;
begin
// в списоке передаём ID узлов через запятую, нужно отметить флажками нужные узлы

  sl := TStringList.Create;
  try
    if not Tree.DataController.DataSource.DataSet.Active then Tree.DataController.DataSource.DataSet.Open;
    Tree.BeginUpdate;//чтобы работало шибче

    if sRegionsIdList = '' then Exit;// не удалось получить корневой узел - выходим их процедуры
    sl.Text := StringReplace(sRegionsIdList, ',', sLineBreak, [rfReplaceAll]);// заменяем список через зяпятую

    for I := 0 to tree.AbsoluteCount - 1 do
      if not VarIsNull(Tree.AbsoluteItems[i].Values[iKeyCol]) then
        if IdInStringList(sl, Tree.AbsoluteItems[i].Values[iKeyCol]) then//если текущий узел в списке отмеченных ID
          Tree.AbsoluteItems[i].CheckState := cbsChecked;//отмечаем узел флажком

  finally
    Tree.EndUpdate;// отпускаем
    FreeAndNil(sl);
  end;
end;


// проверка, существует ли ID узла в списке
function IdInStringList(const StringList: TStringList; const ID: string): boolean;
var
 i: integer;
begin
  result := false;
  i := 0;

  repeat
    if id = StringList[i] then
    begin
      result := true;
      Break;
    end;
    inc(i);

  until (StringList.Count <= i);
end;



На панели, рядом с деревом лежит кнопка Отмена. При нажатии закрываем дерево
procedure ClosePopupEdit(ParentControl: TWinControl);
Var
  PopupWnd: TcxPopupEditPopupWindow;
begin
  PopupWnd := TcxPopupEditPopupWindow(ParentControl);
  PopupWnd.ClosePopup();

//если дерево привязано к гриду, то нужно выйти из режима редактирования
  <cxVerticalGrid1>.HideEdit();
end;


При нажатии на кнопка "Развернуть всё" и "Свернуть всё":
<Tree>.FullExpand и <Tree>.FullCollapse соответственно.



Теперь следует, при нажатии на кнопку "ОК", сохранить отмеченные узлы в некий список через запятую, показать, что отметил пользователь, и сохранить список в базу:

type
type

  TRecCheckedNodes = record//здесь будет ID и название узла
   id_list, name_list: string;
  end;
...
...
...

procedure btnSelect();
var
 RecCheckedNodes: TRecCheckedNodes;
begin
  with dbTreeRegion do
  begin
    if TcxDBTreeListNode(FocusedNode) = nil then exit;//если пользователь всё же ничего не отметил

    if IsCheckedNodes(dbTreeRegion) then//если есть хоть один отмеченный узел
    begin
      RecCheckedNodes := GetCheckedNodes(dbTreeRegion, false);//что отметил пользователь, получаем имя узла и его ID
      sRegionsIdList  := RecCheckedNodes.id_list;//список отмеченных ID через запятую для записи в базу

      //colRegion - строка таблицы, в ней пользователь видит, что отмечено
      colRegion.Properties.Value := RecCheckedNodes.name_list;//список отмеченных названий показываем пользователю
      colRegion.Properties.Hint := RecCheckedNodes.name_list;
    end;
  end;//with

//tcRegions - TcxTabControl, на котором лежит дерево с кнопками
  ClosePopupEdit(tcRegions.Parent, cxVerticalGrid1);//скрываем дерево и прячем редактор
end;


Function IsCheckedNodes(Tree: TcxDBTreeList): Boolean;
Var
 vNode:  TcxTreeListNode;
begin
//проверяем, есть ли хоть один отмеченный флажок
  Result := false;
  vNode := tree.Root;
  while vNode <> nil do
    begin
      if vNode.CheckState = cbsChecked then
        begin
          //есть, даже нет смысла проверять, выходим
          result := true;
          exit;
        end//if
      else
        vNode := vNode.GetNext;
    end;//While
end;


//получаем список ID и названий узлов

Function GetCheckedNodes(Tree: TcxDBTreeList; iKeyCol, iNameCol: integer; bAddBraces: boolean = true): TRecCheckedNodes;
var
 i: Integer;
begin
  result.id_list := '';
  result.name_list := '';

  for I := 0 to Tree.AbsoluteCount - 1 do
  begin
    if Tree.AbsoluteItems[i].CheckState = cbsChecked then
    begin
    //записываем в строку через запятую названия и ID узлов, названия отобразим пользователю, и список ID запишем в базу
      if result.id_list = '' then
        result.id_list := VarToStr(Tree.AbsoluteItems[i].Values[iKeyCol])
      else
        result.id_list := result.id_list + ',' + VarToStr(Tree.AbsoluteItems[i].Values[iKeyCol]);

      if result.name_list = '' then
        result.name_list := VarToStr(Tree.AbsoluteItems[i].Values[iNameCol])
      else
        result.name_list := result.name_list + ',' + VarToStr(Tree.AbsoluteItems[i].Values[iNameCol]);

    end;//if
  end;// for

  //если требуется обрамить список скобками - (1,129,328,1577,21,7)
  if (result.id_list <> '') and bAddBraces then
    result.id_list := '(' + result.id_list + ')';// возращаем все значения через запятую, в скобках, чтобы можно было легко вставить с SQL запрос, в условие where pole1 in(.....)
end;
добавлено: 20 мар 13 просмотры: 3689, комментарии: 0