Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TreeView, перемещение элементов 
:(
    Опции темы
Alix
Дата 8.11.2005, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Обыскал рунет, но так и не нашел описание того, как можно сделать перемещения элементов в TreeView вверх/вниз на позицию, влево/вправо (т.е. выше на каталог и поместить в нижний каталог).
Сам я это все сделал. Точнее пока только вверх/вниз. И оно работает. Но если один элемент переместить вверх/вниз опр. (притом фиксированное!) число раз, то вылетает Access Violation. А так ничего... работает... Но проблема в том, что я не могу найти откуда у этого violation'a "ноги растут"... Думал что это конфликт с обработчиками событий TreeView'a, но закоментировал их код, а ошибка все равно осталась.
Пожалуйста, напишите, как бы вы сделали перемещение элемента вверх/вниз (хотя бы это). Заодно в DRKB поместить можно будет smile В рунете этого точно нет...
Перемещать можно по-разному. Как способ предлагаю написать ф-ю Exchange(node1, node2 : TTreeNode), которая меняла бы соседние эл-ты местами. Соответственно функции:
Код
procedure MoveUp;
var
  node, prev : TTreeNode;
begin
  node := TreeView.Selected;
  if node = nil then
    exit;

  prev := node.getPrevSibling; //но не getPrev!!!
  if prev = nil then
    exit;

  Exchange(prev, node);
end;

procedure MoveDown;
var
  node, next : TTreeNode;
begin
  node := TreeView.Selected;
  if node = nil then
    exit;

  next := node.getNextSibling; //но не getNext!!!
  if next = nil then
    exit;

  Exchange(node, next);
end;

// ну и обработчик OnKeyDown или OnKeyUp TreeView'a с if key=VK_UP или т.п.



--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
_hunter
Дата 8.11.2005, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 15
Всего: 98



код Exchange() привести не помешало бы...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Alix
Дата 8.11.2005, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Цитата(_hunter @ 8.11.2005, 12:28)
код Exchange() привести не помешало бы...

Цитата
Как способ предлагаю написать ф-ю Exchange(node1, node2 : TTreeNode), которая меняла бы соседние эл-ты местами.

Читайте внимательнее!


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
_hunter
Дата 8.11.2005, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 15
Всего: 98



Цитата
Сам я это все сделал. Точнее пока только вверх/вниз. И оно работает. Но если один элемент переместить вверх/вниз опр. (притом фиксированное!) число раз, то вылетает Access Violation.

из чего я делаю вывод что код есть. его я и просил.

или под
Цитата
Как способ предлагаю написать ...

следует понимать приглашение для всех желающих написать эту функцию?


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Alix
Дата 9.11.2005, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Поясняю.
Да, код есть. Но есть и непонятные глюки. Поэтому я прошу тех, кто может, написать всего одну очень простую функцию Exchange.
Свой код я не привожу по той причине, что, быть может, у данной задачи есть несколько путей решения и я не хочу, чтобы другие, посмотрев на мой код, начали искать решение в том же направлении, где его искал я. Тогда, может быть, появятся решения другого типа нежели у меня и, может быть, с ним не будет никаких глюков.
Хотя если вы будете настаивать, свой код я выложить могу. Благо это задача copy/paste...


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
_hunter
Дата 9.11.2005, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 15
Всего: 98



код выкладывай ( заодно о своих ошибках узнаеш )

а решение зависит от того, нужно ли детей ноды переносить.


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Alix
Дата 9.11.2005, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Цитата
а решение зависит от того, нужно ли детей ноды переносить.

Разумеется!

Ладно. Уломал. Вот код:
Код
// вот эту фунцию я взял с какого-то форму. Сорри если что... :)
procedure MoveChildren(SrcNode, DestNode: TTreeNode);
begin
     if (SrcNode = nil) or (DestNode = nil) or
        (SrcNode = DestNode) or DestNode.HasAsParent(SrcNode) then exit;
     while SrcNode.Count > 0 do
       SrcNode.Item[0].MoveTo(DestNode, naAddChild);
end;

function Exchange(node1, node2 : TTreeNode) : boolean;
var
  node : TTreeNode;

begin
  Result := true; // ну мне это надо было...
  node := TreeView.Items.InsertObject(node1, node2.Text, node2.Data);

  MoveChildren(node2, node);
  node2.Free;
  node.Collapse(false);
  node1.Collapse(false);
end;

Да! Забыл здесь написать (а так это есть). В функциях MoveUp/Down оисанных выше вызов Exchange обрамлен следующим кодом:
Код
TreeView.Items.BeginUpdate;
// Exchange here...
TreeView.Items.EndUpdate;



--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
Alexeis
Дата 10.11.2005, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Вот такой код позволяет перетаскивать элементы Treeview

Код

type
  TForm1 = class(TForm)
    Button1: TButton;
    TreeView1: TTreeView;
    TreeView2: TTreeView;
    procedure Button1Click(Sender: TObject);
    procedure TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure MoveNode(TargetNode, SourceNode: TTreeNode);
  end;
  
var
  Form1: TForm1;


implementation

{$R *.dfm}

  //Dragmode := mautomatic

procedure TForm1.Button1Click(Sender: TObject);
begin
 TreeView1.SetFocus;
end;

procedure TForm1.MoveNode(TargetNode, SourceNode: TTreeNode);
var
  nodeTmp : TTreeNode;
  i       : Integer;
begin
  with TreeView1 do
  begin
    nodeTmp := Items.AddChild(TargetNode, SourceNode.Text);
    for i := 0 to SourceNode.Count - 1 do
    begin
      MoveNode(nodeTmp, SourceNode.Item[i]);
    end;
  end;
end;


procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  TargetNode, SourceNode: TTreeNode;
begin
  with TreeView1 do
  begin
    TargetNode := GetNodeAt(X, Y); // Get target node
    SourceNode := Selected;

    if TargetNode = nil
    then
      begin
        TreeView1.Items.Add(nil, SourceNode.Text);
        SourceNode.Free;
        EndDrag(False);
        Exit;
      end;

    if TargetNode = SourceNode
    then
      begin
        EndDrag(False);
        Exit;
      end;

    MoveNode(TargetNode, SourceNode);
    SourceNode.Free;
  end;
end;

procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  if (Sender = TreeView1) then // If TRUE than accept the draged item
  begin
    Accept := True;
  end;

end;



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Albinos_x
Дата 10.11.2005, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



alexeis1
я думаю ему нужно не передаскивание, а именно перемещение


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Quadr0
Дата 10.11.2005, 13:56 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











...

Это сообщение отредактировал(а) Quadr0 - 15.7.2011, 02:43
  Вверх
Alexeis
Дата 10.11.2005, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Quadr0
Сортировка вроде не работает,
а внутренние элементы дерева(листья)
перемещаются неверно (перескакивают с уровня на уровень)



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Quadr0
Дата 10.11.2005, 14:52 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











...

Это сообщение отредактировал(а) Quadr0 - 15.7.2011, 02:43
  Вверх
Alexeis
Дата 10.11.2005, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Quadr0
Ввел весь алфовит при нажатии на кнопку
"сортировка по возрастанию", "сортировка по убыванию"
ноль эмоций

компилировал в delphi7


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alix
Дата 10.11.2005, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Well... smile
Спасибо, Quadr0. Сортировка мне даром не была нужна, правда, но смысл ясен.
Увидел naInsert - не поверил, что оно есть, полез в хелп - точно есть. Я просто уже смотрел moveTo, но не заметил там naInsert и долго, помниться, еще ругался, почему везде одни только naAdd'ы smile .
Еще мне не нужен был переход к родителю - это уже отдельные функции. В итоге мой код:
Код
procedure MoveUp;
var
  node : TTreeNode;
  prev : TTreeNode;

begin
  node := TreeView.Selected;
  if node = nil then exit;

  prev := node.getPrevSibling;
  if prev = nil then exit; // не надо переходить к родителю. Так, например, в The Bat'e сделано.

  TreeView.Items.BeginUpdate;
  node.MoveTo(prev, naInsert);
  TreeView.Selected := node;
  TreeView.Items.EndUpdate;
end;

procedure MoveDown;
var
  node : TTreeNode;
  next : TTreeNode;

begin
  node := TreeView.Selected;
  if node = nil then exit;

  next := node.getNextSibling;
  if next = nil then exit;

  TreeView.Items.BeginUpdate;
  next.MoveTo(node, naInsert);
  TreeView.Selected := node;
  TreeView.Items.EndUpdate;
end;

Глюков тоже больше нет smile. Странно, почему прошлый код вызывал Access Violation...


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
Quadr0
Дата 10.11.2005, 15:58 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











...

Это сообщение отредактировал(а) Quadr0 - 15.7.2011, 02:43
  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0711 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.