【问题标题】:How to override on click event of custom Firemonkey control如何覆盖自定义 Firemonkey 控件的点击事件
【发布时间】:2015-10-29 20:25:50
【问题描述】:

我正在尝试创建一个继承自 TListView 控件的自定义 Firemonkey 控件。我想向控件添加一些功能,当用户单击控件时会自动执行这些功能。因此,我的目标不是在我的控件表单上指定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
}

但是,我似乎在文档中找不到任何关于我应该尝试覆盖什么方法,或者我应该如何处理这个问题的任何内容。

我确实找到了 this information 关于调用“点击事件”处理程序的信息。我设置了一个这样的简单示例:

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

这很好用,但是根据文档:

如果用户已将处理程序分配给控件的 OnClick 事件,则单击该控件会导致调用该方法。

因此,如果设置了控件的单击事件属性之一,我在控件的Click() 方法中放置的任何附加逻辑都将丢失。

扩展单击自定义控件时发生的功能的正确方法是什么?

【问题讨论】:

  • "因此,如果设置了控件的单击事件属性之一,我在控件的 Click() 方法中放置的任何附加逻辑都将丢失。"。那不是真的。你误读了文档。它是基类Click() 调用OnClick 处理程序(如果分配了一个)。如果用户分配了OnClick 处理程序,并且您覆盖Click(),则不会调用用户的处理程序,除非您的Click() 调用基类Click()。这允许您在用户代码之外采取行动,决定您的代码是在用户代码之前/之后运行,甚至可以跳过用户代码。

标签: c++ firemonkey c++builder-xe8


【解决方案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
}

两条消息都会显示。

【讨论】:

  • TListView 已经发布了 OnItemClick 事件。您不需要为它创建自己的事件声明。当您覆盖的DoItemClick() 方法准备好触发用户的OnItemClick 处理程序时,只需调用基本TListView::DoItemClick() 方法即可。顺便说一句,在西雅图,TItemEvent 不再是TCustomListView 的一部分,它现在是TAppearanceListView 的一部分。并且DoItemClick() 已重命名为DoListItemClick()
  • @RemyLebeau 感谢您的有用评论和编辑。请随时编辑我的任何帖子。
猜你喜欢
  • 2014-07-16
  • 1970-01-01
  • 1970-01-01
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多