Search code examples
monomonodevelopmonomac

MonoMac BeginSheet issues


I'm writing a MonoMac app and I'm struggling with the BeginSheet. I have a number of problems with it, and will list them in the hope that it is a common problem across them all.

I have managed to get my BeginSheet to show my Login Window as a sheet, but if I set my app's main interface to the MainWindow in the app's properties, instead of the MainMenu, then the BeginSheet does nothing. My delegate also never runs after the sheet closes. I close the LoginWindow from within the LoginDialogController by calling Close().

This is the code that I use on my MainWindowController:

public override void WindowDidLoad ()
{
    base.WindowDidLoad ();

    Dialogs.LoginDialogController loginDialog = new Dialogs.LoginDialogController();
    loginDialog.Window.IsVisible = false;

    NSApplication.SharedApplication.BeginSheet(loginDialog.Window, Window, delegate {
        // THIS NEVER RUNS
        mainTabView.SelectAt(1);
        mainToolbar.SelectedItemIdentifier = "hometoolbaritem";
    });
}

In one of my other views I use the following code which has absolutely no effect:

TypeDialogController typeDialog = new TypeDialogController();
typeDialog.Window.IsVisible = false;
// THIS CALL HAS NO EFFECT
NSApplication.SharedApplication.BeginSheet(typeDialog.Window, View.Window, delegate {
    // THIS WILL PROBABLY NOT RUN EITHER, EVEN IF THE SHEET SHOWS
});

Any help would be appreciated.


Solution

  • The WindowDidLoad() method is not called when you switch the application main interface to the MainWindow, because the method is part of the MainWindowController, not MainWindow.

    Normal sequence of events is something like this:

    1. MainMenu.xib is started as the app's main UI
    2. MainMenu.xib instantiates the AppDelegate
    3. AppDelegate FinishedLaunching(NSObject notification) delegate method is called
    4. FinishedLaunching(NSObject notification) constructs a new instance of MainWindowController, and uses it to show MainWindow
    5. MainWindowController WindowDidLoad() is called, and your code runs

    When you change the main interface to be MainWindow.xib, this is what happens

    1. MainWindow.xib is started as the app's main UI. That is, an instance of MainWindow is created but not controller to manage it and no app delegate

    It's not clear to me what you're trying to achieve by changing the main interface to MainWindow.xib. Perhaps if you explain what you are trying to achieve someone may be able to help.

    Regarding the problems you are having with sheets, it seems likely that you are not closing the sheet properly in your LoginDialogController. Just calling Window.Close() is insufficient and will prevent further sheets from being shown, as you have seen. You need to do something like this:

    NSApplication.SharedApplication.EndSheet(this.Window);
    this.Window.OrderOut(sender);
    this.Window.Close();
    

    You always need to balance a call to BeginSheet with a call to EndSheet.

    If this is not your problem, you need to show how you are closing out the sheet in your LoginDialogController.