VirtualStringTree - встраивание элементов управления в ячейки - элемент управления не отображается - PullRequest
6 голосов
/ 28 декабря 2011

Итак, моя конечная игра здесь - это иметь способ перечислять элементы (например, TListView в vsReport) с помощью кнопок добавления / удаления в клиентской области.

Ex:

|----------------|
|Old Item 1    X |
|Old Item 2    X |
|Add new item... |
|                |
|----------------|

Если вам известен компонент, который делает это без всей этой дополнительной работы, пожалуйста, дайте мне знать!

Итак, я выбрал красный закрывающий «X» и использую TJvTransparentButton (Jedi Components - JVCL) для его отображения. Он обрабатывает состояния нажатия / отсутствия нажатия и показывает только изображение. Первоначально я использовал TButton, но мне не нужен был весь пух, который идет вокруг глифа.

Теперь я сохраняю кнопку изображения в записи, связанной с каждым узлом.

Код выглядит следующим образом:

procedure TfrmMain.AddNewAccount(const Username, Password: String);
var
  Data : PTreeData;
  XNode : PVirtualNode;
Begin
  XNode := vstAccounts.AddChild(nil);
  If vstAccounts.AbsoluteIndex(XNode) > -1 Then
    begin
    Data := vstAccounts.GetNodeData(Xnode);
    Data^.Column0 := Username;
    Data^.Column1 := '';
    Data^.DeleteButton := TJvTransparentButton.Create(nil);
    With Data^.DeleteButton Do
      begin
      Parent := vstAccounts;
      Left := 0;
      Top := 0;
      Width := 16;
      Height := 16;
      Anchors := [];
      AutoGray := False;
      BorderWidth := 0;
      FrameStyle := fsNone;
      Images.ActiveImage := iListView;
      Images.ActiveIndex := 0;
    end;
  end;
end;

В событии OnAfterCellPaint я управляю позиционированием кнопки изображения следующим образом:

procedure TfrmMain.vstAccountsAfterCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellRect: TRect);
var
  Data : PTreeData;
begin
  If Column = 1 Then
    begin
    Data := vstAccounts.GetNodeData(Node);
    If Assigned(Data) Then
      begin
      With Data^.DeleteButton Do
        begin
        BoundsRect := CellRect;
      end;
    end;
  end;
end;

Теперь проблема в том, что этот элемент вообще не отображается. Я знаю, что изображение из TImageList в порядке, потому что я могу создать кнопку во время разработки, и она отлично выглядит во время выполнения.

Я также знаю, что этот код должен работать, потому что, если я сделаю TJvTransparentButton обычным TButton (без изменения логики кода), он будет работать просто отлично и будет отображаться нормально!

Единственное, о чем я могу думать, это то, что TButton наследует от TWinControl, а TJvTransparentButton наследует от TControl.

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 28 декабря 2011

Вы делаете это неправильно. Вы должны написать свой собственный редактор для TVirtualStringTree, который реализует интерфейс IVTEditLink. Затем в OnCreateEditor событии вам нужно создать свой редактор:

procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
begin
  EditLink:=TStringEditLink.Create;
end;

Вы можете получить больше информации здесь .

3 голосов
/ 28 декабря 2011

Я предполагаю, что TJvTransparentButton является TGraphicControl и, как таковой, отображается как часть фона Родителя (поэтому Tlabel всегда будет находиться за TEdit или TButton в одном и том же Родителе). TButton - это TWinControl, поэтому он нарисован поверх Родителя и выше или ниже других WinControls в том же Родителе.

Итак, либо вы снова рисуете себя TJvTransparentButton после регулярного рисования ячейки (обновление BoundsRect недостаточно), либо используете WinControl.
Например, использование TPanel с TJvTransparentButton должно работать.

Отказ от ответственности: я не знаком ни с VirtualStringTree, ни с TJvTransparentButton ...

...