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

Can't figure out how to pass arguments to a bind function

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

我正在制作一个自定义滚动面板,需要绑定函数在用户向下滚动时触发,为此我需要传递将在面板内使用的变量。这不是 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 arguements 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 中用于将事件绑定到事件处理程序的语法不正确。

event handler's documentation 开始,正确的语法应该是这样的:

//-------------------------------------------------------------------vv--->no need of other things here
Bind(wxEVT_SCROLLWIN_PAGEDOWN, &MyFrame::ScrolledWindowCreate, this);

Bind() 确实支持将指针传递给任意“用户数据”,但这不是最好的方法,仅支持向后兼容和简化早于 [= 的旧代码的迁移10=].

相反,请考虑将您需要的数据作为某个对象的一部分——通常是从 window class 派生并代表您绑定的 window 的东西,但不是必然如此 - 并绑定到该对象的成员函数,您可以在其中访问所需的所有数据。

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