Как переопределить событие щелчка пользовательского элемента управления Firemonkey

Я пытаюсь создать собственный элемент управления Firemonkey, который наследуется от элемента управления TListView. Я хочу добавить некоторую функциональность в элемент управления, который автоматически выполняется, когда пользователь нажимает на элемент управления. Поэтому моя цель НЕ состоит в том, чтобы указать метод OnItemClick в форме моего элемента управления, а скорее в том, чтобы добавить функциональность непосредственно в сам элемент управления.

Я изо всех сил пытаюсь понять, что мне нужно сделать, чтобы подключиться к обработчику кликов для TListView. В моей голове я представляю, что мое решение будет выглядеть примерно так:

//somewhere in the base TListView code
void __fastcall TListView::ClickHandler()
{
    //logic for handling a click on the list view
}

//somewhere in my custom list view control
void __fastcall TMyListView::ClickHandler()
{ 
    TListView::ClickHandler(); //call base click handler so all the normal stuff happens

    //my additional logic goes here
}

Тем не менее, я не могу найти в документации ничего о том, какой метод я должен попытаться переопределить или как я вообще должен это делать.

Я нашел эту информацию о вызове обработчика Click-event. Я создал простой пример следующим образом:

void __fastcall TFmListView::Click()
{
    ShowMessage("This is the control's click");
}

Это отлично работает, однако согласно документации:

Если пользователь назначил обработчик событию OnClick элемента управления, щелчок по элементу управления приводит к вызову этого метода.

Следовательно, любая дополнительная логика, которую я поместил в метод Click() элемента управления, будет потеряна, если будет установлено одно из свойств элемента управления по событию щелчка.

Каков правильный способ расширить функциональность того, что происходит при нажатии пользовательского элемента управления?


person James Hogle    schedule 29.10.2015    source источник
comment
Поэтому любая дополнительная логика, которую я поместил в метод Click() элемента управления, будет потеряна, если будет установлено одно из свойств элемента управления по событию щелчка.. Это неправда. Вы неправильно читаете документ. Это базовый класс Click(), который вызывает обработчик OnClick, если он назначен. Если пользователь назначает обработчик OnClick, а вы переопределяете Click(), обработчик пользователя не будет вызываться, пока ваш Click() не вызовет базовый класс Click(). Это позволяет вам действовать в дополнение к коду пользователя, решать, будет ли ваш код выполняться до или после кода пользователя, и даже пропускать код пользователя.   -  person Remy Lebeau    schedule 31.10.2015


Ответы (1)


Вот решение C++Builder для вас.

Вот интерфейс класса и реализация:

class TMyListView : public TListView
{
protected:
    virtual void __fastcall DoItemClick(const TListViewItem *AItem);
};

...

/* TMyListView */

void __fastcall TMyListView::DoItemClick(const TListViewItem *AItem)
{
    // write here the logic that will be  executed
    // even if the OnItemClick handler is not assigned
    ShowMessage("Internal itemclick");

    // call the OnItemClick handler, if assigned
    TListView::DoItemClick(AItem);
}

Затем вы объявляете экземпляр класса TMyListView и необходимый обработчик событий в объявлении формы:

TMyListView *LV;
void __fastcall MyOnItemClick(const TObject *Sender, const TListViewItem *AItem);

А вот реализация обработчика событий и создания LV:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    LV = new TMyListView(this);
    LV->Parent = this;
    LV->Position->X = 1;
    LV->Position->Y = 1;
    LV->Width = 100;
    LV->Height = 100;

    LV->Items->Add()->Text = "111";

    LV->OnItemClick = &MyOnItemClick;
}

void __fastcall TForm1::MyOnItemClick(const TObject *Sender, const TListViewItem *AItem)
{
    ShowMessage("Assigned itemclick"); //or any other event handler action
}

Оба сообщения будут показаны.

person asd-tm    schedule 30.10.2015
comment
TListView уже есть опубликованное мероприятие OnItemClick. Вам не нужно создавать для него собственное объявление события. Просто вызовите базовый метод TListView::DoItemClick(), когда ваш переопределенный метод DoItemClick() будет готов вызвать пользовательский обработчик OnItemClick. Кстати, в Сиэтле TItemEvent больше не является частью TCustomListView, теперь это часть TAppearanceListView. И DoItemClick() был переименован в DoListItemClick(). - person Remy Lebeau; 31.10.2015
comment
@RemyLebeau Спасибо за ваш полезный комментарий и правку. Пожалуйста, не стесняйтесь редактировать любой из моих постов. - person asd-tm; 31.10.2015