Udostępnij za pośrednictwem


Windows na platformie Xamarin.Mac

W tym artykule opisano pracę z oknami i panelami w aplikacji platformy Xamarin.Mac. W tym artykule opisano tworzenie okien i paneli w środowisku Xcode i narzędziu Interface Builder, ładowanie ich z scenorysów i plików xib oraz pracę z nimi programowo.

Podczas pracy z językiem C# i platformą .NET w aplikacji platformy Xamarin.Mac masz dostęp do tych samych paneli systemu Windows i paneli, które wykonuje deweloper pracujący w Objective-C środowisku I Xcode . Ponieważ platforma Xamarin.Mac integruje się bezpośrednio z programem Xcode, możesz użyć narzędzia Interface Builder środowiska Xcode, aby utworzyć i obsługiwać panele systemu Windows i panele (lub opcjonalnie utworzyć je bezpośrednio w kodzie języka C#).

W zależności od celu aplikacja Xamarin.Mac może przedstawić jeden lub więcej systemu Windows na ekranie w celu zarządzania i koordynowania wyświetlanych informacji i współpracy z nimi. Główne funkcje okna to:

  1. Aby udostępnić obszar, w którym można umieścić widoki i kontrolki oraz zarządzać nimi.
  2. Aby zaakceptować zdarzenia i reagować na nie w odpowiedzi na interakcję użytkownika zarówno z klawiaturą, jak i myszą.

System Windows może być używany w stanie Modeless (na przykład edytor tekstu, który może mieć wiele dokumentów otwieranych jednocześnie) lub modalny (na przykład okno dialogowe Eksportowanie, które musi zostać odrzucone, zanim aplikacja będzie mogła kontynuować).

Panele są specjalnym rodzajem okna (podklasy klasy bazowej NSWindow ), który zazwyczaj pełni funkcję pomocniczą w aplikacji, takich jak okna narzędziowe, takie jak inspektorzy formatu tekstu i systemowy selektor kolorów.

Edytowanie okna w programie Xcode

W tym artykule omówimy podstawy pracy z systemem Windows i panelami w aplikacji platformy Xamarin.Mac. Zdecydowanie zaleca się, aby najpierw zapoznać się z artykułem Hello, Mac , w szczególności wprowadzenie do narzędzi Xcode i Interface Builder i Outlet and Actions , ponieważ obejmuje ona kluczowe pojęcia i techniki, których będziemy używać w tym artykule.

Warto zapoznać się również z sekcją Uwidacznianie klas/ metod Objective-C języka C# w dokumencie Xamarin.Mac Internals . Register Objaśnienie poleceń i Export używanych do podłączania klas języka C# do Objective-C obiektów i elementów interfejsu użytkownika.

Wprowadzenie do okien

Jak wspomniano powyżej, okno zawiera obszar, w którym można umieścić widoki i kontrolki oraz zarządzać nimi i reagować na zdarzenia na podstawie interakcji użytkownika (za pomocą klawiatury lub myszy).

Według Firmy Apple istnieje pięć głównych typów systemu Windows w aplikacji systemu macOS:

  • Okno dokumentu — okno dokumentu zawiera dane użytkownika oparte na plikach, takie jak arkusz kalkulacyjny lub dokument tekstowy.
  • Okno aplikacji — okno aplikacji jest głównym oknem aplikacji, która nie jest oparta na dokumentach (na przykład aplikacja Kalendarz na komputerze Mac).
  • Panel — panel unosi się nad innymi oknami i udostępnia narzędzia lub kontrolki, z którymi użytkownicy mogą pracować, gdy dokumenty są otwarte. W niektórych przypadkach panel może być przezroczysty (na przykład podczas pracy z dużą grafiką).
  • Okno dialogowe — okno dialogowe jest wyświetlane w odpowiedzi na akcję użytkownika i zazwyczaj zapewnia sposób, w jaki użytkownicy mogą wykonać akcję. Okno dialogowe wymaga odpowiedzi od użytkownika, zanim będzie można go zamknąć. (Zobacz Praca z oknami dialogowymi)
  • Alerty — alert jest specjalnym typem okna dialogowego, które pojawia się, gdy wystąpi poważny problem (np. błąd) lub jako ostrzeżenie (np. przygotowanie do usunięcia pliku). Ponieważ alert jest okno dialogowe, wymaga również odpowiedzi użytkownika, zanim będzie można go zamknąć. (Zobacz Praca z alertami)

Aby uzyskać więcej informacji, zobacz sekcję About Windows (Informacje o systemie Windows) motywów projektowych systemu macOS firmy Apple.

Okna główne, klucz i nieaktywne

System Windows w aplikacji platformy Xamarin.Mac może wyglądać i zachowywać się inaczej w zależności od sposobu, w jaki użytkownik obecnie wchodzi z nimi w interakcje. Najważniejsze okno dokumentu lub aplikacji, które jest obecnie fokusem uwagi użytkownika, jest nazywane głównym oknem. W większości przypadków to okno będzie również oknem klucza (oknem, które obecnie akceptuje dane wejściowe użytkownika). Jednak nie zawsze tak jest, na przykład selektor kolorów może być otwarty i być oknem Klucz, z którym użytkownik wchodzi w interakcję, aby zmienić stan elementu w oknie dokumentu (które nadal będzie głównym oknem).

Okna główne i kluczowe (jeśli są oddzielne) są zawsze aktywne, Nieaktywne okna są otwarte okna, które nie znajdują się na pierwszym planie. Na przykład aplikacja edytora tekstów może mieć więcej niż jeden otwarty dokument jednocześnie, tylko okno główne będzie aktywne, a wszystkie inne będą nieaktywne.

Aby uzyskać więcej informacji, zobacz sekcję About Windows (Informacje o systemie Windows) motywów projektowych systemu macOS firmy Apple.

Okna nazewnictwa

Okno może wyświetlać pasek tytułu, a gdy tytuł jest wyświetlany, zazwyczaj jest to nazwa aplikacji, nazwa dokumentu, nad jakim pracujesz, lub funkcja okna (na przykład Inspector). Niektóre aplikacje nie wyświetlają paska tytułu, ponieważ są rozpoznawalne przez widok i nie działają z dokumentami.

Firma Apple sugeruje następujące wytyczne:

  • Użyj nazwy aplikacji jako tytułu głównego okna innego niż dokument.
  • Nadaj nowe okno dokumentu untitlednazwę . W przypadku pierwszego nowego dokumentu nie dołączaj numeru do tytułu (na przykład untitled 1). Jeśli użytkownik utworzy inny nowy dokument przed zapisaniem i podtytuniem pierwszego, wywołaj to okno untitled 2, untitled 3itp.

Aby uzyskać więcej informacji, zobacz sekcję Nazewnictwo systemu Windows w motywach projektowych systemu macOS firmy Apple.

Okna pełnoekranowe

W systemie macOS okno aplikacji może przechodzić w tryb pełnoekranowy ukrywający wszystko, w tym pasek menu aplikacji (który można ujawnić, przenosząc kursor na górę ekranu), aby zapewnić swobodną interakcję z zawartością.

Firma Apple sugeruje następujące wytyczne:

  • Określ, czy ma to sens, aby okno przechodziło w tryb pełnoekranowy. Aplikacje, które zapewniają krótkie interakcje (takie jak Kalkulator), nie powinny zapewniać trybu pełnoekranowego.
  • Pokaż pasek narzędzi, jeśli wymaga tego zadanie pełnoekranowe. Zazwyczaj pasek narzędzi jest ukryty w trybie pełnoekranowym.
  • Okno pełnoekranowe powinno zawierać wszystkie funkcje, które użytkownicy muszą wykonać zadanie.
  • Jeśli to możliwe, unikaj interakcji wyszukiwania, gdy użytkownik znajduje się w oknie pełnoekranowym.
  • Korzystaj ze zwiększonego miejsca na ekranie bez przesuwania fokusu z głównego zadania.

Aby uzyskać więcej informacji, zobacz sekcję Pełnoekranowe okna motywów projektowych systemu macOS firmy Apple.

Panele

Panel to okno pomocnicze zawierające kontrolki i opcje wpływające na aktywny dokument lub wybór (np. systemowy selektor kolorów):

Panel kolorów

Panele mogą być specyficzne dla aplikacji lub Systemwide. Panele specyficzne dla aplikacji są przenoszone w górnej części okien dokumentów aplikacji i znikają, gdy aplikacja znajduje się w tle. Panele systemowe (takie jak panel Czcionki ), unoszą się na wszystkich otwartych oknach niezależnie od aplikacji.

Firma Apple sugeruje następujące wytyczne:

  • Ogólnie rzecz biorąc, należy używać panelu standardowego, przezroczyste panele powinny być używane tylko oszczędnie i do zadań intensywnie korzystających z grafiki.
  • Rozważ użycie panelu, aby zapewnić użytkownikom łatwy dostęp do ważnych kontrolek lub informacji, które bezpośrednio wpływają na ich zadanie.
  • Ukryj i pokaż panele zgodnie z potrzebami.
  • Panele powinny zawsze zawierać pasek tytułu.
  • Panele nie powinny zawierać aktywnego przycisku minimalizuj.

Inspektorów

Większość nowoczesnych aplikacji systemu macOS przedstawia pomocnicze kontrolki i opcje, które mają wpływ na aktywny dokument lub wybór jako inspektorzy , którzy są częścią okna głównego (na przykład w aplikacji Strony pokazane poniżej), zamiast korzystać z panelu Windows:

Przykładowy inspektor

Aby uzyskać więcej informacji, zobacz sekcję Panele motywów projektowych systemu macOS firmy Apple.

Tworzenie i obsługa okien w środowisku Xcode

Podczas tworzenia nowej aplikacji platformy Xamarin.Mac Cocoa domyślnie zostanie wyświetlone standardowe puste okno. Te okna są definiowane w pliku automatycznie dołączonym .storyboard do projektu. Aby edytować projekt systemu Windows, w Eksplorator rozwiązań kliknij Main.storyboard dwukrotnie plik:

Wybieranie głównego scenorysu

Spowoduje to otwarcie projektu okna w narzędziu Interface Builder programu Xcode:

Edytowanie interfejsu użytkownika w środowisku Xcode

W Inspektorze atrybutów istnieje kilka właściwości, których można użyć do definiowania i kontrolowania okna:

  • Tytuł — jest to tekst, który będzie wyświetlany na pasku tytułu okna.
  • Autozapis — jest to klucz , który będzie używany do identyfikatora okna po automatycznym zapisaniu pozycji i ustawień.
  • Pasek tytułu — czy w oknie jest wyświetlany pasek tytułu.
  • Ujednolicony tytuł i pasek narzędzi — jeśli okno zawiera pasek narzędzi, powinien być częścią paska tytułu.
  • Widok zawartości o pełnym rozmiarze — umożliwia wyświetlanie obszaru zawartości okna na pasku tytułu.
  • Cień — czy okno ma cień.
  • Teksturowane - Teksturowane okna mogą używać efektów (takich jak vibrancy) i można je przenosić, przeciągając w dowolnym miejscu na ciele.
  • Zamknij — czy okno ma przycisk zamknięcia.
  • Minimalizuj — czy okno ma przycisk minimalizuj.
  • Zmiana rozmiaru — czy okno ma kontrolkę zmiany rozmiaru.
  • Przycisk paska narzędzi — czy okno ma przycisk ukryj/pokaż pasek narzędzi.
  • Przywracanie — czy pozycja i ustawienia okna są automatycznie zapisywane i przywracane.
  • Widoczne podczas uruchamiania — czy okno jest automatycznie wyświetlane po załadowaniu .xib pliku.
  • Ukryj przy dezaktywacji — czy okno jest ukryte, gdy aplikacja wchodzi w tło.
  • Wydanie po zamknięciu — czy okno jest przeczyszczane z pamięci po zamknięciu.
  • Zawsze wyświetlaj etykietki narzędzi — czy etykietki narzędzi są stale wyświetlane.
  • Ponownie oblicza pętlę widoku — czy kolejność widoku jest obliczana ponownie przed narysowanym oknem.
  • Spaces, Exposé i Cycling — wszystkie definiują, jak działa okno w tych środowiskach systemu macOS.
  • Pełny ekran — określa, czy to okno może wejść w tryb pełnoekranowy.
  • Animacja — określa typ animacji dostępnej dla okna.
  • Wygląd — określa wygląd okna. Na razie jest tylko jeden wygląd, Aqua.

Aby uzyskać więcej informacji, zobacz Wprowadzenie firmy Apple do systemów Windows i NSWindow .

Ustawianie domyślnego rozmiaru i lokalizacji

Aby ustawić początkową pozycję okna i kontrolować jego rozmiar, przejdź do inspektora rozmiaru:

Domyślny rozmiar i lokalizacja

W tym miejscu można ustawić początkowy rozmiar okna, nadać mu minimalny i maksymalny rozmiar, ustawić początkową lokalizację na ekranie i kontrolować obramowania wokół okna.

Ustawianie niestandardowego głównego kontrolera okna

Aby można było utworzyć elementy punktów i akcji w celu uwidocznienia elementów interfejsu użytkownika w kodzie języka C#, aplikacja Xamarin.Mac będzie musiała używać niestandardowego kontrolera okien.

Należy wykonać następujące czynności:

  1. Otwórz scenorys aplikacji w narzędziu Interface Builder programu Xcode.

  2. Wybierz element NSWindowController na powierzchni projektowej.

  3. Przejdź do widoku Inspektor tożsamości i wprowadź WindowController jako nazwę klasy:

    Ustawianie nazwy klasy

  4. Zapisz zmiany i wróć do Visual Studio dla komputerów Mac, aby przeprowadzić synchronizację.

  5. Plik WindowController.cs zostanie dodany do projektu w Eksplorator rozwiązań w Visual Studio dla komputerów Mac:

    Wybieranie kontrolera systemu Windows

  6. Otwórz ponownie scenorys w narzędziu Interface Builder programu Xcode.

  7. Plik WindowController.h będzie dostępny do użycia:

    Edytowanie pliku WindowController.h

Dodawanie elementów interfejsu użytkownika

Aby zdefiniować zawartość okna, przeciągnij kontrolki z Inspektora biblioteki do Edytora interfejsów. Aby uzyskać więcej informacji na temat tworzenia i włączania kontrolek za pomocą narzędzia Interface Builder, zapoznaj się z naszą dokumentacją Wprowadzenie do narzędzi Xcode i Interface Builder .

Na przykład przeciągnijmy pasek narzędzi z Inspektora biblioteki do okna w Edytorze interfejsów:

Wybieranie paska narzędzi z biblioteki

Następnie przeciągnij widok tekstu i rozmiar go, aby wypełnić obszar pod paskiem narzędzi:

Dodawanie widoku tekstowego

Ponieważ chcemy , aby widok tekstu był zmniejszany i zwiększany wraz ze zmianami rozmiaru okna, przejdźmy do edytora ograniczeń i dodajmy następujące ograniczenia:

Edytowanie ograniczeń

Klikając cztery czerwone belki we/w górnej części edytora i klikając pozycję Dodaj 4 ograniczenia, informujemy widok tekstu, aby trzymał się podanych współrzędnych X,Y i zwiększał lub zmniejszał się w poziomie i w pionie, gdy okno jest zmieniane.

Na koniec uwidocznij widok tekstu w kodzie przy użyciu gniazda ( pamiętaj, aby wybrać ViewController.h plik):

Konfigurowanie gniazda

Zapisz zmiany i wróć do Visual Studio dla komputerów Mac, aby przeprowadzić synchronizację z programem Xcode.

Aby uzyskać więcej informacji na temat pracy z placówkami i akcjami, zobacz dokumentację dotyczącą gniazd i akcji.

Standardowy przepływ pracy okna

W przypadku dowolnego okna, z którym tworzysz aplikację platformy Xamarin.Mac i pracujesz z nimi, proces jest zasadniczo taki sam, jak to, co właśnie zrobiliśmy powyżej:

  1. W przypadku nowych okien, które nie są domyślnie dodawane automatycznie do projektu, dodaj nową definicję okna do projektu. Zostanie to szczegółowo omówione poniżej.
  2. Kliknij dwukrotnie plik, Main.storyboard aby otworzyć projekt okna do edycji w narzędziu Xcode Interface Builder.
  3. Przeciągnij nowe okno do projektu interfejsu użytkownika i podłącz okno do okna głównego przy użyciu segues (aby uzyskać więcej informacji, zobacz sekcję Segues w naszej dokumentacji Praca z scenorysami).
  4. Ustaw wszystkie wymagane właściwości okna w Inspektorze atrybutów i Inspektorze rozmiaru.
  5. Przeciągnij kontrolki wymagane do skompilowania interfejsu i skonfiguruj je w Inspektorze atrybutów.
  6. Użyj inspektora rozmiaru, aby obsłużyć zmianę rozmiaru elementów interfejsu użytkownika.
  7. Uwidocznij elementy interfejsu użytkownika okna w kodzie języka C# za pośrednictwem placówek i akcji.
  8. Zapisz zmiany i wróć do Visual Studio dla komputerów Mac, aby przeprowadzić synchronizację z programem Xcode.

Po utworzeniu podstawowego okna przyjrzymy się typowym procesom, które aplikacja platformy Xamarin.Mac wykonuje podczas pracy z systemem Windows.

Wyświetlanie okna domyślnego

Domyślnie nowa aplikacja platformy Xamarin.Mac automatycznie wyświetla okno zdefiniowane w pliku po uruchomieniu MainWindow.xib :

Uruchomione przykładowe okno

Ponieważ zmodyfikowaliśmy projekt tego okna powyżej, zawiera on teraz domyślną kontrolkę Pasek narzędzi i Widok tekstu. Następująca sekcja w Info.plist pliku jest odpowiedzialna za wyświetlenie tego okna:

Edytowanie pliku Info.plist

Lista rozwijana Interfejs główny służy do wybierania scenorysu, który będzie używany jako główny interfejs użytkownika aplikacji (w tym przypadku Main.storyboard).

Kontroler widoku jest automatycznie dodawany do projektu w celu kontrolowania wyświetlanego głównego systemu Windows (wraz z podstawowym widokiem). Jest on zdefiniowany w ViewController.cs pliku i dołączony do właściciela pliku w narzędziu Interface Builder w obszarze Inspektor tożsamości:

Ustawianie właściciela pliku

W naszym oknie chcemy, aby miał tytuł untitled po pierwszym otwarciu, więc przesłońmy metodę ViewWillAppear w pliku , ViewController.cs aby wyglądała następująco:

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

    // Set Window Title
    this.View.Window.Title = "untitled";
}

Uwaga

Właściwość okna jest ustawiona Title w ViewWillAppear metodzie zamiast ViewDidLoad metody, ponieważ podczas gdy widok może zostać załadowany do pamięci, nie jest jeszcze w pełni tworzone. Uzyskanie Title dostępu do właściwości w ViewDidLoad metodzie spowoduje wyjątek null , ponieważ okno nie zostało jeszcze skonstruowane i połączone z właściwością.

Programowe zamykanie okna

Czasami możesz programowo zamknąć okno w aplikacji Xamarin.Mac, inne niż kliknięcie przycisku Zamknij okna lub użycie elementu menu. System macOS oferuje dwa różne sposoby programowego zamykania NSWindow : PerformClose i Close.

PerformClose

PerformClose Wywołanie metody symuluje NSWindow użytkownikowi kliknięcie przycisku Zamknij okna przez chwilowe wyróżnienie przycisku, a następnie zamknięcie okna.

Jeśli aplikacja implementuje NSWindowzdarzenie , WillClose zostanie ono zgłoszone przed zamknięciem okna. Jeśli zdarzenie zwróci falsewartość , okno nie zostanie zamknięte. Jeśli okno nie ma przycisku Zamknij lub nie można go zamknąć z jakiegokolwiek powodu, system operacyjny będzie emitować dźwięk alertu.

Na przykład:

MyWindow.PerformClose(this);

Spróbuje zamknąć MyWindowNSWindow wystąpienie. Jeśli to się powiedzie, okno zostanie zamknięte, a w przeciwnym razie zostanie wyemitowany dźwięk alertu i pozostanie otwarty.

Zamknij

Close Wywołanie metody elementu NSWindow nie symuluje, że użytkownik kliknie przycisk Zamknij okna przez chwilowe wyróżnienie przycisku. Spowoduje to po prostu zamknięcie okna.

Okno nie musi być widoczne, aby zostało zamknięte, a NSWindowWillCloseNotification powiadomienie zostanie opublikowane w domyślnym Centrum powiadomień dla zamykanego okna.

Metoda Close różni się na dwa ważne sposoby od PerformClose metody :

  1. Nie próbuje podnieść WillClose zdarzenia.
  2. Nie symuluje on kliknięcia przycisku Zamknij przez chwilowe wyróżnienie przycisku.

Na przykład:

MyWindow.Close();

Aby zamknąć MyWindowNSWindow wystąpienie.

Zmodyfikowana zawartość systemu Windows

W systemie macOS firma Apple udostępniła użytkownikowi możliwość poinformowania użytkownika, że zawartość okna (NSWindow) została zmodyfikowana przez użytkownika i musi zostać zapisana. Jeśli okno zawiera zmodyfikowaną zawartość, w widżecie Zamknij zostanie wyświetlona mała czarna kropka:

Okno ze zmodyfikowanym znacznikiem

Jeśli użytkownik spróbuje zamknąć okno lub zamknąć aplikację dla komputerów Mac, gdy istnieją niezapisane zmiany zawartości okna, należy przedstawić okno dialogowe lub arkusz modalny i zezwolić użytkownikowi na pierwsze zapisanie zmian:

Arkusz zapisywania wyświetlany po zamknięciu okna

Oznaczanie okna jako zmodyfikowanego

Aby oznaczyć okno jako zmodyfikowanej zawartości, użyj następującego kodu:

// Mark Window content as modified
Window.DocumentEdited = true;

Po zapisaniu zmiany wyczyść zmodyfikowaną flagę przy użyciu:

// Mark Window content as not modified
Window.DocumentEdited = false;

Zapisywanie zmian przed zamknięciem okna

Aby zobaczyć, jak użytkownik zamknął okno i umożliwił mu wcześniejsze zapisanie zmodyfikowanej zawartości, należy utworzyć podklasę NSWindowDelegate i zastąpić jej WindowShouldClose metodę. Na przykład:

using System;
using AppKit;
using System.IO;
using Foundation;

namespace SourceWriter
{
    public class EditorWindowDelegate : NSWindowDelegate
    {
        #region Computed Properties
        public NSWindow Window { get; set;}
        #endregion

        #region constructors
        public EditorWindowDelegate (NSWindow window)
        {
            // Initialize
            this.Window = window;

        }
        #endregion

        #region Override Methods
        public override bool WindowShouldClose (Foundation.NSObject sender)
        {
            // is the window dirty?
            if (Window.DocumentEdited) {
                var alert = new NSAlert () {
                    AlertStyle = NSAlertStyle.Critical,
                    InformativeText = "Save changes to document before closing window?",
                    MessageText = "Save Document",
                };
                alert.AddButton ("Save");
                alert.AddButton ("Lose Changes");
                alert.AddButton ("Cancel");
                var result = alert.RunSheetModal (Window);

                // Take action based on result
                switch (result) {
                case 1000:
                    // Grab controller
                    var viewController = Window.ContentViewController as ViewController;

                    // Already saved?
                    if (Window.RepresentedUrl != null) {
                        var path = Window.RepresentedUrl.Path;

                        // Save changes to file
                        File.WriteAllText (path, viewController.Text);
                        return true;
                    } else {
                        var dlg = new NSSavePanel ();
                        dlg.Title = "Save Document";
                        dlg.BeginSheet (Window, (rslt) => {
                            // File selected?
                            if (rslt == 1) {
                                var path = dlg.Url.Path;
                                File.WriteAllText (path, viewController.Text);
                                Window.DocumentEdited = false;
                                viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
                                viewController.View.Window.RepresentedUrl = dlg.Url;
                                Window.Close();
                            }
                        });
                        return true;
                    }
                    return false;
                case 1001:
                    // Lose Changes
                    return true;
                case 1002:
                    // Cancel
                    return false;
                }
            }

            return true;
        }
        #endregion
    }
}

Użyj następującego kodu, aby dołączyć wystąpienie tego delegata do okna:

// Set delegate
Window.Delegate = new EditorWindowDelegate(Window);

Zapisywanie zmian przed zamknięciem aplikacji

Na koniec aplikacja Xamarin.Mac powinna sprawdzić, czy którykolwiek z jej systemu Windows zawiera zmodyfikowaną zawartość i zezwolić użytkownikowi na zapisanie zmian przed zamknięciem. W tym celu zmodyfikuj AppDelegate.cs plik, zastąpij metodę ApplicationShouldTerminate i utwórz ją tak, jakby wyglądała następująco:

public override NSApplicationTerminateReply ApplicationShouldTerminate (NSApplication sender)
{
    // See if any window needs to be saved first
    foreach (NSWindow window in NSApplication.SharedApplication.Windows) {
        if (window.Delegate != null && !window.Delegate.WindowShouldClose (this)) {
            // Did the window terminate the close?
            return NSApplicationTerminateReply.Cancel;
        }
    }

    // Allow normal termination
    return NSApplicationTerminateReply.Now;
}

Praca z wieloma oknami

Większość aplikacji dla komputerów Mac opartych na dokumentach może jednocześnie edytować wiele dokumentów. Na przykład edytor tekstów może mieć wiele otwartych plików tekstowych do edycji w tym samym czasie. Domyślnie nowa aplikacja platformy Xamarin.Mac ma menu Plik z automatycznie podłączonym elementem Nowy do newDocument:akcji.

Poniższy kod aktywuje ten nowy element i umożliwi użytkownikowi otwarcie wielu kopii okna głównego w celu jednoczesnego edytowania wielu dokumentów.

AppDelegate.cs Edytuj plik i dodaj następującą obliczoną właściwość:

public int UntitledWindowCount { get; set;} =1;

Służy do śledzenia liczby niezapisanych plików, abyśmy mogli przekazać opinię użytkownikowi (zgodnie z wytycznymi firmy Apple opisanymi powyżej).

Następnie dodaj następującą metodę:

[Export ("newDocument:")]
void NewDocument (NSObject sender) {
    // Get new window
    var storyboard = NSStoryboard.FromName ("Main", null);
    var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

    // Display
    controller.ShowWindow(this);

    // Set the title
    controller.Window.Title = (++UntitledWindowCount == 1) ? "untitled" : string.Format ("untitled {0}", UntitledWindowCount);
}

Ten kod tworzy nową wersję naszego kontrolera okien, ładuje nowe okno, sprawia, że jest on głównym i kluczowym oknem i ustawia tytuł. Teraz, jeśli uruchomimy naszą aplikację i wybierzemy pozycję Nowy z menu Plik , zostanie otwarte i wyświetlone nowe okno edytora:

Dodano nowe okno bez tytułu

Jeśli otworzymy menu systemu Windows , zobaczysz, że aplikacja jest automatycznie śledzona i obsługuje otwarte okna:

Menu okien

Aby uzyskać więcej informacji na temat pracy z menu w aplikacji platformy Xamarin.Mac, zobacz dokumentację Praca z menu .

Pobieranie aktualnie aktywnego okna

W aplikacji platformy Xamarin.Mac, która może otwierać wiele okien (dokumentów), istnieją czasy, w których konieczne będzie pobranie bieżącego, najwyższego poziomu okna (okna klucza). Poniższy kod zwróci okno klucza:

var window = NSApplication.SharedApplication.KeyWindow;

Może być wywoływana w dowolnej klasie lub metodzie, która musi uzyskać dostęp do bieżącego okna klucza. Jeśli okno nie jest obecnie otwarte, zostanie zwrócone polecenie null.

Uzyskiwanie dostępu do wszystkich okien aplikacji

Czasami konieczne może być uzyskanie dostępu do wszystkich okien, które aplikacja Xamarin.Mac jest obecnie otwarta. Na przykład, aby sprawdzić, czy plik, który użytkownik chce otworzyć, jest już otwarty w oknie zakończenia.

Obiekt NSApplication.SharedApplication obsługuje właściwość zawierającą Windows tablicę wszystkich otwartych okien w aplikacji. Możesz iterować tę tablicę, aby uzyskać dostęp do wszystkich bieżących okien aplikacji. Na przykład:

// Is the file already open?
for(int n=0; n<NSApplication.SharedApplication.Windows.Length; ++n) {
    var content = NSApplication.SharedApplication.Windows[n].ContentViewController as ViewController;
    if (content != null && path == content.FilePath) {
        // Bring window to front
        NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);
        return true;
    }
}

W przykładowym kodzie rzutujemy każde zwrócone okno do klasy niestandardowej ViewController w naszej aplikacji i testuje wartość właściwości niestandardowej Path względem ścieżki pliku, który użytkownik chce otworzyć. Jeśli plik jest już otwarty, wprowadzamy to okno z przodu.

Dostosowywanie rozmiaru okna w kodzie

Czasami aplikacja musi zmienić rozmiar okna w kodzie. Aby zmienić rozmiar i położenie okna, dostosuj jego Frame właściwość. Podczas dostosowywania rozmiaru okna zwykle trzeba go również dostosować do źródła, aby zachować okno w tej samej lokalizacji ze względu na układ współrzędnych systemu macOS.

W przeciwieństwie do systemu iOS, w którym lewy górny róg reprezentuje (0,0), system macOS używa systemu współrzędnych matematycznych, w którym w lewym dolnym rogu ekranu reprezentuje (0,0). W systemie iOS współrzędne rosną w miarę przechodzenia w dół w prawo. W systemie macOS współrzędne zwiększają wartość w górę do prawej.

Poniższy przykładowy kod zmienia rozmiar okna:

nfloat y = 0;

// Calculate new origin
y = Frame.Y - (768 - Frame.Height);

// Resize and position window
CGRect frame = new CGRect (Frame.X, y, 1024, 768);
SetFrame (frame, true);

Ważne

Podczas dostosowywania rozmiaru okna i lokalizacji w kodzie należy upewnić się, że przestrzegasz minimalnych i maksymalnych rozmiarów ustawionych w narzędziu Interface Builder. Nie zostanie to automatycznie uznane i będzie można zwiększyć lub zmniejszyć okno niż te limity.

Zmiany rozmiaru okna monitorowania

Czasami trzeba monitorować zmiany rozmiaru okna w aplikacji Xamarin.Mac. Na przykład aby ponownie wyrysować zawartość w celu dopasowania do nowego rozmiaru.

Aby monitorować zmiany rozmiaru, najpierw upewnij się, że przypisano klasę niestandardową dla kontrolera okien w narzędziu Xcode Interface Builder. Na przykład MasterWindowController w następujących celach:

Inspektor tożsamości

Następnie zmodyfikuj niestandardową klasę Kontrolera okien i monitoruj DidResize zdarzenie w oknie kontrolera, aby otrzymywać powiadomienia o zmianach rozmiaru na żywo. Na przykład:

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

    Window.DidResize += (sender, e) => {
        // Do something as the window is being live resized
    };
}

Opcjonalnie możesz użyć DidEndLiveResize zdarzenia, aby otrzymywać powiadomienia tylko po zakończeniu zmiany rozmiaru okna przez użytkownika. Na przykład:

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

        Window.DidEndLiveResize += (sender, e) => {
        // Do something after the user's finished resizing
        // the window
    };
}

Ustawianie tytułu okna i reprezentowanego pliku

W przypadku pracy z oknami reprezentującymi dokumenty ma DocumentEdited właściwość , NSWindow która jeśli jest ustawiona na true małą kropkę w przycisku Zamknij, aby nadać użytkownikowi wskazanie, że plik został zmodyfikowany i powinien zostać zapisany przed zamknięciem.

Zmodyfikujmy nasz ViewController.cs plik i wprowadźmy następujące zmiany:

public bool DocumentEdited {
    get { return View.Window.DocumentEdited; }
    set { View.Window.DocumentEdited = value; }
}
...

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

    // Set Window Title
    this.View.Window.Title = "untitled";

    View.Window.WillClose += (sender, e) => {
        // is the window dirty?
        if (DocumentEdited) {
            var alert = new NSAlert () {
                AlertStyle = NSAlertStyle.Critical,
                InformativeText = "We need to give the user the ability to save the document here...",
                MessageText = "Save Document",
            };
            alert.RunModal ();
        }
    };
}

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

    // Show when the document is edited
    DocumentEditor.TextDidChange += (sender, e) => {
        // Mark the document as dirty
        DocumentEdited = true;
    };

    // Overriding this delegate is required to monitor the TextDidChange event
    DocumentEditor.ShouldChangeTextInRanges += (NSTextView view, NSValue[] values, string[] replacements) => {
        return true;
    };

}

Monitorujemy WillClose również zdarzenie w oknie i sprawdzamy stan DocumentEdited właściwości. Jeśli jest true to konieczne, należy dać użytkownikowi możliwość zapisania zmian w pliku. Jeśli uruchomimy aplikację i wprowadzimy jakiś tekst, zostanie wyświetlona kropka:

Zmienione okno

Jeśli spróbujesz zamknąć okno, otrzymasz alert:

Wyświetlanie okna dialogowego zapisywania

Jeśli ładujesz dokument z pliku, ustaw tytuł okna na nazwę pliku przy użyciu window.SetTitleWithRepresentedFilename (Path.GetFileName(path)); metody (biorąc pod uwagę, że path jest to ciąg reprezentujący otwierany plik). Ponadto można ustawić adres URL pliku przy użyciu window.RepresentedUrl = url; metody .

Jeśli adres URL wskazuje typ pliku znany przez system operacyjny, jego ikona będzie wyświetlana na pasku tytułu. Jeśli użytkownik kliknie prawym przyciskiem myszy ikonę, zostanie wyświetlona ścieżka do pliku.

AppDelegate.cs Edytuj plik i dodaj następującą metodę:

[Export ("openDocument:")]
void OpenDialog (NSObject sender)
{
    var dlg = NSOpenPanel.OpenPanel;
    dlg.CanChooseFiles = true;
    dlg.CanChooseDirectories = false;

    if (dlg.RunModal () == 1) {
        // Nab the first file
        var url = dlg.Urls [0];

        if (url != null) {
            var path = url.Path;

            // Get new window
            var storyboard = NSStoryboard.FromName ("Main", null);
            var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

            // Display
            controller.ShowWindow(this);

            // Load the text into the window
            var viewController = controller.Window.ContentViewController as ViewController;
            viewController.Text = File.ReadAllText(path);
                    viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
            viewController.View.Window.RepresentedUrl = url;

        }
    }
}

Teraz, jeśli uruchomimy naszą aplikację, wybierz pozycję Otwórz... z menu Plik , wybierz plik tekstowy w oknie dialogowym Otwórz i otwórz go:

Otwarte okno dialogowe

Zostanie wyświetlony plik, a tytuł zostanie ustawiony z ikoną pliku:

Zawartość załadowanego pliku

Dodawanie nowego okna do projektu

Oprócz głównego okna dokumentu aplikacja Xamarin.Mac może wymagać wyświetlenia innych typów okien dla użytkownika, takich jak Preferencje lub Panele inspektorów.

Aby dodać nowe okno, wykonaj następujące czynności:

  1. W Eksplorator rozwiązań kliknij Main.storyboard dwukrotnie plik, aby otworzyć go do edycji w narzędziu Xcode Interface Builder.

  2. Przeciągnij nowy kontroler okna z biblioteki i upuść go na powierzchni projektowej:

    Wybieranie nowego kontrolera okna w bibliotece

  3. W inspektorze tożsamości wprowadź PreferencesWindow identyfikator scenorysu:

    Ustawianie identyfikatora scenorysu

  4. Projektowanie interfejsu:

    Projektowanie interfejsu użytkownika

  5. Otwórz menu aplikacji (MacWindows), wybierz pozycję Preferencje..., Kliknij kontrolkę i przeciągnij do nowego okna:

    Tworzenie segue'a

  6. Wybierz pozycję Pokaż z menu podręcznego.

  7. Zapisz zmiany i wróć do Visual Studio dla komputerów Mac, aby przeprowadzić synchronizację z programem Xcode.

Jeśli uruchomimy kod i wybierzemy pozycję Preferencje... z menu Aplikacji, zostanie wyświetlone okno:

Menu preferencji przykładowych

Praca z panelami

Jak określono na początku tego artykułu, panel unosi się nad innymi oknami i udostępnia narzędzia lub kontrolki, z którymi użytkownicy mogą pracować, gdy dokumenty są otwarte.

Podobnie jak w przypadku każdego innego typu okna, z którym tworzysz i pracujesz w aplikacji platformy Xamarin.Mac, proces jest w zasadzie taki sam:

  1. Dodaj nową definicję okna do projektu.
  2. Kliknij dwukrotnie plik, .xib aby otworzyć projekt okna do edycji w narzędziu Xcode Interface Builder.
  3. Ustaw wszystkie wymagane właściwości okna w Inspektorze atrybutów i Inspektorze rozmiaru.
  4. Przeciągnij kontrolki wymagane do skompilowania interfejsu i skonfiguruj je w Inspektorze atrybutów.
  5. Użyj inspektora rozmiaru, aby obsłużyć zmianę rozmiaru elementów interfejsu użytkownika.
  6. Uwidocznij elementy interfejsu użytkownika okna w kodzie języka C# za pośrednictwem placówek i akcji.
  7. Zapisz zmiany i wróć do Visual Studio dla komputerów Mac, aby przeprowadzić synchronizację z programem Xcode.

W Inspektorze atrybutów dostępne są następujące opcje specyficzne dla paneli:

Inspektor atrybutów

  • Styl — umożliwia dostosowanie stylu panelu z: Zwykły panel (wygląda jak standardowe okno), Panel narzędzi (ma mniejszy pasek tytułu), panel HUD (jest przezroczysty, a pasek tytułu jest częścią tła).
  • Nieaktywowanie — określa w panelu okno klucza.
  • Modalny dokument — jeśli modalny dokument, panel będzie unosić się tylko nad oknami aplikacji, a także unosi się powyżej wszystkich.

Aby dodać nowy panel, wykonaj następujące czynności:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj>nowy plik....

  2. W oknie dialogowym Nowy plik wybierz pozycję Okno Xamarin.Mac>Cocoa z kontrolerem:

    Dodawanie nowego kontrolera okna

  3. Wprowadź DocumentPanel nazwę i kliknij przycisk Nowy.

  4. Kliknij dwukrotnie plik, aby otworzyć go do edycji w narzędziu DocumentPanel.xib Interface Builder:

    Edytowanie panelu

  5. Usuń istniejące okno i przeciągnij panel z inspektora biblioteki w Edytorze interfejsu:

    Usuwanie istniejącego okna

  6. Podłącz panel do okna - Właściciel - pliku Wyjście:

    Przeciąganie w górę panelu

  7. Przejdź do inspektora tożsamości i ustaw klasę Panel na :DocumentPanel

    Ustawianie klasy panelu

  8. Zapisz zmiany i wróć do Visual Studio dla komputerów Mac, aby przeprowadzić synchronizację z programem Xcode.

  9. DocumentPanel.cs Edytuj plik i zmień definicję klasy na następujące:

    public partial class DocumentPanel : NSPanel

  10. Zapisz zmiany w pliku.

AppDelegate.cs Edytuj plik i utwórz metodę DidFinishLaunching podobną do następującej:

public override void DidFinishLaunching (NSNotification notification)
{
        // Display panel
    var panel = new DocumentPanelController ();
    panel.Window.MakeKeyAndOrderFront (this);
}

Jeśli uruchomimy aplikację, zostanie wyświetlony panel:

Panel w uruchomionej aplikacji

Ważne

System Windows panelu został przestarzały przez firmę Apple i powinien zostać zastąpiony interfejsami Inspector Interfaces.

Podsumowanie

W tym artykule szczegółowo przedstawiono pracę z systemem Windows i panelami w aplikacji platformy Xamarin.Mac. Zobaczyliśmy różne typy i zastosowania okien i paneli, jak tworzyć i obsługiwać okna i panele w narzędziu Interface Builder programu Xcode oraz jak pracować z systemami Windows i Panele w kodzie języka C#.