Skip to content

Instantly share code, notes, and snippets.

@pavlovek
Last active November 5, 2019 11:41
Show Gist options
  • Save pavlovek/5c5ea0acae4e967c7e5661c9bc6467a9 to your computer and use it in GitHub Desktop.
Save pavlovek/5c5ea0acae4e967c7e5661c9bc6467a9 to your computer and use it in GitHub Desktop.
Running Xamarin GTK# application on Linux with multiple windows
  1. First step read and follow official instruction

    https://docs.microsoft.com/ru-ru/xamarin/xamarin-forms/platform/other/gtk?tabs=windows

  2. Second step you must configure your Linux system.

    2.1. Install Mono on Linux (GTK# already included)

    https://www.mono-project.com/download/stable/#download-lin

    2.2. Set up sharing of your application between systems (Win and Linux)

    sudo apt-get install cifs-utils
    sudo mkdir /mnt/myshare
    sudo mount -t cifs //my-windows-computer/myshare /mnt/myshare -o domain=my-windows-domain,username=myalias,uid=$USER,gid=$USER
    # /mnt/myshare should now be mapped
    

    More details you can read there https://github.com/Microsoft/MIEngine/wiki/Offroad-Debugging-of-.NET-Core-on-Linux---OSX-from-Visual-Studio

    2.3. Now you can launch you application in Linux. First, run the application through the terminal to see possible errors:

    cd /mnt/myshare
    mono MyGtkApp.exe
    

    2.4. Most likely you will get an error DllNotFoundException on various native libraries in Mono. In most cases, simple mapping for used dlls in the config file of your GTK project will help you:

    https://www.mono-project.com/docs/advanced/pinvoke/dllnotfoundexception/

    If this does not help, then you should check the mapping in /etc/mono/config and indicate the absolute path to the native libraries in mono.

  3. By default, Xamarin does not support working with multiple windows at the same time as WPF, but only navigating within the same form. However, in GTK, this restriction can be circumvented by native constructions of the following:

    var mainPage = new YouPage().CreateContainer();
    var vBox = new VBox(false, 0);
    vBox.PackEnd(mainPage, true, true, 0);
    var window = new Window("Window Title");
    window.Add(vBox);
    window.ShowAll();

    Where YouPage - your ContentPage.

    But keep in mind that with this use you will lose the ability to set Application to your window.

    CreateContainer() extension is designed to substitute an empty Application with your form and there is nothing to be done about it. And you will need to specify a ResourceDictionary for each Page individually.

    It’s also good practice to implement a service for managing your windows with template methods

    ShowWindow<T>() where T: Page, new ()
    CloseWindow<T>() where T: Page

    You will need the CloseWindow method to close the window using your buttons, for example, “Close” or “Cancel”.

    For close window you must call

    window?.Destroy();
  4. If you want to display a dialog box in this way, then you will need to decide how to transfer the result of the user's response, because Xamarin Page has no interface for this. A service with template methods is also well suited for this purpose:

    ShowDialog<T>(string title, Window parent) where T: Page, new ()
    CloseDialog<T>(bool isConfirm) where T: Page

    Sample for show dialog window:

    try
    {
        var confirmPage = new T().CreateContainer();
        dialog = new Dialog(title, parent, DialogFlags.Modal);
        dialog.VBox.PackEnd(confirmPage, true, true, 0);
        dialog.ShowAll();
        dialog.Run();
    }
    finally { dialog?.Destroy(); }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment