How to detect when NSTextView scrolls vertically

I need to detect whenever a NSTextView scrolls vertically (either via user action or programmatically from ScrollRangeToVisible). I've unsuccessfully tried Adding an Observer in a couple of ways, but it's not working. Here is my code:

  1. Adding observer to the View:

    MainTextView.PostsBoundsChangedNotifications = true;
    MainTextView.AddObserver (this, new NSString("NSViewFrameDidChangeNotification"), NSKeyValueObservingOptions.New, IntPtr.Zero);

    ...

    public override void ObserveValue (NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
    {
    base.ObserveValue (keyPath, ofObject, change, context);
    }

But I never receive any notification. I've changed the keyPath parameter to "Bounds" and various other things, to no avail. Also, I've tried this using the associated NSScrollView.

  1. Adding observer to NSNotificationCenter.DefaultCenter.AddObserver:

    NSNotificationCenter.DefaultCenter.AddObserver ("NSViewFrameDidChangeNotification", ViewScrolled, MainTextView);

    ...

    public void ViewScrolled ( NSNotification notification )
    {
    //do something here
    }

This actually works for the keyPath "NSViewFrameDidChangeNotification" but not for "NSViewBoundsDidChangeNotification" which is what I think I need.

Is there something obvious that's wrong with the code above? Or is there another way to accomplish what I need to do?

Thanks.

Posts

  • rjmrjm CAMember ✭✭✭

    Does this answer help you at all?

  • Yes, that did help. Thanks!

    In case anyone's interested, here's my working (test) code, where ConversationViewer is the NSScrollView for the NSTextView:

    ConversationViewer.ContentView.PostsBoundsChangedNotifications = true;
    NSNotificationCenter.DefaultCenter.AddObserver(this, new
       MonoMac.ObjCRuntime.Selector("boundsDidChangeNotification"),
       NSView.BoundsChangedNotification, ConversationViewer.ContentView);
    

    }

    ...

    [Export("boundsDidChangeNotification")]
    public void BoundsDidChangeNotification(NSObject o){
        var notification = o as NSNotification;
        var view = notification.Object as NSView;
        var position = view.Bounds.Location;
        Console.WriteLine("Scroll position: " + position.ToString());
    } 
    
  • RobertMiles.7600RobertMiles.7600 USMember ✭✭

    For the life of me I can't get any notifications from a bounds change. Is there anything else I could be missing? I found and am using the exact same code. Hmm.

  • RobertMiles.7600RobertMiles.7600 USMember ✭✭

    For some reason, if I change the exact same code to observe frame changes, it gets called just fine.

  • WilliamMunroWilliamMunro USMember

    I ended up using different code (sorry, I don't remember why I changed and don't find any comment - I must have run into some problem). Here's my current code that is working:

            void BoundsChangedNotificationCallback (NSNotification notification)
                {
                    var clipView = notification.Object as NSClipView;
                    if (clipView != null && clipView.DocumentView != null) {
                        var viewHandle = clipView.DocumentView.Handle;
    
                        if (viewHandle == MainTextView.Handle) {
                            ClosePopovers ();
                        }
                    }
    
                }
    
                void AddMainTextViewBoundsChangeNotification ()
                {
                    NSNotificationCenter.DefaultCenter.AddObserver (NSView.BoundsChangedNotification, BoundsChangedNotificationCallback);
                }
    
                void RemoveMainTextViewBoundsChangeNotification ()
                {
                    NSNotificationCenter.DefaultCenter.RemoveObserver (NSView.BoundsChangedNotification);
                }
    
Sign In or Register to comment.