Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.12.12;
Скачать: [xml.tar.bz2];

Вниз

работа с treeview   Найти похожие ветки 

 
123456   (2010-09-20 14:10) [0]

Здравствуйте!
имеется дерево с узлами и подузлами, которое через определенный интервал времени(с помощью таймера) обновляется из базы. после обновления все узлы сворачиваются. как сохранить текущее состояние дерево, чтоб она оставалась без изменении. при обновлении дерево формируется с нуля. просто неудобно, когда рассматриваешь какой-то под узел и тут сразу обновляется и все сворачиваются, приходится все заново раскрывать.


 
Ega23 ©   (2010-09-20 14:27) [1]

Писал в своё время DBTreeView.
Сразу замечание: Не надо обновлять по таймеру. Обновлять нужно по желанию пользователя, т.е. должна быть кнопка "Обновить".

Ну а с разворачиванием-сворачиванием всё просто: запоминаешь ID открытого элемента (не Node.ID, а ID из базы).
После перестроения дерева обходишь ноды, ищешь нужный по последнему ID, ставишь его Selected. Всё что "выше" - должно само раскрыться.


 
linuxoid   (2010-09-20 14:36) [2]

вот исходник: вначале раскрываются родительские parentid=0. затем по цепочке и подузлы.
а где написать процедуру запоминания и раскрытия? придется по базе перебрать все узлы до обновления?

subjecttree.Items.BeginUpdate;
if subjecttree.Items.Count >0 then
begin
 subjecttree.Items.Clear
 end;
 basequery.Active:=false;
 basequery.SQL.Clear;
 basequery.SQL.Text:="select *"+
 "from node where parentid=:parentid";
 basequery.Parameters.ParseSQL(basequery.SQL.Text,true);
basequery.Parameters.ParamByName("parentid").Value:=0;
 try
   baseconnect.Open;
   basequery.Active:=true;

   if basequery.RecordCount<>0 then
   begin
     while not basequery.Eof do
       begin
         TreeNode:=subjecttree.Items.AddObject(nil, basequery.Fields[2].asstring,
         pointer(basequery.Fields[0].asinteger));
         subjecttree.Items.AddChildObject(TreeNode ,"" , nil);
         TreeNode.ImageIndex:=strtoint(basequery.Fields.Fields[3].asstring);
         treenode.SelectedIndex:=treenode.ImageIndex;
         basequery.Next;
       end;
     end; //if

   finally
     BaseConnect.Close; //Закрываем коннект
   end;
 SubjectTree.Items.EndUpdate; //Разрешить прорисовку

begin
 BaseQuery.Active := false;
 BaseQuery.SQL.Clear;
 //Составление запроса и ввод параметров
 //Выбираем элементы не имеющие родителя, т.е. корневые
 BaseQuery.SQL.Text := "SELECT NodeID, ParentID, NodeName, NodeType "+
                           "FROM node WHERE ParentID = :ParentID";
 BaseQuery.Parameters.ParseSQL(BaseQuery.SQL.Text, true);
 BaseQuery.Parameters.ParamByName("ParentID").Value := Integer(tn.Data);
 BaseQuery.Active := true;

 if BaseQuery.RecordCount <> 0 then
     begin
       while not BaseQuery.Eof do
       begin
         TreeNode := SubjectTree.Items.AddChildObject(tn,
                         BaseQuery.Fields[2].AsString,
                         Pointer(BaseQuery.Fields[0].AsInteger));
         TreeNode.ImageIndex:=strtoint(basequery.Fields.Fields[3].asstring);
          treenode.SelectedIndex:=treenode.ImageIndex;
         BaseQuery.Next;
       end;  //while

       Child := tn.getFirstChild;
       while Child <> nil do
         begin
             FillBranch(Child);
           Child := Child.GetNextSibling;
         end;//while

     end; //if
end; {FillBranch}


 
Ega23 ©   (2010-09-20 14:42) [3]


> а где написать процедуру запоминания и раскрытия?


Поясняю.
Если абстрагироваться от конкретных реализаций, то схема работы DB-Aware-компонентов примерно такова:
1. Сделали запрос к хранилищу данных, получили некий набор данных.
2. Перевели полученный набор данных в некую унифицированную структуру (например - в список рекордов)
3. На пользовательском компоненте отобразили видимую в данный момент часть данных.
4. Связали каждый элемент своего контрола (строчка в DBGrid, узел в TreeView и т.д.) с конкретным элементом в своей унифицированной структуре.


 
Ega23 ©   (2010-09-20 14:47) [4]

В случае TreeView нельзя никогда заранее предугадать, какой элемент будет отображён в качестве корня. Поэтому построение дерева возможно только в том случае, когда на клиент получен ВЕСЬ НД, целиком. Есть возможность задания всяких Order By, но это не совсем верно в идеологическом плане (ИМХО).

Далее. В случае дерева у тебя нет никакой гарантии того, что данные в хранилище не изменились. Т.е. даже если ты запомнишь всю "карту" раскрытых узлов, то нет никакой гарантии, что у какого-то узла не поменялся "родитель".
Поэтому, ИМХО, хранить полную карту - бессмысленно. Проще сохранять последний SelectedNodeID, после обновления НД ставить его Selected и раскрывать всё вверх до корня (ЕМНИП, в случае TTreeView это произойдёт автоматом).


 
linuxoid   (2010-09-20 15:02) [5]

можно ли по одному перебирать узлы в базе и затем проверить его в treeview на раскрытость и ставить значение в базе 0 или 1.

затем после обновления процедура сама будет проверять. по любому вначале будут раскрываться узлы, затем подузлы а дальше подподузлы. родитель подузла по любому не поменяется. подузел не будет раскрыт если его узел не раскрыт.


 
Ega23 ©   (2010-09-20 15:16) [6]


> можно ли по одному перебирать узлы в базе и затем проверить
> его в treeview на раскрытость и ставить значение в базе
> 0 или 1.


А ты возьми и сравни, что в данном случае менее затратно по времени: "сорок раз по разу" или "один раз сорок раз".
По времени будет очень долго.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2010.12.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.003 c
15-1283507963
Медвежонок Пятачок
2010-09-03 13:59
2010.12.12
про кита


15-1283459378
Юрий
2010-09-03 00:29
2010.12.12
С днем рождения ! 3 сентября 2010 пятница


15-1283511204
DVM
2010-09-03 14:53
2010.12.12
Помогите с переводом на английский одного слова


15-1283442883
ProgRAMmer Dimonych
2010-09-02 19:54
2010.12.12
Хардлинки на DVD


2-1284885575
Telebot
2010-09-19 12:39
2010.12.12
TWebBrowser грузит сильно ЦП (более 50%) и ест много памяти





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский