Help about create a list of custom control inside a panel

ClodoClodo ITMember ✭✭
edited September 30 in Xamarin.Mac

I have an old Xamarin.Mac project migrated to Unified, without any storyboard.

In a window, i need an scroll area where i can instantiate at runtime a list of custom control.

With Mono/WinForms, i create a class derived from UserControl, in the Window i place a Panel with AutoScroll=true
and i populate for example with

for(int i=0;i<10;i++)
{
    UserControl ctrl = new MyUserControl;
        ctrl.Top = i * ctrl.Height;
        myPanel.Controls.Add(ctrl);
}

What is the corresponding method with Xamarin.Mac?

I create a View.cs derived from NSView, View.xib, ViewController.cs derived from NSViewController.
In the Window, i place a NSScrollView.
And now? The only constructor of View expect a "IntPtr handle".

Any feedback is appreciated, thx.

Posts

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    So, as you found the equivalent in Cocoa is NSScrollView.

    Backing up for a minute, I'd suggest walking through the documentation here:

    https://developer.xamarin.com/guides/mac/getting_started/hello,_mac/

    and this amazing sample:

    https://github.com/xamarin/mac-samples/tree/master/SourceWriter

    But to give you a quick example, this lays out a scroll view with a custom child view of size 2500x2500 with a number of buttons in a line.

    It'd go in the ViewController.cs in a default project.

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
    
            // This is going to contains our custom controls
            NSView customContentView = new NSView(new CoreGraphics.CGRect(0, 0, 2500, 2500));
    
            // 
            NSScrollView scrollView = new NSScrollView(View.Bounds) {
                HasHorizontalScroller = true, // Yes, we want scroll bars
                HasVerticalScroller = true,
                DocumentView = customContentView // And use this frame to determine where we are scrolling
            };
    
            View.AddSubview(scrollView);
            for (int i = 0; i < 10; ++i)
            {
                // Setup some arbitrary custom controls
                NSButton b = new NSButton(new CoreGraphics.CGRect(i * 200, i * 200, 75, 30));
                customContentView.AddSubview (b);
            }
        }
    
  • ClodoClodo ITMember ✭✭

    Many many thanks.

    ViewController.cs in a project exists in recent version of projects, but i need to work on a old XamMac (with MainWindow.cs) upgraded to Xamarin.Mac recently.

    Anyway, i place the NSScrollView via XCode/XIB in the window, create the outlet "pnlTest".

    In the window AwakeFromNib():

    NSView v = new NSView(new CoreGraphics.CGRect(0,0, 200, 2000));
    pnlTest.DocumentView = v;
    for(int i=0;i<10;i++)
    {
        NSButton b = new NSButton(new CoreGraphics.CGRrect(10, 10+ 100 * i, 200, 100));
        v.AddSubview(b);
    }
    

    And works, thanks.

    But i have a more 'stupid' problem.
    Think about a products list, when every product have a title label, description, some buttons for action.
    I do New File -> View Controller that create MySingleProductView.cs, MySingleProductView.xib, MySingleProductViewController.cs.
    I edit MySingleProductView.xib to add some controls and bind outlets.

    I'm losing about create at runtime like the NSButton above, MySingleProductView constructor pick a IntPtr or an NSCoder...

    I know, there are some basics i don't know, i need to study docs & samples. But maybe in mean-time you have a suggestion.

    Thanks anyway for your reply!

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    If I understand your question, it boils down to "What in the world is going on with the various constructors I see on my views".

    • new MyView (NSCoder coder) is a bit of historical happenstance, that you won't see generated in new Unified projects. It is safely ignored.
    • new MyView (IntPtr ptr) is really important, and you need it exposed in every custom NSObject derived class. It is used to "surface" a managed instance of a class when instanced up by the native runtime. Often the only thing to do here is call base
    • new MyView (CGRect rect) is the 99% use case of what you want when creating a view by hand. You might need to code it out (it needs to call base with the rect), specially in older Xamarin.Macs, but that creates a View with the Frame already set.
  • ChrisHamonsChrisHamons USXamarin Team Xamurai
Sign In or Register to comment.