• 0
YurMak

Нажатие на Item в ListBox срабатывает 1 раз

Вопросы

Здравствуйте, уважаемые!

Пробую писать некое подобие файлового менеджера.

Для вывода папок и файлов использую  ListBox .

Так вот: при обработке события ListBoxItemClick (нажатие  на строку) происходит переход по пути, казанному с этой строке, содержимое этой папки отображается, но строки в ней не нажимаютмя, не реагируют на событие нажатия.

Если проще - строки на первой станице ListBox реагируют на нажатие, а на второй - нет.

Что я делаю не так?

{Клик по Item'у, вперёд}
procedure TForm1.FoldersListBoxItemClick(const Sender: TCustomListBox;
  const Item: TListBoxItem);
var
  ExtFile: string;
begin
  // Сохраняем выбранный путь
  CurrentPath := CurrentPath+Item.ItemData.Text; //Текущая директория

  if Item.TagString = 'folder' then //Проверяем, если это папка
  begin
    if TDirectory.Exists(CurrentPath) then //Проверяем, если папка существует
    begin
      Label1.Text:= 'Нажата строка № '+ inttostr(Item.Index); //Контроль!!!
      FillFolderListBox(CurrentPath, True); //Процедура заполнения ListBox`а папками и файлами
    end
  else if Item.TagString = 'file' then //Иначе - файл
    begin
      Label1.Text:='Отправляем файл "'+Item.ItemData.Text+'" на плеер'; //Готовим на исподнение
    end;
  end;
end;

Вот этот код срабатывает один (первый) раз.

 

Прошу помощи, советов, вариантов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 ответов на этот вопрос

  • 0

попробуйте переход делать в потоке, при этом заполнение лист-бокса в синхронайз. вместо потока можно еще попробовать ForceQueue (для Токио)

Изменено пользователем sinuke

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Спасибо, sinuke, за ответ, но не могли бы вы подтвердить его примером, кодом, ссылкой.

Я программист начинающий, многого еще не знаю и не понимаю, но стремлюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
10 часов назад, YurMak сказал:

CurrentPath := CurrentPath+Item.ItemData.Text;

Возможно, проблема в том, что вы не обнуляете переменную CurrentPath. И при повторном нажатии на Item в ней будет строка, которая уже не является путём к директории или файлу. Поэтому код не срабатывает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

В процессе отладки приложения выяснил непонятную для меня вещь: нажатие на любой Item ListBoxa приводит к Application.Terminated.

С чего бы это?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
33 минуты назад, YurMak сказал:

В процессе отладки приложения выяснил непонятную для меня вещь: нажатие на любой Item ListBoxa приводит к Application.Terminated.

С чего бы это?

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

в общем то я и написал, что в событии нажатия на итем, все действия лучше помещать либо в отдельный поток (очередь). помещаем действия в поток/очередь, событие нажатия завершается и начинается выполнение кода в потоке/очереди. а там уже можно делать все, что угодно, только главное помнить, что обращение к визуальным компонентам нужно производить в Synhronize

ваш код я бы как-то так изменил:

uses System.Threading;

procedure TForm1.FoldersListBoxItemClick(const Sender: TCustomListBox;
  const Item: TListBoxItem);
var
  ExtFile: string;
begin
  // Сохраняем выбранный путь
  CurrentPath := CurrentPath+Item.ItemData.Text; //Текущая директория

  if Item.TagString = 'folder' then //Проверяем, если это папка
  begin
    if TDirectory.Exists(CurrentPath) then //Проверяем, если папка существует
    begin
      Label1.Text:= 'Нажата строка № '+ inttostr(Item.Index); //Контроль!!!
      //Помещаем действия по заполнению лист бокса в очередь. можно попробовать в отдельный поток через TTask.Run
      TThread.ForceQueue(nil,
	    procedure ()
        begin
          TThread.Synchronize(nil,
		    procedure ()
            begin
              FillFolderListBox(CurrentPath, True); //Процедура заполнения ListBox`а папками и файлами
            end);
        end);
    end
  else if Item.TagString = 'file' then //Иначе - файл
    begin
      Label1.Text:='Отправляем файл "'+Item.ItemData.Text+'" на плеер'; //Готовим на исподнение
    end;
  end;
end;

П.С. я тоже могу в каких-то моментах ошибаться. потому как я вообще не программист =))

Изменено пользователем sinuke

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Спасибо! попробовал предложенный вариант: результат тот же.

Изначально проект, из которого я брал этот фрагмент, написан под Android.

Я откомпилировал проект, запустил на Android-эмуляторе - РАБОТАЕТ!

Переходит из папки в папку, возвращается, Всё, как должно быть. А на WIndows (исключив Android-функционал) не хочет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Держите готовый объект FileManager с демкой. Под все платформы (тестил на вин и андроиде)

FileManager.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
7 часов назад, Евгений Корепов сказал:

Держите готовый объект FileManager...

Огромное спасибо!!!

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

Спасибо.

P.S. Можно еще обращаться с вопросами напрямую? (если дадите "координаты" (E-mail, Skype, Viber, Messenger...) куда писать).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
3 часа назад, YurMak сказал:

Огромное спасибо!!!

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

Спасибо.

P.S. Можно еще обращаться с вопросами напрямую? (если дадите "координаты" (E-mail, Skype, Viber, Messenger...) куда писать).

Нет, напрямую не надо, форум - лучший способ, мало ли кому пригодится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 3/5/2018 в 00:15, Евгений Корепов сказал:

...готовый объект FileManager...

Здравствуйте, Евгений! Еще раз спасибо!

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

Не могли бы вы прокомментировать (расписать)  Ваш пример.  Новичку многое непонятно. Как заполняется  ListView (и почему именно ListView, а не ListBox);

как изменить Стиль Item`а (мне, например, не нужно "чекить" его);

как заносятся данные в ItemDetail (мне, например, нужно выводить не дату создания файла, а ID Tag Mp3 файда, не размер его, а длительность в мин.сек (после обработки в соответсвенной процедуре);

в примере есть процедура:

procedure TFormMain.SpeedButton1Click(Sender: TObject);
Var ASelected : TArray<TFileManagerSelectedItem>;
begin
  ASelected:=FileManager.GetSelected;
end; 

отвечающая, как я понял, за заполнение массива данными о содержании директории, но самой SpeedButton на форме я не нашел, начал тупить. Видимо оттого, что я привык работать по-старинке, отдельными методами, процедурами и функциями, а здесь нечтто новое для меня, оттого и непонятное.

Разъясните новичку. Думаю, и другим будет интересно.

С уважением!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
4 часа назад, YurMak сказал:

Здравствуйте, Евгений! Еще раз спасибо!

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

Не могли бы вы прокомментировать (расписать)  Ваш пример.  Новичку многое непонятно. Как заполняется  ListView (и почему именно ListView, а не ListBox);

как изменить Стиль Item`а (мне, например, не нужно "чекить" его);

как заносятся данные в ItemDetail (мне, например, нужно выводить не дату создания файла, а ID Tag Mp3 файда, не размер его, а длительность в мин.сек (после обработки в соответсвенной процедуре);

в примере есть процедура:

procedure TFormMain.SpeedButton1Click(Sender: TObject);
Var ASelected : TArray<TFileManagerSelectedItem>;
begin
  ASelected:=FileManager.GetSelected;
end; 

отвечающая, как я понял, за заполнение массива данными о содержании директории, но самой SpeedButton на форме я не нашел, начал тупить. Видимо оттого, что я привык работать по-старинке, отдельными методами, процедурами и функциями, а здесь нечтто новое для меня, оттого и непонятное.

Разъясните новичку. Думаю, и другим будет интересно.

С уважением!

Listview против ListBox - листбокс тут не подходит, он проще, но гораздо тяжеловеснее. В некоторые папки вы зайти не сможете, при использовании Листбокса. К примеру C:\Windows\System32, у меня там 4 тысячи файлов, и даже под винду для листбокса это будет тяжело. В TFileManager использование ListView не самое оптимальное (лучше использовать DynamicApperance), но на тот момент мне нужен был работающий менеджер и за пол часа

Все вопросы касаемые ListView - вне этой темы, просто изучите соответствующий раздел этого форума. Очень, очень, очень рекомендую упереться и понять как им пользоваться и как он работает. Владение ListView очень пригодится, особенно в мобильных платформах. Просто прочтите вдумчиво все темы в разделе ListView. Потраченное время окупится многократно.

 

Процедуру SpeedButton1Click(Sender: TObject) игнорируйте, просто класс TFileManager я писал для какого то своего проекта, и этот пример, в некоторых местах, просто куски бессмысленного кода...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От Леонид Кудацкий
      Процедура  Process заполняет Listbox:
      procedure TForm1.Process;
      Const
         N=100;
      var
        I,Index:Integer;
        Item:TListBoxItem;
      begin
      for I := 1 to N do
          begin
          Item:=TListBoxItem.Create(ListBox1);
          Item.Text:=IntToStr(I);
          ListBox1.AddObject(Item);
          end;
      ListBox1.ScrollToItem(Item);
      end;
      Нужно, чтобы после заполнения Listbox скролировал в конец.
      Если процедура запускается нажатием кнопки, то всё нормально.
      А если из события формы FormCreate, то Listbox заполняется,
      а скролирование не происходит.
      Где тут собака порылась ?
    • От Sergiy_83
      Всем привет.
      Иногда, особенно когда есть прокрутка списка можно случайно выделить несколько элементов ListBox-а. Ощущение, что чем больше загрузка приложения, тем чаще проявляет себя эта проблема. Бывает редко но жутко раздражает. Работоспособность программы не нарушается.
      Что делать? Может "костыли" какие возможно придумать? 
      Android.
    • От Алексей Алексеев
      Помогите новичку советом!
      Делаю проект блокнота. Использую SQLite. На главной странице есть ListBox на который выводятся первые строки каждой записи (собственно заголовки записей):

       
      При нажатии на Item открывается окно с Memo. Далее запись редактируется, сохраняется и тд...
      С БД ListBox синхронизируется через колонку id, который равен ItemIndex.  
      ВОПРОС:
      Подскажите, как можно сделать, чтобы записи в ListBox отображались в обратном порядке: последние были вверху, первые внизу, как в почтовых сервисах например?
       
       
    • От chaplin.u@gmail.com
      во всех примерах по ComboBox есть только добавить AddItem  а как удалить не нужный Item ?
    • От Sashar333
      Здравствуйте!
      Есть ListBox1, на нем разное кол-во tlistboxitem'ов, на каждом tlistboxitem'е есть один tgridpanellayout состоящий из четырех колонок и одной строчи, в каждой колонке
      по одному trectangle, в каждом trectangle по одному ttext с именами по очереди типа 'w'+IntToStr(Item.index), 'l'+IntToStr(Item.index), 'k'+IntToStr(Item.index)
      такие имена для Ttext требуются для дальнейшей обработки и распознования, в каждом Ttext надпись, на примере "-","2","2","Х" :

      при нажатии на текст "Х" удаляется tlistboxitem c помощью listbox1.Items.Delete(indexclick)
      Проблема следующая, при создании нового итема пишет дубликат имени Ttext, я так понял что итем удалился а то что на нем -нет
      как можно быстро удалить и итем и то что на нем находилось? Пример создания итема:
      procedure addrazmer(zap:typezap); var item:tlistboxitem; pg:tgridpanellayout; t1,t2,t3,t4:ttext; al:talignlayout; r1,r2,r3,r4:trectangle; i:integer; begin form1.listbox1.BeginUpdate; while Form1.listbox1.Count<>1 do Form1.listbox1.Items.Delete(0); for i := 0 to length(zap.razmer)-1 do begin item:=tlistboxitem.Create(form1.listbox1); item.Height:=30; pg:=tgridpanellayout.Create(item); pg.RowCollection[1].Value:=0; pg.ColumnCollection.Add;pg.ColumnCollection[2].Value:=50; pg.ColumnCollection.Add;pg.ColumnCollection[3].Value:=10; pg.Parent:=item; pg.Align:=al.alClient; r1:=trectangle.Create(pg); r2:=trectangle.Create(pg); r3:=trectangle.Create(pg); r4:=trectangle.Create(pg); r1.Parent:=pg;r1.Align:=al.alClient; r2.Parent:=pg;r2.Align:=al.alClient; r3.Parent:=pg;r3.Align:=al.alClient; r4.Parent:=pg;r4.Align:=al.alClient; t1:=ttext.Create(r1); if zap.tip<>'Лист' then Begin t1.Enabled:=false; t1.Text:='-'; End else Begin t1.text:=floattostr(zap.razmer.witdh); end; t2:=ttext.Create(r2);t2.text:=floattostr(zap.razmer.length); t3:=ttext.Create(form1);t3.Text:=floattostr(zap.razmer.kol); t4:=ttext.Create(form1);t4.Text:='X'; t1.Parent:=r1;t1.OnClick:=form1.CliskRazmerClick; t2.Parent:=r2;t2.OnClick:=form1.CliskRazmerClick; t3.Parent:=r3;t3.OnClick:=form1.CliskRazmerClick; t4.Parent:=r4;t4.OnClick:=form1.DeleteItemClick; t1.Align:=al.alClient; t2.Align:=al.alClient; t3.Align:=al.alClient; t4.Align:=al.alClient; form1.listbox1.InsertObject(form1.listbox1.Items.Count-1,item); t1.Name:='w'+IntToStr(item.Index); t2.Name:='l'+IntToStr(item.Index); t3.Name:='k'+IntToStr(item.Index); end; form1.listbox1.EndUpdate; end; Заранее спасибо!
    • От gresaggr
      Добрый день.
      IDE: Delphi 10.1 Berlin Update2
      OS: Windows 7/64 ->Android (тестировал на 4.4.4)
      Вопрос 1:
       
      Пытаюсь загрузить в Listbox файл с русскими словами: ListBox1.Items.LoadFromFile(TPath.Combine(TPath.GetDocumentsPath, 'test1.txt'));
      При запуске на устройстве выдает ошибку: No mapping for the Unicode character exists in the target multi-byte code page
      Файл пытался сохранить и в UTF-8, и в ANSI, и в Unicode - без разницы (после смены кодировки делал Deployment)
      Как можно это победить?
      Вопрос 2:
      Вставил напрямую в дизайн-моде список этих же слов (из файла вопрос1) в Listbox - при старте программа очень долго думает. Слов порядка 10000. Как-то можно это ускорить?


       


       


       
    • От M1shQa
      Есть один листбокс..) В общем парился я парился, так и не понял как запилить стиль по человечески для итемов в боксе и нашел кнопку Edit default Style. Нашел куда впилить TimageViewer и поставил ему свойство client. Все бы ничего, да вот размер итемов не статичен, а картинка не растягивается, к тому же pngшная картинка не отделяется от фона. Подскажите, как картинку растягивать в зависимости от длины и ширины итемов листбокса и как правильно юзать pngшные картинки (что бы они сохраняли прозрачность). Может я вообще не туда рою и нужно другими способами вставлять картинки под каждый item? Видел много гайдов под listview, но к сожалению мне нужно именно для бокса..
      ----
      п.с. что бы было проще: как нарисовать ровную плашку позади каждого элемента листбокс?
    • От chaplin.u@gmail.com
      У Мемо есть фича когда нажимаешь (тап по экрану) вылезает клавиатура для редактирования текста.
      Можно ли сделать такое-же с ListBox ? Тапаешь по итему и клавой исправляешь текст.
    • От M1shQa
      Всем утречка! Интересует вопрос кастмизации listbox в плане дизайна. Хотелось бы что бы плашки имели какой то другой цвет, рамку с обводкой и все на андроиде: в какую сторону рыть? Пилить стиль самому?
      Хотелось бы, что бы элементы в листбоксе были темно подсвечены и имели рамочку.. Стили ставил, а вот как поправить что-то в стиле пока не понял.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу