无法弄清楚如何将参数传递给绑定函数



在多次尝试在滚动事件函数中传递参数后,它不工作

我正在制作一个自定义滚动面板,并需要绑定函数在用户向下滚动时触发,为了做到这一点,我需要传递将要在面板内使用的变量。这不是wxScrolledWindow的问题,因为我不需要绑定任何东西,可以为它创建一个函数并直接调用它。

其中一些参数我不一定需要传递,因为我可以通过event.GetEventObject();得到它们,但其他的,比如m,是我需要传递的映射

在我尝试过的解决方案中,如下所示,我想做一个隐藏面板,地图已经在"滚动面板"内部或附近。所以我可以使用event.GetEventObject();访问它,但我离开它作为最后的努力(如果这甚至可以工作)。我真的希望有更简单的方法。如有任何帮助,不胜感激。

尝试# 1

ScrolledWindow->Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this)(m, ScrolledWindow, ScrolledWindowMain, ScrolledWindowSizer, initalWindowWidth));

尝试# 2

// Saw a thread that said parameters should be put outside
ScrolledWindow->Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this)(m, ScrolledWindowContainerSub, ScrolledWindowMain, ScrolledWindowSizer, initalWindowWidth);

尝试# 3

// Tried to pass the arguments as the userData as in the WxWidgets documentation, the WxWidgets forums suggested it, but I looked and apparently, I need to pass in a wxObject? I don't know how a set of arguments is supposed to be turned into a wxObject 
ScrolledWindow->Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this, -1, (m, ScrolledWindowContainerSub, ScrolledWindowMain, ScrolledWindowSizer, initalWindowWidth);
更新:

所以我发现你需要将参数存储为wxClientData,我相信我已经成功地做到了,但我仍然不知道如何从中提取单个项目。

struct CustomData final : public wxClientData {
int PanelNum = 20;
std::list<std::string> TagList{ "Paid", "Needs invoice" };
std::map<std::string, std::variant<std::string, std::list<std::string>>> m{ {"TIME","8:69"}, {"HEADER","Title"},{"TAGS", TagList},{"CONTENT", "Hey this is content!"} };
wxPanel* ScrolledWindowContainerSub;
wxPanel* ScrolledWindowMain;
wxBoxSizer* ScrolledWindowSizer;
int initalWindowWidth = 1300;
};

// Panels that are set as arguments below are defined here 
// wxPanel* ScrolledWindowContainerSub = ...; etc...
CustomData* const myData{ new CustomData() };
myData->PanelNum, m, ScrolledWindowContainerSub, ScrolledWindowMain, ScrolledWindowSizer, initalWindowWidth;
ScrolledWindowContainerSub->SetClientObject(myData);
ScrolledWindowContainerSub->Bind(wxEVT_SCROLL_BOTTOM, &MyFrame::ScrolledWindowScrolled, this);

void MyFrame::ScrolledWindowScrolled(wxScrollEvent& event) {
wxObject* Obj = event.GetEventObject();
wxClientData* ObjClientData = static_cast<wxEvtHandler*>(Obj)->GetClientObject();

wxPanel* ObjStaticChild = dynamic_cast<wxPanel*>(ObjClientData); // Which panel will this give me? I've put two as parameters

};

Bind()确实支持将指针传递给任意"用户数据",但这不是最好的方法,并且只支持向后兼容和简化迁移Bind()之前的非常旧的代码。

相反,考虑让你需要的数据成为某个对象的一部分——通常是从窗口类派生出来的,代表你要绑定到的窗口,但不一定是这样——并绑定到这个对象的成员函数,在这个对象中你可以访问你需要的所有数据。

请记住,您不需要绑定到生成事件的对象或其父对象。您可以使用任何您想要的,包括lambda,例如。

您在Bind中用于将事件绑定到事件处理程序的语法是不正确的。

从事件处理程序的文档中,正确的语法应该是这样的:
//-------------------------------------------------------------------vv--->no need of other things here
Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this);

最新更新