Difference between revisions of "VirtualTreeview Example for Lazarus/ru"
Line 173: | Line 173: | ||
[[Image:ExempleVirtualtreeView4.jpg|center]] | [[Image:ExempleVirtualtreeView4.jpg|center]] | ||
− | 27. | + | 27. Попробуйте отредактировать узел. Выберите узел и нажмите F2, напишите новое значение. Если вы видите, что напечатали, тогда все в порядке. Иначе, читайте ниже: [[VirtualTreeview_Example_for_Lazarus/ru#Если правки ячейки не отображаются|Если правки ячейки не отображаются]]. |
− | Попробуйте отредактировать узел. Выберите узел и нажмите F2, напишите новое значение. Если вы видите, что напечатали, тогда все в порядке. Иначе, читайте ниже: | ||
28. To get VST show the new value entered after editing, go to the Form Designer, select VST. On Object Inspector -> Events -> OnNewText combobox double click. Paste the following: | 28. To get VST show the new value entered after editing, go to the Form Designer, select VST. On Object Inspector -> Events -> OnNewText combobox double click. Paste the following: | ||
+ | Чтобы отображалось полученное VST новое значение, введенное после редактирования, перейдите в конструктор форм, выберите VST. В инспекторе объектов [дважды кликаем] по комбобоксу OnNewText на вкладке Events. Вставляем следующее: | ||
<syntaxhighlight>procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; | <syntaxhighlight>procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; | ||
Column: TColumnIndex; NewText: WideString); | Column: TColumnIndex; NewText: WideString); | ||
Line 190: | Line 190: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | + | Пока что пример базового использования заканчивается здесь. Вы можете бросить [еще] несколько кнопок на форму, чтобы проверить несколько команд, приведенных ниже. Далее будут показаны [работы с] checkbox'ом, изображением, цветом шрифта и добавлением combobox'а на узле. | |
− | + | *Другой способ добавления корневого узла | |
− | * | ||
<syntaxhighlight>procedure TForm1.Button8Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button8Click(Sender: TObject); | ||
begin | begin | ||
Line 200: | Line 199: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Другой способ добавления дочернего узла |
<syntaxhighlight>procedure TForm1.Button9Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button9Click(Sender: TObject); | ||
begin | begin | ||
Line 207: | Line 206: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Определение и удаление потомков узла |
<syntaxhighlight>procedure TForm1.Button4Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button4Click(Sender: TObject); | ||
var | var | ||
Line 222: | Line 221: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Удаление узла |
<syntaxhighlight>procedure TForm1.Button5Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button5Click(Sender: TObject); | ||
begin | begin | ||
− | {VST.Clear; // | + | {VST.Clear; //Удаляет все узлы} |
if not Assigned(VST.FocusedNode) then | if not Assigned(VST.FocusedNode) then | ||
Exit; | Exit; | ||
Line 231: | Line 230: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Поиск и выделение узла |
<syntaxhighlight>procedure TForm1.Button6Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button6Click(Sender: TObject); | ||
bar | bar | ||
Line 253: | Line 252: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Определение родителя |
<syntaxhighlight>procedure TForm1.Button13Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button13Click(Sender: TObject); | ||
var | var | ||
Line 270: | Line 269: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Поиск всего |
<syntaxhighlight>procedure TForm1.Button7Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button7Click(Sender: TObject); | ||
var | var | ||
Line 292: | Line 291: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Поиск следующего |
<syntaxhighlight>procedure TForm1.Button8Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button8Click(Sender: TObject); | ||
var | var | ||
Line 320: | Line 319: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Вставка узла |
<syntaxhighlight>procedure TForm1.Button12Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button12Click(Sender: TObject); | ||
var | var | ||
Line 334: | Line 333: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Установка высоты узла |
<syntaxhighlight>procedure TForm1.Button14Click(Sender: TObject); | <syntaxhighlight>procedure TForm1.Button14Click(Sender: TObject); | ||
begin | begin | ||
Line 341: | Line 340: | ||
end;</syntaxhighlight> | end;</syntaxhighlight> | ||
− | * | + | *Сохранение и загрузка |
− | + | Простое дерево (без столбцов) можно сохранить и загрузить как: | |
<syntaxhighlight>VST.SaveToFile('filename.dat'); | <syntaxhighlight>VST.SaveToFile('filename.dat'); | ||
VST.LoadFromFile('filename.dat');</syntaxhighlight> | VST.LoadFromFile('filename.dat');</syntaxhighlight> |
Revision as of 16:32, 14 November 2018
│
English (en) │
español (es) │
français (fr) │
polski (pl) │
русский (ru) │
ENG: AT THE MOMENT THIS PAGE IS UNDER TRANSLATION.
RUS: В НАСТОЯЩИЙ МОМЕНТ СТРАНИЦА НАХОДИТСЯ В ПРОЦЕССЕ ПЕРЕВОДА.
Вот несколько примеров того, как использовать VirtualTreeview для Lazarus (проверено на win32). Они в основном собираются из Интернета, написанного для Delphi, и из учебника/документов Philipp Frenzel и Mike Lischke.
Учебник / документы можно загрузить с http://www.soft-gems.net. Ниже кто-либо найдет только быстрый способ использовать VirtualTreeview на Lazarus, а не объяснения. Для пояснения и множества других функций/методов, получите официальные документы и учебник.
Основной список дерева с тремя столбцами
1. Установите компонент. Запустите lazarus.
2. Бросьте [на форму] компонент TVirtualStringTree (вкладка Virtual Controls).
3. Перейдите в редактор исходного кода (нажмите F12). В разделе Uses добавьте модуль - VirtualTrees (если она еще не существует, и это не VirtualStringTree). Это может выглядеть так:
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
VirtualStringTree, VirtualTrees;
4. Войдите в конструктор форм (нажмите F12). Выберите компонент Virtual Tree. В Инспекторе объектов нажмите Name, введите VST и нажмите enter. Кликните на заголовок (разверните его) -> Columns, нажмите маленькую кнопку рядом с "0 items". Нажмите 3 раза кнопку Add, чтобы добавить 3 столбца. Не закрывайте это окно.
5. В окне редактирования столбца теперь выбирается третий столбец. Войдите в Инспектор объектов. Кликните Options (разверните его) -> установите для параметра coAllowClick значение False.
6. Нажмите на Text. Введите Column2.
7. Нажмите Width, введите 100 и нажмите enter.
8. Перейдите в окно редактирования столбцов, выберите 1-й и 2-й столбцы и установите их свойство, как указано выше (для текстового поля используйте разные имена, то есть Column0, Column1).
9. Закройте окно редактирования столбцов. Выберите компонент Virtual Tree в форме. В Object Inspector перейдите к Header -> Options ([раскройте спиcок]). Установите значение hoVisible в значение True.
10. Прокрутите вниз до Style, чтобы установить его в hsFlatButtons.
11. Прокрутите вниз до TreeOptions (раскройте) -> MiscOption (раскройте), установите toEditable в значение True. Установите toGridExtensions в значение True.
12. Прокрутите вниз до пункта SelectionOptions(раскройте) -> установите toExtendedFocus в значение True. Установите toMultiSelect в значение True. В конструкторе форм измените размер VST (Virtual Tree Component) так, чтобы получить представление обо всех столбцах, если необходимо.
13. Теперь добавьте 3 кнопки на форму. Получите их из палитры компонентов - вкладка Standard (ярлык "OK").
14. Нажмите кнопку Button1, изменив в Object Inspector [ее свойство] Caption на AddRoot. Нажмите кнопку Button2, измените заголовок на AddChild. Измените заголовок Button3 на Delete.
15. Сохраните это и перейдите в редактор исходного кода (нажмите F12). В редакторе исходного кода замените строку:
{$mode objfpc}{$H+}
на
{$MODE DELPHI}
16. В разделе "implementation" вставьте следующие строки:
type
PTreeData = ^TTreeData;
TTreeData = record
Column0: String;
Column1: String;
Column2: String;
end;
17. Войдите в конструктор форм (нажмите F12). Выберите VST. Перейдите к Object Inspector, выберите вкладку Events, прокрутите вниз до onChange. Дважды щелкните значок со списком. Вставьте следующие данные:
procedure TForm1.VSTChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
VST.Refresh;
end;
18. Прокрутите до onFocusChanged. Дважды щелкните и вставьте следующее:
procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex);
begin
VST.Refresh;
end;
19. Прокрутите до onFreeNode. Дважды щелкните и вставьте следующее:
procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
Data: PTreeData;
begin
Data := VST.GetNodeData(Node);
if Assigned(Data) then begin
Data^.Column0 := '';
Data^.Column1 := '';
Data^.Column2 := '';
end;
end;
20. Прокрутите вниз до onFreeNode. Дважды кликните и вставьте следующее:
procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin
NodeDataSize := SizeOf(TTreeData);
end;
21. Прокрутите вниз до onGetText. Дважды кликните и вставьте следующее:
procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
Data: PTreeData;
begin
Data := VST.GetNodeData(Node);
case Column of
0: CellText := Data^.Column0;
1: CellText := Data^.Column1;
2: CellText := Data^.Column2;
end;
end;
22. Нажмите F12 для перехода дизайнер форм. Дважды кликните кнопку AddRoot. Вставьте следующее:
procedure TForm1.Button1Click(Sender: TObject);
var
Data: PTreeData;
XNode: PVirtualNode;
Rand: Integer;
begin
Randomize;
Rand := Random(99);
XNode := VST.AddChild(nil);
if VST.AbsoluteIndex(XNode) > -1 then
begin
Data := VST.GetNodeData(Xnode);
Data^.Column0 := 'One ' + IntToStr(Rand);
Data^.Column1 := 'Two ' + IntToStr(Rand + 10);
Data^.Column2 := 'Three ' + IntToStr(Rand - 10);
end;
end;
23. Нажмите F9 для запуска проекта с целью проверки. Нажмите AddRoot, чтобы добавить узел. Если все нормально, узел будет добавлен в VST.
24. Прервите выполнение. В конструкторе форм кликните дважды кнопку с надписью AddChild. Вставьте следующее:
procedure TForm1.Button2Click(Sender: TObject);
var
XNode: PVirtualNode;
Data: PTreeData;
begin
if not Assigned(VST.FocusedNode) then
Exit;
XNode := VST.AddChild(VST.FocusedNode);
Data := VST.GetNodeData(Xnode);
Data^.Column0 := 'Ch 1';
Data^.Column1 := 'Ch 2';
Data^.Column2 := 'Ch 3';
VST.Expanded[VST.FocusedNode] := True;
end;
25. В конструкторе форм дважды нажмите кнопку Delete. Вставьте следующее:
procedure TForm1.Button3Click(Sender: TObject);
begin
VST.DeleteSelectedNodes;
end;
26. Запустите проект, нажав F9 для проверки. Добавьте узел, дочерний элемент и удалите их.
27. Попробуйте отредактировать узел. Выберите узел и нажмите F2, напишите новое значение. Если вы видите, что напечатали, тогда все в порядке. Иначе, читайте ниже: Если правки ячейки не отображаются.
28. To get VST show the new value entered after editing, go to the Form Designer, select VST. On Object Inspector -> Events -> OnNewText combobox double click. Paste the following: Чтобы отображалось полученное VST новое значение, введенное после редактирования, перейдите в конструктор форм, выберите VST. В инспекторе объектов [дважды кликаем] по комбобоксу OnNewText на вкладке Events. Вставляем следующее:
procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; NewText: WideString);
var
Data: PTreeData;
begin
Data := VST.GetNodeData(Node);
case Column of
0: Data^.Column0 := NewText;
1: Data^.Column1 := NewText;
2: Data^.Column2 := NewText;
end;
end;
Пока что пример базового использования заканчивается здесь. Вы можете бросить [еще] несколько кнопок на форму, чтобы проверить несколько команд, приведенных ниже. Далее будут показаны [работы с] checkbox'ом, изображением, цветом шрифта и добавлением combobox'а на узле.
- Другой способ добавления корневого узла
procedure TForm1.Button8Click(Sender: TObject);
begin
with VST do
RootNodeCount := RootNodeCount + 1;
end;
- Другой способ добавления дочернего узла
procedure TForm1.Button9Click(Sender: TObject);
begin
if Assigned(VST.FocusedNode) then
VST.ChildCount[VST.FocusedNode] := VST.ChildCount[VST.FocusedNode] + 1;
end;
- Определение и удаление потомков узла
procedure TForm1.Button4Click(Sender: TObject);
var
c: Integer;
begin
if not Assigned(VST.FocusedNode) then
Exit;
if VST.HasChildren[VST.FocusedNode] then
begin
c := VST.ChildCount[VST.FocusedNode];
VST.DeleteChildren(VST.FocusedNode);
ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c));
end;
end;
- Удаление узла
procedure TForm1.Button5Click(Sender: TObject);
begin
{VST.Clear; //Удаляет все узлы}
if not Assigned(VST.FocusedNode) then
Exit;
VST.DeleteNode(VST.FocusedNode);
end;
- Поиск и выделение узла
procedure TForm1.Button6Click(Sender: TObject);
bar
XNode: PVirtualNode;
Data: PTreeData;
begin
XNode := VST.GetFirst;
while XNode <> nil do
begin
Data := VST.GetNodeData(XNode);
if Data^.Column0 = '1' then
begin
VST.ClearSelection;
VST.Selected[XNode] := True;
VST.SetFocus;
break;
end else
XNode := VST.GetNextSibling(XNode);
end;
end;
- Определение родителя
procedure TForm1.Button13Click(Sender: TObject);
var
XNode: PVirtualNode;
begin
if not Assigned(VST.FocusedNode) then
Exit;
XNode := VST.FocusedNode;
while VST.GetNodeLevel(XNode) > 0 do
begin
XNode := XNode.Parent;
VST.Selected[XNode] := True;
end;
VST.Refresh;
VST.SetFocus;
end;
- Поиск всего
procedure TForm1.Button7Click(Sender: TObject);
var
XNode: PVirtualNode;
Data: PTreeData;
begin
if VST.GetFirst = nil then Exit;
XNode := nil;
repeat
if XNode = nil then
XNode := VST.GetFirst
else
XNode := VST.GetNext(XNode);
Data := VST.GetNodeData(XNode);
if (Data^.Column0 = '1') or (Data^.Column1 = '1') or (Data^.Column2 = '1') then
begin
ShowMessage('Found at Node Level : ' + IntToStr(VST.GetNodeLevel(XNode)));
break;
end;
until XNode = VST.GetLast();
end;
- Поиск следующего
procedure TForm1.Button8Click(Sender: TObject);
var
XNode: PVirtualNode;
Data: PTreeData;
begin
if not Assigned(VST.GetFirst) then
Exit
else
XNode := VST.GetFirst;
repeat
XNode := VST.GetNext(XNode);
Data := VST.GetNodeData(XNode);
if Pos(LowerCase(SearchEdit.Text), LowerCase(Data^.Column0)) > 0 then
begin
VST.FocusedNode := XNode;
VST.Selected[XNode] := True;
if MessageDlg('Item found?', mtConfirmation, mbYesNo, 0) = mrYes then
begin
VST.Expanded[XNode] := True;
VST.Refresh;
VST.SetFocus;
Break;
end;
end;
until XNode = VST.GetLast;
end;
- Вставка узла
procedure TForm1.Button12Click(Sender: TObject);
var
XNode: PVirtualNode;
begin
if Assigned(VST.FocusedNode) then
begin
XNode := VST.InsertNode(VST.FocusedNode,amInsertBefore);
// To Insert After Selected Node.
{XNode := VST.InsertNode(VST.FocusedNode,amInsertAfter);}
VST.Refresh;
end;
end;
- Установка высоты узла
procedure TForm1.Button14Click(Sender: TObject);
begin
if Assigned(VST.FocusedNode) then
VST.NodeHeight[VST.FocusedNode] := 32;
end;
- Сохранение и загрузка
Простое дерево (без столбцов) можно сохранить и загрузить как:
VST.SaveToFile('filename.dat');
VST.LoadFromFile('filename.dat');
To save and load the above mentioned example, place 2 buttons on the form, rename caption to "Save" and "Load". Select VST, on Object Inspector -> TreeOptions -> StringOptions make sure toSaveCaptions is set to True. Go to Object Inspector's Events tab. Scroll down to OnLoadNode, double click and then paste:
procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
Stream: TStream);
var
Data: PTreeData;
Len: Integer;
begin
Data := VST.GetNodeData(Node);
Stream.read(Len, SizeOf(Len));
SetLength(Data^.Column0, Len);
Stream.read(PChar(Data^.Column0)^, Len);
Stream.read(Len, SizeOf(Len));
SetLength(Data^.Column1, Len);
Stream.read(PChar(Data^.Column1)^, Len);
Stream.read(Len, SizeOf(Len));
SetLength(Data^.Column2, Len);
Stream.read(PChar(Data^.Column2)^, Len);
end;
Again on Object Inspector's Events tab - scroll down to OnSaveNode, double click and then paste:
procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
Stream: TStream);
var
Data: PTreeData;
Len: Integer;
begin
Data := VST.GetNodeData(Node);
Len := Length(Data^.Column0);
Stream.write(Len, SizeOf(Len));
Stream.write(PChar(Data^.Column0)^, Len);
Len := Length(Data^.Column1);
Stream.write(Len, SizeOf(Len));
Stream.write(PChar(Data^.Column1)^, Len);
Len := Length(Data^.Column2);
Stream.write(Len, SizeOf(Len));
Stream.write(PChar(Data^.Column2)^, Len);
end;
On Form Designer double click Save captioned button, paste:
procedure TForm1.Button10Click(Sender: TObject);
begin
VST.SaveToFile('C:\vst.dat');
end;
On Form Designer double click Load captioned button, paste:
procedure TForm1.Button11Click(Sender: TObject);
begin
VST.LoadFromFile('C:\vst.dat');
end;
Now test to save and load tree.
- Scroll Problem
The header of the treeview disappears fully or partially when scrolling. I could not find a good solution for this. One way to overcome this is to set the header height to 0, then using general label for columns. This is good while there are few columns, and all are visible without horizontal scrolling. Or, the header height can be set to a higher value like 25 or 30. VST.Refresh can be added to the OnScroll event.
- Column Resize
It was not possible to resize column by dragging mouse on VST header. May be it is for the header bug or I have missed something. If it is for the header, probably will be fixed on next version of Lazarus. See this link: http://bugs.freepascal.org/view.php?id=11209
Anyway, it is possible to resize column from code. When you press down right mouse button and move mouse-wheel up, the width of the selected column increases and press down the right mouse button and move mouse-wheel down, to decrease the width of the selected column. To do this:
1. Add a variable in the source editor named as CurCol: Integer; So it looks like:
var
Form1: TForm1;
CurCol: Integer; // <- Add this line only.
implementation
{ TForm1 }
2. On the Form Designer double click the form to generate an event OnCreate. Inside the OnCreate procedure type Form1.OnMouseWheelUp:= and press Ctrl+Shift+C, this will complete the code and make skeleton of the MouseWheelUp event. Now get back to procedure TForm1.FormCreate(Sender: TObject); And add another event for MouseWheelDown. Type Form1.OnMouseWheelDown:= and press Ctrl+Shift+C, to generate the MouseWheelDown event. FormCreate procedure now looks like:
procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.OnMouseWheelUp := @Form1MouseWheelUp;
Form1.OnMouseWheelDown := @Form1MouseWheelDown;
end;
3. Fill the TForm1.Form1MouseWheelUp procedure as:
procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
if VST.Focused and (ssRight in Shift) then
VST.Header.Columns[CurCol].Width := VST.Header.Columns[CurCol].Width + 10;
end;
4. Fill the TForm1.Form1MouseWheelDown procedure as:
procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean);
begin
if VST.Focused and (ssRight in Shift) then
VST.Header.Columns[CurCol].Width := VST.Header.Columns[CurCol].Width - 10;
end;
5. Go to the Form Designer (press F12), select VST, on Object Inspector's Events tab scroll to OnFocusChanged, double click & paste:
procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex);
begin
CurCol := Column;
end;
When you run, click on a column then hold down right mouse button and move wheel up to increase width, wheel down to decrease. You may tune-up the above procedures if needed. Or, add keyboard event with something like "if (key=187) and (ssShift in Shift) then" to watch for Shift + "+".
Checkbox
On Form Designer select VST. Go to:
- Object Inspector -> Properties -> CheckImageKind and select ckDarkCheck.
- Object Inspector -> Properties -> TreeOptions -> MiscOptions -> toCheckSupport and set it to True.
Now switch to Events tab.
- Scroll to OnInitNode. Double click and paste the followings:
procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode,
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var
Level: Integer;
begin
Level := VST.GetNodeLevel(Node);
if Level = 0 then
Node.CheckType := ctCheckBox;
if Level = 2 then
Node.CheckType := ctRadioButton;
if Level = 1 then
begin
Node.CheckType := ctTriStateCheckBox;
Node.CheckState := csCheckedNormal;
end;
if Level = 3 then
Node.CheckType := ctButton;
end;
Run the program, add rootnode and child then child of the child, and check if you can check and uncheck properly. If not, close the program. Go to the Object Inspector's Events tab.
- Scroll to OnChecked, double click and paste:
procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
VST.Refresh;
end;
- Scroll to OnChecking, double click and paste:
procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode;
var NewState: TCheckState; var Allowed: Boolean);
begin
VST.Refresh;
end;
Hope now it is ok. To determine checkbox state use like:
if XNode.CheckState = csCheckedNormal then
ShowMessage('Checked.');
Other states are:
csUncheckedNormal = unchecked and not pressed
csUncheckedPressed = unchecked and pressed
csCheckedNormal = checked and not pressed
csCheckedPressed = checked and pressed
csMixedNormal = 3-state check box and not pressed
csMixedPressed = 3-state check box and pressed
Other types are:
ctNone
ctTriStateCheckBox
ctCheckBox
ctRadioButton
ctButton
- To Catch Checkbox's Button (ctButton) Click
Go to Object Inspector's Events tab. Scroll to OnChecked, double click and paste:
procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
if Node.CheckType = ctButton then
ShowMessage('Ok.');
VST.Refresh;
end;
End of checkbox.
Images
To show image on VST nodes, a list of image should be created.
- Go to the Component Palette -> Common Controls. Select and drop a TImageList component on the form. Right click on the component icon and select ImageList Editor. Click on Add button and and select some images (at least 3 for now), then click on tick button to accept and close the ImageList Editor. By the way, there are some nice images you can download from http://www.famfamfam.com/lab/icons/silk/
- Now on the Form Designer select VST, and on Object Inspector's Properties tab, scroll to Images and select ImageList1
- On Object Inspector's Events tab scroll to OnGetImageIndex, double click and paste:
procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean;
var ImageIndex: Integer);
begin
if Kind in [ikNormal , ikSelected] then // Either Selected or not
begin
if Column = 0 then // if 1st Column
ImageIndex := 0; // 1st Image of the ImageList1
if Column = 1 then // if 2nd Column
ImageIndex := 1; // 2nd Image of the ImageList1
if Sender.FocusedNode = Node then // Only show if Focused
if Column = 2 then // if 3rd Column
ImageIndex := 2; // 3rd Image of the ImageList1
end;
{Sender.NodeHeight[node] := 40; //If Image is big}
end;
Font Colour
On the Form Designer select VST, and on Object Inspector's Events tab, scroll to OnPaintText, double click and paste:
procedure TForm1.VSTPaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType);
var
Data: PTreeData;
begin
Data := VST.GetNodeData(Node);
if Data^.Column0 = 'sky' then
TargetCanvas.Font.Color := clBlue;
if Column = 1 then
begin
TargetCanvas.Font.Color := clRed;
TargetCanvas.Font.Style := Font.Style + [fsItalic];
end;
if Column = 2 then
begin
// ImageList1.Draw(Form1.Canvas, -1, -1, 2); {draw top left of form, 3rd image of ImageList1??}
TargetCanvas.Font.Size := 9;
TargetCanvas.Font.Color := clHighlightText;
end;
end;
Adding A Combobox
- I guess you have an open project on Lazarus IDE having VST on it and can edit the nodes. If not see the "Basic Tree Listview With 3 Columns" above, and atleast complete steps 1 to 21.
- Below there is an unit file named combo. Copy that unit and save as combo.pas inside the project directory. Under your program's uses clause add combo. So it may look like:
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
VirtualStringTree, VirtualTrees, combo;
- The combo.pas unit
unit combo;
{$mode delphi}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
VirtualStringTree, VirtualTrees, messages, windows, StdCtrls;
type
TStringEditLink = class(TInterfacedObject, IVTEditLink)
private
FEdit: TWinControl;
FTree: TVirtualStringTree;
FNode: PVirtualNode;
FColumn: Integer;
protected
procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
public
destructor Destroy; override;
function BeginEdit: Boolean; stdcall;
function CancelEdit: Boolean; stdcall;
function EndEdit: Boolean; stdcall;
function GetBounds: TRect; stdcall;
function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
procedure ProcessMessage(var Message: TMessage); stdcall;
procedure SetBounds(R: TRect); stdcall;
end;
implementation
destructor TStringEditLink.Destroy;
begin
FEdit.Free;
inherited;
end;
procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
case Key of
VK_ESCAPE:
begin
FTree.CancelEditNode;
Key := 0;
FTree.setfocus;
end;
VK_RETURN:
begin
PostMessage(FTree.Handle, WM_KEYDOWN, VK_DOWN, 0);
Key := 0;
FTree.EndEditNode;
FTree.setfocus;
end;
end; //case
end;
function TStringEditLink.BeginEdit: Boolean;
begin
Result := True;
//FEdit.Height := (FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo
FEdit.Show;
TComboBox(FEdit).DroppedDown := True;
FEdit.SetFocus;
end;
function TStringEditLink.CancelEdit: Boolean;
begin
Result := True;
FEdit.Hide;
end;
function TStringEditLink.EndEdit: Boolean;
var
s: String;
begin
Result := True;
s := TComboBox(FEdit).Text;
FTree.Text[FNode, FColumn] := s;
FTree.InvalidateNode(FNode);
FEdit.Hide;
FTree.SetFocus;
end;
function TStringEditLink.GetBounds: TRect;
begin
Result := FEdit.BoundsRect;
end;
function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
begin
Result := True;
FTree := Tree as TVirtualStringTree;
FNode := Node;
FColumn := Column;
FEdit.Free;
FEdit := nil;
FEdit := TComboBox.Create(nil);
with FEdit as TComboBox do
begin
Visible := False;
Parent := Tree;
Items.Add('Google');
Items.Add('Yahoo');
Items.Add('Altavista');
OnKeyDown := EditKeyDown;
end;
end;
procedure TStringEditLink.ProcessMessage(var Message: TMessage);
begin
FEdit.WindowProc(Message);
end;
procedure TStringEditLink.SetBounds(R: TRect);
var
Dummy: Integer;
begin
FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
FEdit.BoundsRect := R;
end;
end.
- After saving the file, on the Form Designer select VST and on Object Inspector's Properties, scroll to TreeOptions -> MiscOptions, set toEditable to True. Then get to TreeOptions -> SelectionOptions, set toExtendedFocus to True.
- Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste:
procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
begin
EditLink := TStringEditLink.Create;
end;
- On Object Inspector's Events tab. Scroll to OnNewText, double click and paste:
procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; NewText: WideString);
var
Data: PTreeData;
begin
Data := VST.GetNodeData(Node);
case Column of
0: Data^.Column0 := NewText;
1: Data^.Column1 := NewText;
2: Data^.Column2 := NewText;
end;
end;
Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node.
Если правки ячейки не отображаются
Open VirtualStringTree.pas unit file (if you are still on the above example project, right click on VirtualStringTree under Uses clause and select Find Declaration. This opens the file on next tab. Go to that file's tab.). Get to the "function TStringEditLink.BeginEdit: Boolean; stdcall;". It looks like:
function TStringEditLink.BeginEdit: Boolean; stdcall;
// Notifies the edit link that editing can start now. Descentants may cancel node edit
// by returning False.
begin
Result := not FStopping;
if Result then
begin
FEdit.Show;
FEdit.SelectAll;
FEdit.SetFocus;
end;
end;
Now add "FEdit.Height:=18;". It should look like:
function TStringEditLink.BeginEdit: Boolean; stdcall;
// Notifies the edit link that editing can start now. Descentants may cancel node edit
// by returning False.
begin
Result := not FStopping;
if Result then
begin
FEdit.Show;
FEdit.SelectAll;
FEdit.SetFocus;
FEdit.Height := 18; // <--- Added this line.
end;
end;
Save the file (press Ctrl + S). If you are on the example project, close this (Project -> Close Project). Click on Tools -> Configure "Build Lazarus" ... Select Clean Up + Build All and then click on the Build button. After compile Lazarus should be restarted. Now open the example project and try to edit node on VST. This time it should be ok.
External links
- [1] - Virtual Treeview tutorials/docs
- Programando en Pascal - Spanish tutorial focused on FPC/Lazarus, hosted in Wikibooks.