在按钮 OnClick 方法中作为发件人传递什么?
What to pass as a Sender in a button OnClick method?
我有一个动态创建按钮的函数
void createBtn(News obj,TForm *Form1){
TButton *spam = new TButton(Form1);
spam->Parent = newsCard;
spam->Position->X = 280;
spam->Position->Y = 256;
spam->Text = "Spam";
}
我需要给它分配一个 OnClick
事件,所以我在上面的函数中添加了以下行:
spam->OnClick = spamClick;
spamClick 的代码是:
void __fastcall TForm1::spamClick(TObject *Sender, News obj)
{
allUsers[userIndex].spamNews(obj);
ShowMessage("Done!");
}
问题是,我需要在行中传递 obj
,但该函数需要 2 个参数,即 Sender
和 obj
。
spam->OnClick = spamClick(obj); // error here
但是不知道要传什么。我试过 Form1
、spam
和 newsCard
。但是没有任何效果。
我作为 Sender
传递什么?或者,有没有办法将 OnClick 事件分配给 createBtn()
内的按钮?
编辑:
class 新闻具有以下定义
class News
{
public:
News(string, string, string, Dates);
string title;
string description;
Dates date;
int rate;
string category;
vector<Comment> comments;
int spamCount;
static int newsCount;
int newsID;
int numOfRatedUsers;
};
spamNews 是用户 class 中的一个函数,它将 obj.newsID 推入用户中的向量,然后增加 spamCount。
void user::spamNews(News& obj) {
//check that the news in not already spammed
if(!findNews(spammedNews,obj)){
spammedNews.push_back(obj.newsID);
obj.spamCount++;
}
}
您的第二种方法不起作用,因为您试图先 调用 spamClick()
,然后将其 return 值分配给 OnClick
事件.
您的第一种方法是正确的方法,但是您不能向 OnClick
事件处理程序添加参数。
TButton
具有 Tag...
用于保存 user-defined 数据的属性。但是,由于 News
对象不是通过指针传递的,因此 Tag...
属性在这种情况下不是很有用(除非 News
对象保存在 array/list然后可以将其索引存储在 Tag
).
否则,我会建议从 TButton
派生一个新的 class 来保存 News
对象,例如:
class TMyButton : public TButton
{
public:
News NewsObj;
__fastcall TMyButton(TComponent *Owner, const News &obj)
: TButton(Owner), NewsObj(obj) {}
};
void TForm1::createBtn(const News &obj)
{
TMyButton *spam = new TMyButton(this, obj);
spam->Parent = newsCard;
spam->Position->X = 280;
spam->Position->Y = 256;
spam->Text = _D("Spam");
spam->OnClick = &spamClick;
}
void __fastcall TForm1::spamClick(TObject *Sender)
{
MyButton *btn = static_cast<TMyButton*>(Sender);
allUsers[userIndex].spamNews(btn->NewsObj);
ShowMessage(_D("Done!"));
}
UPDATE:由于您的 News
对象存储在您正在循环的 vector
中,因此一个更简单的解决方案是通过News
通过 reference 指向 createBtn()
的对象,然后将 pointer 存储到 TButton::Tag
属性,例如:
void TForm1::createBtn(News &obj)
{
TButton *spam = new TButton(this);
spam->Parent = newsCard;
spam->Position->X = 280;
spam->Position->Y = 256;
spam->Text = _D("Spam");
spam->Tag = reinterpret_cast<NativeInt>(&obj);
spam->OnClick = &spamClick;
}
void __fastcall TForm1::spamClick(TObject *Sender)
{
TButton *btn = static_cast<TButton*>(Sender);
News *obj = reinterpret_cast<News*>(btn->Tag);
allUsers[userIndex].spamNews(*obj);
ShowMessage(_D("Done!"));
}
或者,使用 TMyButton
后代:
class TMyButton : public TButton
{
public:
News *NewsObj;
__fastcall TMyButton(TComponent *Owner)
: TButton(Owner) {}
};
void TForm1::createBtn(News &obj)
{
TMyButton *spam = new TMyButton(this);
spam->Parent = newsCard;
spam->Position->X = 280;
spam->Position->Y = 256;
spam->Text = _D("Spam");
spam->NewsObj = &obj;
spam->OnClick = &spamClick;
}
void __fastcall TForm1::spamClick(TObject *Sender)
{
MyButton *btn = static_cast<TMyButton*>(Sender);
allUsers[userIndex].spamNews(*(btn->NewsObj));
ShowMessage(_D("Done!"));
}
我有一个动态创建按钮的函数
void createBtn(News obj,TForm *Form1){
TButton *spam = new TButton(Form1);
spam->Parent = newsCard;
spam->Position->X = 280;
spam->Position->Y = 256;
spam->Text = "Spam";
}
我需要给它分配一个 OnClick
事件,所以我在上面的函数中添加了以下行:
spam->OnClick = spamClick;
spamClick 的代码是:
void __fastcall TForm1::spamClick(TObject *Sender, News obj)
{
allUsers[userIndex].spamNews(obj);
ShowMessage("Done!");
}
问题是,我需要在行中传递 obj
,但该函数需要 2 个参数,即 Sender
和 obj
。
spam->OnClick = spamClick(obj); // error here
但是不知道要传什么。我试过 Form1
、spam
和 newsCard
。但是没有任何效果。
我作为 Sender
传递什么?或者,有没有办法将 OnClick 事件分配给 createBtn()
内的按钮?
编辑: class 新闻具有以下定义
class News
{
public:
News(string, string, string, Dates);
string title;
string description;
Dates date;
int rate;
string category;
vector<Comment> comments;
int spamCount;
static int newsCount;
int newsID;
int numOfRatedUsers;
};
spamNews 是用户 class 中的一个函数,它将 obj.newsID 推入用户中的向量,然后增加 spamCount。
void user::spamNews(News& obj) {
//check that the news in not already spammed
if(!findNews(spammedNews,obj)){
spammedNews.push_back(obj.newsID);
obj.spamCount++;
}
}
您的第二种方法不起作用,因为您试图先 调用 spamClick()
,然后将其 return 值分配给 OnClick
事件.
您的第一种方法是正确的方法,但是您不能向 OnClick
事件处理程序添加参数。
TButton
具有 Tag...
用于保存 user-defined 数据的属性。但是,由于 News
对象不是通过指针传递的,因此 Tag...
属性在这种情况下不是很有用(除非 News
对象保存在 array/list然后可以将其索引存储在 Tag
).
否则,我会建议从 TButton
派生一个新的 class 来保存 News
对象,例如:
class TMyButton : public TButton
{
public:
News NewsObj;
__fastcall TMyButton(TComponent *Owner, const News &obj)
: TButton(Owner), NewsObj(obj) {}
};
void TForm1::createBtn(const News &obj)
{
TMyButton *spam = new TMyButton(this, obj);
spam->Parent = newsCard;
spam->Position->X = 280;
spam->Position->Y = 256;
spam->Text = _D("Spam");
spam->OnClick = &spamClick;
}
void __fastcall TForm1::spamClick(TObject *Sender)
{
MyButton *btn = static_cast<TMyButton*>(Sender);
allUsers[userIndex].spamNews(btn->NewsObj);
ShowMessage(_D("Done!"));
}
UPDATE:由于您的 News
对象存储在您正在循环的 vector
中,因此一个更简单的解决方案是通过News
通过 reference 指向 createBtn()
的对象,然后将 pointer 存储到 TButton::Tag
属性,例如:
void TForm1::createBtn(News &obj)
{
TButton *spam = new TButton(this);
spam->Parent = newsCard;
spam->Position->X = 280;
spam->Position->Y = 256;
spam->Text = _D("Spam");
spam->Tag = reinterpret_cast<NativeInt>(&obj);
spam->OnClick = &spamClick;
}
void __fastcall TForm1::spamClick(TObject *Sender)
{
TButton *btn = static_cast<TButton*>(Sender);
News *obj = reinterpret_cast<News*>(btn->Tag);
allUsers[userIndex].spamNews(*obj);
ShowMessage(_D("Done!"));
}
或者,使用 TMyButton
后代:
class TMyButton : public TButton
{
public:
News *NewsObj;
__fastcall TMyButton(TComponent *Owner)
: TButton(Owner) {}
};
void TForm1::createBtn(News &obj)
{
TMyButton *spam = new TMyButton(this);
spam->Parent = newsCard;
spam->Position->X = 280;
spam->Position->Y = 256;
spam->Text = _D("Spam");
spam->NewsObj = &obj;
spam->OnClick = &spamClick;
}
void __fastcall TForm1::spamClick(TObject *Sender)
{
MyButton *btn = static_cast<TMyButton*>(Sender);
allUsers[userIndex].spamNews(*(btn->NewsObj));
ShowMessage(_D("Done!"));
}