Перейти к содержанию
  • Регистрация
  • 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;

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

 

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

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


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

Рекомендуемые сообщения

  • 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 я писал для какого то своего проекта, и этот пример, в некоторых местах, просто куски бессмысленного кода...

 

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


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

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


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

    • От Алексей Алексеев
      Помогите новичку! 
      Rad Studio 10.2
      Задача определить какая кнопка мыши нажата.
      Совсем не понимаю, почему не работает:
      procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin if Button = mbLeft then Showmessage('Left!'); Подсвечивает mbLeft:[dcc32 Error] Unit1.pas(1529): E2003 Undeclared identifier: 'mbLeft'
    • От Леонид Кудацкий
      Процедура  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 ? Тапаешь по итему и клавой исправляешь текст.
  • Последние посетители   0 пользователей онлайн

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

×
×
  • Создать...