Search code examples
c#cocoaxamarinmonomac

Detect scroll event in NSScrollView


I want to both read and write the scroll position (horizontal and vertical) inside an NSScrollView using MonoMac. I do this because I want to save and load several different states which include the scroll positions. Instead of having several different NSScrollViews I just have a single one and want to change it whenever the state changes.

I have so far figured out that I am interested in the DoubleValue of the NSScrollView's HorizontalScroller and VerticalScroller. But I cannot for my life figure out how to detect when this value changes so I can save it. I need to detect the change no matter if the user is clicking the scroll bar, dragging it, or using either a mouse or a trackpad. As long as the scrollbar moves, I want to save the position.

Any suggestions?


Solution

  • I think you are approaching this the wrong way. My understanding is, it is not best practice to interact with the NSScroller directly (nor, do I think, this will work).

    See the answer to this question, which I think is similar to your scenario. The best thing to do is to set the origin of the scroll view's ContentView.

    I converted the answer of that question to C#:

    public override void AwakeFromNib()
    {
        tableView.EnclosingScrollView.ContentView.PostsBoundsChangedNotifications = true;
        NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("boundsDidChangeNotification"), 
        NSView.BoundsChangedNotification, tableView.EnclosingScrollView.ContentView);
    
        base.AwakeFromNib();
    }
    
    [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());
    } 
    

    You can scroll to a specific point something like this:

    PointF scrollTo = new PointF(19, 1571);
    tableView.EnclosingScrollView.ContentView.ScrollToPoint(scrollTo);
    tableView.EnclosingScrollView.ReflectScrolledClipView(tableView.EnclosingScrollView.ContentView);
    

    You may find this interesting: Scroll View Programming Guide for Mac