How to use PrepareWithInvocationTarget on NSUndoManager

When I try the following call

((MyDocument) this.UndoManager.PrepareWithInvocationTarget(this)).DoRemoveEntry (row);

I get the following error:

Could not find a valid superclass for type NSUndoManagerProxy. Did you forget to register the bindings at MonoMac.ObjCRuntime.Class.Register() or call NSApplication.Init()?

I know the problem has to do with Xamarin.Mac not supporting NSProxy, but does this mean there is no way to use NSInvocation based undo/redo? Why would there be a binding to PrepareWithInvocationTarget if thats the case?

Posts

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    I believe you've ran into a bug. I was unable to get get Invocation based undo working myself. I've filed a bug: https://bugzilla.xamarin.com/show_bug.cgi?id=19623

    However, I believe RegisterUndoWithTarget should work just fine. I hacked up a really simple example: https://gist.github.com/chamons/df746ba790d3f0aabaa9 and ran into no problems.

    Sorry for the rough edge you hit and the delay it took in getting you and answer.

  • ChrisBrunoChrisBruno USMember

    Thanks for the response. I ended up using RegisterUndoWithTarget, but the invocation based undo is a little more elegant. Hope to be able to use it in future xamarin.mac releases.

  • dlechdlech USMember ✭✭
    edited May 2014

    NSUndoManagerProxy is not a real object. I actually tried binding it myself and it was weird, so I gave up and made PrepareWithInvocationTarget return an IntPtr (handle to the proxy).

    If you don't compile your own MonoMac like me and you still want to hack around the problem, you can call PrepareWithInvocationTarget using MonoMac.ObjCRuntime.Messaging.xx_objc_msgSend_xx. Something like this maybe?

    var proxyHandle = Messaging.IntPtr_objc_msgSend_IntPtr (this.UndoManager.Handle,
        Selector.GetHandle ("selPrepareWithInvocationTarget:"), this.Handle);
    Messaging.void_objc_msgSend_IntPtr (proxyHandle,
        Selector.GetHandle ("doRemoveEntry:"), this.Handle);
    
  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    I noticed nobody cc'ed themselves on the bug, so i'll post here.

    This will be fixed in XM 2.0 (mid year), but won't be pleasant. For invocation based undo, you have to send a message to the proxy that the undo returns, which when you are normally invoking a c# method is unfortunate. I have it working internally but you get to call IntPtr_objc_msgSend_* on your own exported selectors. Sticking with RegisterUndoWithTarget might be easier even with the fix.

  • ChrisBrunoChrisBruno USMember

    Thanks for the update. RegisterUndoWithTarget is good enough most of the time. The only time I find issues is when the the undo callback takes multiple arguments.

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    Scratch my post on this being fixed in 2.0. Fixing it for real is actually more difficult that I expected, and we need more infrastructure work before we attempt it. Glad RegisterUndoWithTarget is working reasonably well for you.

Sign In or Register to comment.