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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработчик OnItemChecked в ListView, Необходим совет 
V
    Опции темы
Antony41
  Дата 28.10.2009, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 332
Регистрация: 27.12.2008

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



Здравствуйте уважаемые программисты!
Есть компонент, ListView, но без обработчика OnItemChecked, ну как в Delphi7 было, приходилось руками лепить, но вот ни когда не сталкивался я с этой задачей, а вот и столкнулся в Delphi 2009 хоть там у стандартного компонента есть такой обработчик, но мне нужно самому отследить это событие так как я хочу его прилепить к другому компоненту(TsListView из пакета AlphaControls), да и вобще понять как вобще это нужно было сделать. Основная задача посчитать кол-во отмеченных CheckBox'ов.

В делфи 2009 со стандартным списком всё ясно и понятно, но вот как это сделать вручную?
Я сделал следующее:

Код

CurrentBoxStatus : Boolean; //глобальная
FChecked:Integer;


Код

procedure TForm1.ListView1Changing (Sender: TObject; Item: TListItem; Change: TItemChange; var AllowChange: Boolean);
begin
CurrentBoxStatus := Item.Checked; // запоминаем значение Item.Checked до того как юзер на нее нажал
end;


Код

procedure TForm1.ListView1Change(Sender: TObject; Item: TListItem;  Change: TItemChange);
begin
   if Item.Checked <> CurrentBoxStatus then //  изменил значение Item.Checked
     begin
      {До того пока не изменили положение галочки на новое значение, начинаю считать}
         if not CurrentBoxStatus then {если галочка была снята, то отмечаю, значит CheckCount+1}
          Inc(FChecked)
         else {Иначе вычитаю CheckCount-1}
           Dec(FChecked); 
      CurrentBoxStatus := Item.Checked; // изменяем значение переменной на новое значение
      { По сути всё правильно и тут можно запихать любой код, который должен срабатывать при установки или снятии галочки} 
     end;
Label1.Caption:=IntToStr(FChecked); {Показать результат}
end;


Вся сложность в том, что например когда я выполняю процедуру предположим MyListView.DeleteSelected, то начинается путаница и неразбериха! И я честно сказать уже заколебался ловить события какие за каким выполняются, короче одним словом я запутался! Как быть?

Это сообщение отредактировал(а) Antony41 - 28.10.2009, 12:29
PM MAIL   Вверх
Beltar
Дата 28.10.2009, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

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



А при DeleteSelected, как я понимаю, ListViewChange возникает? Я бы завел какую-то гобальную переменую, (вариант Tag контрола) которую мониторил бы в событиях, и если она True, то сразу Exit из обработчика, или блокировка части кода.

Вообще не уверен, что правильно тебя понял.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
bems
Дата 28.10.2009, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Если этот TsListView тоже обертка над виндовым лист вью, то можно ловить LVN_ITEMCHANGING или LVN_ITEMCHANGED


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Antony41
  Дата 29.10.2009, 04:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 332
Регистрация: 27.12.2008

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



Ну вот так сказать на свежую голову и мозги просвежели))) 
спасибо всем! 
Осталось только помочь с оптимизацией кода

Код

var//Глобальные
FCheckedCount:Integer; //сюда будет записываться кол-во отмеченных итемов
CurrentBoxStatus : Boolean; //это запись последнего состояния checkBox'a
FDelItemChecked, FDelItemNotChecked: Boolean; //Это переменные в которые сообщается какой был удалён итем отмеченный или нет

procedure TForm1.sButton1Click(Sender: TObject);
begin
  sListView1.DeleteSelected; //Удаляю выделенный элемент из ListView
end;

procedure TForm1.sListView1Change(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
  if FDelItemChecked then {Если было выполнено удаление отмеченного итема}
    begin
      if FCheckedCount>0 then
        begin
          Dec(FCheckedCount); {Уменьшаю на единицу}
          FDelItemChecked:=False; {сообщаю что действие выполнено}
          Result.Caption:=Inttostr(FCheckedCount); {Показываю результат}
        end;
      Exit; {Выхожу}
    end;

    if Item.Checked <> CurrentBoxStatus then // юзер изменил значение Item.Checked
      begin
        if not FDelItemNotChecked then {если неотмеченный итем не удалялся}
          if not CurrentBoxStatus then {если записанное значение было False}
            if FCheckedCount>=0 then
              Inc(FCheckedCount) {то увеличиваю на единицу}
            else
          else
            if FCheckedCount>0 then
              Dec(FCheckedCount); {иначе уменьшаю на единицу}
        FDelItemNotChecked:=False;{если удалялся неотмеченный эллемент, то мы ни чего не выполняем, а просто сообщаю что действие выполнено}

        CurrentBoxStatus := Item.Checked; // изменяем значение переменной на новое значение
          {===================================}
          {Здесь код для события OnItemChecked}
          {===================================}
      end;
    Result.Caption:=Inttostr(FCheckedCount); {Показываю результат}
end;

procedure TForm1.sListView1Changing(Sender: TObject; Item: TListItem;
  Change: TItemChange; var AllowChange: Boolean);
begin
  CurrentBoxStatus := Item.Checked; // запоминаем значение Item.Checked до того как юзер на нее нажал
end;

procedure TForm1.sListView1Deletion(Sender: TObject; Item: TListItem);
begin
  if Item.Checked then
    FDelItemChecked:=True {Сообщаю что удаляется отмеченный итем}
  else
    FDelItemNotChecked:=True; {Сообщаю что удаляется не отмеченный итем}
end;


Это сообщение отредактировал(а) Antony41 - 29.10.2009, 04:43
PM MAIL   Вверх
Antony41
Дата 30.10.2009, 06:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 332
Регистрация: 27.12.2008

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



Вопрос решён!

Код

var //глобальные
OriginalListViewWindowProc:TWndMethod;
FCheckedCount:Integer;

Код

procedure TForm1.ListViewWindowProcEx(var Message: TMessage) ;
var
  listItem : TListItem;
begin
  if Message.Msg = CN_NOTIFY then
    if (PNMHdr(Message.LParam)^.Code = LVN_ITEMCHANGED) then
      with PNMListView(Message.LParam)^ do
        if (uChanged and LVIF_STATE) <> 0 then
          if ((uNewState and LVIS_STATEIMAGEMASK) shr 12) <> ((uOldState and LVIS_STATEIMAGEMASK) shr 12) then
          begin
            listItem := slistView1.Items[iItem];
            if ListItem.Checked then {если итем отмечен}
              inc(FCheckedCount)
            else
              if FCheckedCount>0 then {если отметка снята}
                Dec(FCheckedCount);
            Result.Caption:=IntToStr(FCheckedCount); {Показываю результат}
            memo1.Lines.Add(Format('%s checked:%s', [listItem.Caption, BoolToStr(listItem.Checked, True)])) ; {Показываю результат}
          end;
  OriginalListViewWindowProc(Message) ;
end;

Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  OriginalListViewWindowProc := sListView1.WindowProc;
  sListView1.WindowProc := ListViewWindowProcEx;
end;

Код

procedure TForm1.sButton1Click(Sender: TObject);
begin
  sListView1.DeleteSelected; //Удаляю выделенный элемент из ListView
end;

Код

procedure TForm1.sListView1Deletion(Sender: TObject; Item: TListItem);
begin
  if Item.Checked then
    Item.Checked:=False;
end;


Это сообщение отредактировал(а) Antony41 - 30.10.2009, 07:52
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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