Delphi: показать назначенный кадр узлу древовидного представления

У меня нет опыта работы с рамками.

Как использовать Tree View с фреймами? Мне нужно переключаться между узлами древовидного представления и показывать назначенный кадр выбранному узлу.

Огромнейшее спасибо за помощь!!!


person maxfax    schedule 04.07.2011    source источник


Ответы (1)


На самом деле не имеет никакого значения, если Data узлов содержат указатель на фрейм или любой другой тип объекта, приведите указатель к типу объекта, который он содержит.

В приведенном ниже коде добавляются два фрейма ("Frame2" и "Frame3", созданные в среде IDE — очень похоже на новую форму) в качестве узлов TreeView, и задается для видимости фрейма выбранного узла значение true, а для невыбранного — значение false.

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    procedure FormCreate(Sender: TObject);
    procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
    procedure TreeView1Changing(Sender: TObject; Node: TTreeNode;
      var AllowChange: Boolean);
    procedure FormDestroy(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

uses Unit2, Unit3;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  TreeView1.Align := alLeft;

  with TFrame(TreeView1.Items.AddObject(nil, 'Frame2', TFrame2.Create(nil)).Data) do begin
    Visible := False;
    Parent := Self;
    Align := alClient;
  end;

  with TFrame(TreeView1.Items.AddObject(nil, 'Frame3', TFrame3.Create(nil)).Data) do begin
    Visible := False;
    Parent := Self;
    Align := alClient;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to TreeView1.Items.Count - 1 do
    TFrame(TreeView1.Items[i].Data).Free;
end;


procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
  TFrame(Node.Data).Visible := True;
end;

procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode;
  var AllowChange: Boolean);
begin
  if Assigned((Sender as TTreeView).Selected) then
    TFrame(TTreeView(Sender).Selected.Data).Visible := False;
end;
person Sertac Akyuz    schedule 05.07.2011
comment
Хорошо. Почему у меня возникают такие ошибки при переключении между узлами: исключение первого шанса на $766EB727. Класс исключения EAccessViolation с сообщением «Нарушение прав доступа по адресу 0049515B в модуле Project1.exe». Чтение адреса 00000059'. Процесс Project1.exe (3636)??? - person maxfax; 05.07.2011
comment
+1, код работает отлично. @maxfax, если это не работает для вас, уточните причину сбоя. Вы скопировали код или адаптировали его к вашей ситуации? Откуда вы получаете нарушение прав доступа? - person Cosmin Prund; 05.07.2011
comment
Да, я создал новый проект, добавил 2 фрейма (Frame2 и Frame3), добавил новые элементы в TreeView. У меня есть ошибки в TreeView1Change и TreeView1Changing. После выбора всех элементов ошибок нет, до этого - да. - person maxfax; 05.07.2011
comment
@maxfax, как вы добавили свои узлы в TreeView? Код Сертака добавляет их в FormCreate вместе со связанным TFrame. Если вы добавили узлы в TreeView каким-либо другим способом, связаны ли с ними кадры? - person Cosmin Prund; 05.07.2011
comment
как предотвратить эту ошибку, если добавить другие узлы без связанного TFrame? - person maxfax; 06.07.2011
comment
@maxfax - Если вы ничего не присвоили «Данным» узла, то эти «Данные» равны нулю. Таким образом, вы можете проверить, являются ли «Данные» «Назначенными», прежде чем приводить их к объекту: if Assigned(Node.Data) then TFrame(Node.Data)... - person Sertac Akyuz; 06.07.2011
comment
У меня уже есть 1 узел (не назначенный) и код при изменении: если назначен (узел.Данные), то TFrame(Узел.Данные).Видимость := Истина; и при изменении: если назначено ((Отправитель как TTreeView).Selected), то TFrame(TTreeView(Sender).Selected.Data).Visible:= False. И получаю ОШИБКУ! - person maxfax; 06.07.2011
comment
@maxfax — в событии «OnChanging», которое вы тестируете, если назначено «Selected», вы также должны проверить (когда назначено «Selected»), если назначено «Selected.Data»: if Assigned((Sender as TTreeView).Selected) and Assigned(TTreeView(Sender).Selected.Data) then - person Sertac Akyuz; 06.07.2011
comment
@maxfax - для более легкого разрешения этого типа AV поставьте точку останова там, где возникает исключение. Когда выполнение достигает точки останова, наведите указатель мыши на ссылки, т.е. сначала на правых скобках TTreeView(Sender), затем на Selected, затем на Data. Когда вы видите «ноль», вы знаете причину AV. - person Sertac Akyuz; 06.07.2011
comment
Спасибо! Последний вопрос - если я хочу создавать узлы во время разработки, как я могу назначить фреймы узлам? - person maxfax; 06.07.2011
comment
@maxfax - Вы можете назначить свой фрейм «Данным» любого узла во время выполнения: TreeView1.Items[1].Item[1].Data := MyFrame; Конечно, к тому времени должен быть создан экземпляр «MyFrame».. - person Sertac Akyuz; 06.07.2011