serialization - IDataObject store managed object reference -
i trying implement drag-and-drop functionality within c++/cli application, using standard winforms , wpf (managed) apis. these apis accept object wrapped in implementation of idataobject, serialize it, , deserialize once drag-and-drop target has been specified. not want data transferred serialized , deserialized.
a bit more concretely (albeit dramatically simplified):
[serializableattribute] ref class mytype : public system::iobserver<object^> { public: system::iobservable<object^> ^myobj; static void watch(mytype ^wrapper) { myobj->subscribe(watcher); } private: static mytype ^watcher = gcnew mytype(); void oncompleted(void) = system::iobserver<object^>::oncompleted {} void onerror(system::exception^) = system::iobserver<object^>::onerror {} void onnext(object^) = system::iobserver::onnext { system::windows::forms::messagebox::show("hi!"); } } ref class mycontrol : public system::windows::controls::usercontrol { public: mycontrol(void) { this->drop += gcnew drageventhandler(this, &mycontrol::this_drop); } private: void this_drop(object^, system::windows::drageventargs ^e) { mytype::watch(dynamic_cast<mytype^>(e->data->getdata("myformat"))); } } ref class myform : public system::windows::forms::form { public: myform(void) { initializecomponent(); mytreeview->itemdrag += gcnew system::windows::forms::itemdrageventhandler(this, &myform::mytreeview_itemdrag); } private: mytype ^data = gcnew mytype(); system::windows::forms::treeview ^mytreeview; mycontrol ^mycontrol; void modifymyobjfield(mytype^); void myeventhandler(object^, eventargs^) { modifymyobjfield(data); } void mytreeview_itemdrag(object^, system::windows::forms::itemdrageventargs^) { mytreeview->dodragdrop(gcnew dataobject("myformat", mytype), dragdropeffects::copy); } }
when myeventhandler
called, no messagebox appears, because different mytype
object receives iobservable subscription 1 modified.
because drag-and-drop occurs cis-application, can work around issue pinning myform::data
, passing intptr
back-and-forth. myform::mytreeview_itemdrag
becomes
{ mytreeview->dodragdrop(gcnew dataobject("myformat", system::runtime::interopservices::gchandle::alloc(data, system::runtime::interopservices::gchandletype::pinned).tointptr()), dragdropeffects::copy); }
and mycontrol::this_drop
becomes
{ system::runtime::interopservices::gchandle handle = system::runtime::interopservices::gchandle::fromintptr(*dynamic_cast<intptr^>(e->data->getdata("myformat"))); mytype::watch(dynamic_cast<mytype^>(handle.target)); handle.free(); }
this seems extraordinarily complicated way accomplish simple task, , (obviously) bog down garbage collector. there better way missing?
Comments
Post a Comment