![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Ребят, нуждаюсь в помощи. Не могу разобраться с алгоритмом.
Суть траблы такова: Есть Stringlist с какими-то строками в нём. Строки эти нужно Drag&Drop'ом перетягивать вверх\вниз (ну то бишь юзер должен иметь возможность менять их позицию вручную, мышкой). И каждый раз, при смене позиции строки, нужно записывать в базу эту строку и её новый порядковый номер в Stringlist'e (позицию этой строки). Подскажите плиз либо пошаговый алгоритм, либо кусок кода, в котором реализуется именно получение новой позиции строки. Бьюсь уже третьи сутки, получается пока только бред. |
|
#2
|
|||
|
|||
|
Где-то я уже здесь постил такую штуку.
Тут главный вопрос - у тебя мультивыделение или нет. Если у тебя выделяется всего одна строка, то все просто. Берешь TListBox, как простейший визуальный компонент, отображающий StringList и позволяющий делать Drag'n'Drop. У него ставишь DragMode (каыется так) в dmAuto, а потом все просто: ListBox.ItemIndex - строка которую тащишь, ItemAtPos(X,Y) в момент бросания (соотв. событие) - место, куда надо бросить строку. Соответсвенно, вырезаешь ее и потом Insert. Только при вставке не забудь, что если ты ее ташишь вниз, то после вырезания позиции на 1 уменьшаться. Если у тебя мультивыделение, то все сложнее. точнее начало такое же, только вот вырезнием и вставкой сдвинуть не получится. Тут придется Двигать всю группу выделенных строк по одной позиции поочереди, что бы сохранить их взяимное положение. а по поводу вычисления координат, так так же, как и в первом случае. только явно различаются варианты сдвижки вверх и вниз (направление цикла и граничные условия другие). |
|
#3
|
|||
|
|||
|
lmikle, огромное тебе спасибо. Получилось. Помогло вот это:
ListBox1.ItemAtPos(Point(x,y),True)+1 |
|
#4
|
|||
|
|||
|
Хотя, всё равно глючно работало. После трёх часов мучений пришёл к выводу, что надёжнее будет просто перебором. Вот даже кусочек кода, в котором показано это:
Код:
Procedure TForm10.Ochered(Rayon_name:String);
var
st_count1,qx:integer;
Begin
Table2.Active:=True;
Table2.Open;
Table2.First;
st_count1:=Form1.ListBox1.Items.Count-1; // Получаем реальное количество строк в ListBox'e.
For qx:=0 to st_count1 do
begin
If Table2.Locate('ID',Form1.ListBox1.Items.Strings[qx],[loCaseInsensitive]) then // При условии, что данной строки ещё нет в базе выполняем:
begin
Table2.Edit;
Table2.Fields[0].AsString:=Form1.ListBox1.Items.Strings[qx];// Счётчик цикла определяет индекс строки
Table2.Fields[1].AsString:='NNN';
Table2.Fields[3].AsString:=IntToStr(qx+1); //Для реального значения увеличиваем индекс на 1
Table2.Post;
Table2.FlushBuffers;
end
else // В случае, если такая строка уже есть в базе
begin
Table2.Append;
Table2.Fields[0].AsString:=Form1.ListBox1.Items.Strings[qx];
Table2.Fields[1].AsString:='NNN';
Table2.Fields[3].AsString:=IntToStr(qx+1);
Table2.Post;
Table2.FlushBuffers;
end;
end;
Table2.FlushBuffers;
Table2.Close;
Table2.Active:=False;
end;
end;Вызывать процедуру при событии ListBox1EndDrag. Вроде всё так, может кому-то понадобится Последний раз редактировалось w1zard, 03.10.2008 в 13:13. |