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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Добавление item'а в listview, и последующее изменение caption'а юзером 
:(
    Опции темы
AriX
Дата 23.5.2005, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Проблема такая. Есть ListView, есть кнопка, при нажатии на которую добавляется Item в ListView с пустым Caption, чтобы юзер ввел туда что-то. Если после ввода Caption пустой, то его надо удалить.
Я добавил в событие OnEdited проверку на пустой Caption. В принципе, работает, но! только когда юзер что-то написал и стер. Оно не срабатывает, если после добавления Item'а юзер ничего не пишет, а сразу нажимает Enter.
Как можно это исправить?
PM MAIL   Вверх
Dynamic
Дата 23.5.2005, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Обрабатывай OnKeyPress.


--------------------
Было бы о чем молчать, а уж что сказать – всегда найдется...
PM MAIL WWW   Вверх
AriX
Дата 23.5.2005, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Dynamic
smile))) Блина, что-то я не догадался smile)
Спасибо, попробую!
PM MAIL   Вверх
Snowy
Дата 23.5.2005, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

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



Если редактирование закончится мышей, то не сработает.
Я бы послал сообщение на нажатие кнопошки, а потом на бэкспэйс.
Хотя, если посмотреть исходняки, то может быть получится просто установить флаг редактирования...
PM MAIL   Вверх
s-mike
Дата 23.5.2005, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 425
Регистрация: 16.1.2005
Где: Киев

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



А про стандартные события OnEditing/OnEdited забыли?
PM MAIL WWW   Вверх
Dynamic
Дата 23.5.2005, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



s-mike Читай первый пост:
Цитата(AriX @ 23.5.2005, 10:38)
Я добавил в событие OnEdited проверку на пустой Caption. В принципе, работает, но! только когда юзер что-то написал и стер. Оно не срабатывает, если после добавления Item'а юзер ничего не пишет, а сразу нажимает Enter.


ЗЫ. Куда-то мое предыдущее сообщение подевалось ...


--------------------
Было бы о чем молчать, а уж что сказать – всегда найдется...
PM MAIL WWW   Вверх
Quadr0
Дата 23.5.2005, 19:47 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











...

Это сообщение отредактировал(а) Quadr0 - 14.7.2011, 20:46
  Вверх
<Spawn>
Дата 24.5.2005, 07:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

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



Вот работающий пример:

Код

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListView1: TListView;
    procedure Button1Click(Sender: TObject);
    procedure ListView1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ListView1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    procedure CheckSelected(ListView: TListView);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Item: TListItem;
begin
  Item := ListView1.Items.Add;
  ListView1.Selected := Item;
  ListView1.Selected.EditCaption;
  ListView1.SetFocus;
end;

procedure TForm1.CheckSelected(ListView: TListView);
begin
  if Assigned(ListView.Selected) and
    (Length(ListView.Selected.Caption) = 0) then
    ListView.DeleteSelected;
end;

procedure TForm1.ListView1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key in [VK_ESCAPE, VK_RETURN] then
    CheckSelected(TListView(Sender));
end;

procedure TForm1.ListView1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  CheckSelected(TListView(Sender));
end;



--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
AriX
Дата 24.5.2005, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



<Spawn>
А OnMouseUp разве сработает, если например нажать на другой контрол, т.е. ListView фокус потеряет. Наверное, надо еще и в OnExit проверку ставить.

Я вот думал, может сделать обработчик какого-то сообщения системного, что-нить типа CM_AFTEREDIT. Пытался найти в MSDN - ничего не выцепил, но толи у меня MSDN кривой какой, толи руки. Там по-моему было что-то про AfterLabelEdit - но по какому сообщению оно происходит - не ясно. Просто столько проверок, может как проще можно сделать?

Но все равно думаю так тоже будет работать.
Всем Спасибо! Дома проверим.

Это сообщение отредактировал(а) AriX - 24.5.2005, 09:41
PM MAIL   Вверх
Dynamic
Дата 24.5.2005, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Мое сообщение куда-то делось, поэтому повторю: может проще запрашивать текст при помощи inputquery() и создавать итем только при непустом вводе?? Столько проблем снимается...


--------------------
Было бы о чем молчать, а уж что сказать – всегда найдется...
PM MAIL WWW   Вверх
Quadr0
Дата 24.5.2005, 14:12 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











...

Это сообщение отредактировал(а) Quadr0 - 14.7.2011, 20:48
  Вверх
<Spawn>
Дата 24.5.2005, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

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



Quadr0 Он имелл ввиду ситуацию завершения редактирования Caption-а, к которой OnExit тоже отностится, а так же и те события которые я описал.


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
AriX
Дата 30.5.2005, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Попробовал. Вроде OnMouseUp не работает. Т.е. создаю итем, ничего туда не пишу, щелкаю мышой на другой элемент - пустой не удаляется.
А остальное вроде работает.
Всем спасибо!!

Dynamic
Цитата
Мое сообщение куда-то делось, поэтому повторю: может проще запрашивать текст при помощи inputquery() и создавать итем только при непустом вводе?? Столько проблем снимается...

Я думаю, что так и придется делать. Не хочется правда - дико как-то неудобно чтоли smile.


Может все-таки есть еще способы? smile

PM MAIL   Вверх
AriX
Дата 3.6.2005, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Посидел-помучился, но наконец разобрался с этой проблемой.

Способ вставлять проверку в OnExit, OnMouseUp, OnKeyUp, OnSelectItem работает, но не всегда.
Во-первых, вместо OnMouseUp надо использовать OnMouseDown, не помню зачем, но так работает лучше.
Но тоже плохо - если, например, нажать на другой итем при вводе пустого, то событие не срабатывает.

Короче, чем вставлять кучу проверок, проще создать потомка от TListView и немного его переделать.
Разбирался долго, но врубился, что куда и откуда. MSDN не стоит, поэтому до всего пришлось додумываться методом тыка.

Вообщем, если это кому надо, вот код. Может и не лучший, но работающий smile :::

Код
unit sjListView;

interface

uses
  SysUtils, Classes, Controls, ComCtrls, CommCtrl, Messages;

type
  TsjListView = class(TListView)
  private
    FOldCaption: string;
    // Здесь идет обработка системных сообщений BeginLabelEdit и EndLabelEdit
    procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('sJ', [TsjListView]);
end;

{ TsjListView }

procedure TsjListView.CNNotify(var Message: TWMNotify);
var
  S: string;
  TmpItem: TLVItem;
begin
  with Message do
    case NMHdr^.code of
      // В начале редактирования...
      LVN_BEGINLABELEDIT: begin
        inherited;
        // Запоминаем caption
        FOldCaption := ItemFocused.Caption;
      end;
      LVN_ENDLABELEDIT: begin
        // В конце редактирования...
        with PLVDispInfo(NMHdr)^ do begin
          // Делаем копию item'а
          TmpItem := item;
          // Здесь самое хитрое
          // В item.pszText записывается строка по такому принципу:
          //   - если строка после редактирования осталась той же, то pszText = ''
          //   - если она изменилась, то в pszText записывается новый caption
          // Фишка в том, что если item.pszText = '', то если вызвать Edit(item)
          // без проверки на пустой pszText, то caption очиститься
          // Но ведь если caption был не пустой, нам не нужно его очищать!
          // Для этого мы и запоминаем OldCaption
          // Здесь идет проверка: если строка была не пуста, и она не изменилась,
          // то TmpItem.pszText = старой надписи
          if (item.pszText = '') and (FOldCaption <> '') then
            TmpItem.pszText := PAnsiChar(FOldCaption);
          // Здесь убрана проверка для того, чтобы вызвать OnEdited в любом случае,
          // даже если строка не изменилась (в оригинальном коде, проверка стоит,
          // поэтому OnEdited не вызывается, когда строка не поменялась
          if TmpItem.IItem <> -1 then
            Edit(TmpItem);
        end;
      end;
      else
        inherited;
    end;
end;

end.


ЗЫ: Писал ночью, хотел спать, так что комментарии немного идиотские smile)
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.0774 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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