Widoki konspektu na platformie Xamarin.Mac

W tym artykule opisano pracę z widokami konspektu w aplikacji platformy Xamarin.Mac. W tym artykule opisano tworzenie i konserwowanie widoków konspektu w programie Xcode i narzędziu Interface Builder oraz pracę z nimi programowo.

Podczas pracy z językami C# i .NET w aplikacji platformy Xamarin.Mac masz dostęp do tych samych widoków konspektu, 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 do tworzenia i obsługi widoków konspektu (lub opcjonalnie tworzenia ich bezpośrednio w kodzie języka C#).

Widok konspektu to typ tabeli, który umożliwia użytkownikowi rozwijanie lub zwijanie wierszy danych hierarchicznych. Podobnie jak widok tabeli, widok konspektu wyświetla dane dla zestawu elementów pokrewnych z wierszami reprezentującymi poszczególne elementy i kolumny reprezentujące atrybuty tych elementów. W przeciwieństwie do widoku tabeli elementy w widoku konspektu nie znajdują się na płaskiej liście, są zorganizowane w hierarchii, takich jak pliki i foldery na dysku twardym.

An example app run

W tym artykule omówimy podstawy pracy z widokami konspektu 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 widoków konspektu

Widok konspektu to typ tabeli, który umożliwia użytkownikowi rozwijanie lub zwijanie wierszy danych hierarchicznych. Podobnie jak widok tabeli, widok konspektu wyświetla dane dla zestawu elementów pokrewnych z wierszami reprezentującymi poszczególne elementy i kolumny reprezentujące atrybuty tych elementów. W przeciwieństwie do widoku tabeli elementy w widoku konspektu nie znajdują się na płaskiej liście, są zorganizowane w hierarchii, takich jak pliki i foldery na dysku twardym.

Jeśli element w widoku konspektu zawiera inne elementy, można go rozwinąć lub zwinąć przez użytkownika. Element rozwijany wyświetla trójkąt ujawniający, który wskazuje na prawo po zwinięciu elementu i wskazuje go w dół po rozwinięciu elementu. Kliknięcie trójkąta ujawniania powoduje rozwinięcie lub zwinięcie elementu.

Widok konspektu (NSOutlineView) jest podklasą widoku tabeli (NSTableView), a w związku z tym dziedziczy znaczną część swojego zachowania z klasy nadrzędnej. W związku z tym wiele operacji obsługiwanych przez widok tabeli, takich jak wybieranie wierszy lub kolumn, zmiana położenia kolumn przez przeciąganie nagłówków kolumn itp., są również obsługiwane przez widok konspektu. Aplikacja Xamarin.Mac ma kontrolę nad tymi funkcjami i może skonfigurować parametry widoku konspektu (w kodzie lub narzędziu Interface Builder), aby zezwalać na niektóre operacje lub nie zezwalać na nie.

Widok konspektu nie przechowuje własnych danych, zamiast tego opiera się na źródle danych (NSOutlineViewDataSource), aby zapewnić wymagane zarówno wiersze, jak i kolumny zgodnie z potrzebami.

Zachowanie widoku konspektu można dostosować, udostępniając podklasę delegata widoku konspektu (NSOutlineViewDelegate), aby obsługiwać zarządzanie kolumnami konspektu, typ, aby wybrać funkcje, wybór wiersza i edytowanie, śledzenie niestandardowe i widoki niestandardowe dla poszczególnych kolumn i wierszy.

Ponieważ widok konspektu udostępnia większość jego zachowań i funkcji w widoku tabeli, warto zapoznać się z naszą dokumentacją widoków tabel przed kontynuowaniem pracy z tym artykułem.

Tworzenie i obsługa widoków konspektu w programie 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:

Selecting the main storyboard

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

Editing the UI in Xcode

Wpisz outline w polu wyszukiwania Inspektora biblioteki, aby ułatwić znajdowanie kontrolek Widok konspektu:

Selecting an Outline View from the Library

Przeciągnij widok konspektu na kontroler widoku w Edytorze interfejsu, wypełnij obszar zawartości kontrolera widoku i ustaw go na miejsce, w którym zmniejsza się i rośnie wraz z oknem w Edytorze ograniczeń:

Editing the constraints

Wybierz widok konspektu w hierarchii interfejsu, a następujące właściwości są dostępne w Inspektorze atrybutów:

Screenshot shows the properties available in the Attribute Inspector.

  • Kolumna konspektu — kolumna tabeli, w której są wyświetlane dane hierarchiczne.
  • Automatyczne zapisywanie kolumny konspektu — jeśli truekolumna konspektu zostanie automatycznie zapisana i przywrócona między uruchomionymi aplikacjami.
  • Wcięcie — wielkość wcięcia kolumn w rozwiniętym elemencie.
  • Wcięcie następuje po komórkach — jeśli trueznak wcięcia zostanie wcięcie wraz z komórkami.
  • Automatyczne zapisywanie rozwiniętych elementów — jeśli truestan rozwiniętego/zwiniętego elementu zostanie automatycznie zapisany i przywrócony między uruchomieniem aplikacji.
  • Tryb zawartości — umożliwia wyświetlanie danych w wierszach i kolumnach przy użyciu widoków (NSView) lub komórek (NSCell). Począwszy od systemu macOS 10.7, należy użyć widoków.
  • Liczba zmiennoprzecinkowa Grupuj wiersze — jeśli truewidok tabeli będzie rysować pogrupowane komórki tak, jakby były przestawne.
  • Kolumny — definiuje liczbę wyświetlanych kolumn.
  • Nagłówki — jeśli truekolumny będą miały nagłówki.
  • Zmiana kolejności — jeśli trueużytkownik będzie mógł przeciągnąć kolejność kolumn w tabeli.
  • Zmiana rozmiaru — jeśli trueużytkownik będzie mógł przeciągać nagłówki kolumn w celu zmiany rozmiaru kolumn.
  • Ustalanie rozmiaru kolumn — określa sposób automatycznego rozmiaru kolumn tabeli.
  • Wyróżnienie — określa typ wyróżniania tabeli, który jest używany podczas wybierania komórki.
  • Alternatywne wiersze — jeśli truekiedykolwiek inny wiersz będzie miał inny kolor tła.
  • Siatka pozioma — wybiera typ obramowania rysowanego między komórkami poziomo.
  • Siatka pionowa — wybiera typ obramowania rysowanego między komórkami w pionie.
  • Kolor siatki — ustawia kolor obramowania komórki.
  • Tło — ustawia kolor tła komórki.
  • Wybór — umożliwia kontrolowanie sposobu wybierania komórek w tabeli przez użytkownika jako:
    • Wiele — jeśli trueużytkownik może wybrać wiele wierszy i kolumn.
    • Kolumna — jeśli trueużytkownik może wybrać kolumny.
    • Typ Wybierz — jeśli trueużytkownik może wpisać znak, aby wybrać wiersz.
    • Puste — jeśli trueużytkownik nie jest wymagany do wybrania wiersza lub kolumny, tabela w ogóle nie zezwala na wybór.
  • Autozapis — nazwa, w ramach którego format tabel jest zapisywany automatycznie.
  • Informacje o kolumnie — jeśli truekolejność i szerokość kolumn zostaną automatycznie zapisane.
  • Podziały wierszy — wybierz sposób obsługi podziałów wierszy przez komórkę.
  • Obcina ostatnią widoczną linię — jeśli truekomórka zostanie obcięta w danych, nie mieści się w granicach.

Ważne

Jeśli nie utrzymujesz starszej aplikacji platformy Xamarin.Mac, NSView widoki konspektu na podstawie powinny być używane w NSCell oparciu o widoki tabel. NSCell jest uważana za starszą i może nie być obsługiwana w przyszłości.

Wybierz kolumnę tabeli w hierarchii interfejsu, a w Inspektorze atrybutów są dostępne następujące właściwości:

Screenshot shows the properties available for the selected table column in the Attribute Inspector.

  • Title — ustawia tytuł kolumny.
  • Wyrównanie — ustawianie wyrównania tekstu w komórkach.
  • Czcionka tytułu — wybiera czcionkę dla tekstu nagłówka komórki.
  • Klucz sortowania — jest kluczem używanym do sortowania danych w kolumnie. Pozostaw pole puste, jeśli użytkownik nie może posortować tej kolumny.
  • Selektor — czy akcja służy do sortowania. Pozostaw pole puste, jeśli użytkownik nie może posortować tej kolumny.
  • Order — to kolejność sortowania danych kolumn.
  • Zmiana rozmiaru — wybiera typ zmiany rozmiaru kolumny.
  • Edytowalne — jeśli trueużytkownik może edytować komórki w tabeli opartej na komórkach.
  • Ukryte — jeśli truekolumna jest ukryta.

Możesz również zmienić rozmiar kolumny, przeciągając uchwyt (w pionie wyśrodkowany po prawej stronie kolumny) w lewo lub w prawo.

Wybierzmy każdą kolumnę w widoku tabeli i nadajmy pierwszej kolumnie tytułProduct i drugą Detailskolumnę .

Wybierz widok komórki tabeli (NSTableViewCell) w hierarchii interfejsu i następujące właściwości są dostępne w Inspektorze atrybutów:

Screenshot shows the properties available for the selected table cell in the Attribute Inspector.

Są to wszystkie właściwości widoku standardowego. Istnieje również możliwość zmiany rozmiaru wierszy dla tej kolumny tutaj.

Wybierz komórkę widoku tabeli (domyślnie jest NSTextFieldto ) w hierarchii interfejsu, a następujące właściwości są dostępne w Inspektorze atrybutów:

Screenshot shows the properties available for the selected table view cell in the Attribute Inspector.

Wszystkie właściwości standardowego pola tekstowego zostaną ustawione tutaj. Domyślnie standardowe pole tekstowe służy do wyświetlania danych dla komórki w kolumnie.

Wybierz widok komórki tabeli (NSTableFieldCell) w hierarchii interfejsu i następujące właściwości są dostępne w Inspektorze atrybutów:

Screenshot shows the properties available for the selected table view cell.

Najważniejsze ustawienia są następujące:

  • Układ — wybierz sposób, w jaki komórki w tej kolumnie są ułożone.
  • Używa trybu pojedynczego wiersza — jeśli truekomórka jest ograniczona do pojedynczego wiersza.
  • Pierwsza szerokość układu środowiska uruchomieniowego — jeśli truekomórka będzie preferować ustawioną szerokość (ręcznie lub automatycznie), gdy jest wyświetlana po pierwszym uruchomieniu aplikacji.
  • Akcja — określa, kiedy akcja edycji jest wysyłana dla komórki.
  • Zachowanie — określa, czy komórka jest wybierana lub edytowalna.
  • Tekst sformatowany — jeśli truekomórka może wyświetlać sformatowany i stylizowany tekst.
  • Cofnij — jeśli truekomórka przejmuje odpowiedzialność za jego zachowanie cofania.

Wybierz widok komórki tabeli (NSTableFieldCell) w dolnej części kolumny tabeli w hierarchii interfejsu:

Selecting the table cell view

Dzięki temu można edytować widok komórek tabeli używany jako podstawowy wzorzec dla wszystkich komórek utworzonych dla danej kolumny.

Dodawanie akcji i gniazd

Podobnie jak w przypadku każdej innej kontrolki interfejsu użytkownika platformy Cocoa, musimy uwidocznić widok konspektu oraz kolumny i komórki w kodzie języka C# przy użyciu akcji i punktów sprzedaży (na podstawie wymaganych funkcji).

Proces jest taki sam dla każdego elementu widoku konspektu, który chcemy uwidocznić:

  1. Przejdź do Edytora asystentów i upewnij się, że ViewController.h plik został wybrany:

    Selecting the correct .h file

  2. Wybierz widok konspektu z hierarchii interfejsu, kliknij kontrolkę i przeciągnij do ViewController.h pliku.

  3. Utwórz gniazdo dla widoku konspektu o nazwie ProductOutline:

    Screenshot shows an Outlet called ProductOutline in the Attribute Inspector.

  4. Utwórz punkty dla kolumn tabel, a także o nazwie ProductColumn i DetailsColumn:

    Screenshot shows an Outlet named DetailsColumn in the Attribute Inspector.

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

Następnie napiszemy kod wyświetlając dane konspektu po uruchomieniu aplikacji.

Wypełnianie widoku konspektu

W naszym widoku konspektu zaprojektowanym w narzędziu Interface Builder i uwidocznieniu za pośrednictwem gniazda musimy utworzyć kod języka C#, aby go wypełnić.

Najpierw utwórzmy nową Product klasę do przechowywania informacji dla poszczególnych wierszy i grup produktów podrzędnych. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj>nowy plik... Wybierz pozycję Ogólna>Pusta klasa, wprowadź Product nazwęi kliknij przycisk Nowy:

Creating an empty class

Product.cs Utwórz plik w następujący sposób:

using System;
using Foundation;
using System.Collections.Generic;

namespace MacOutlines
{
    public class Product : NSObject
    {
        #region Public Variables
        public List<Product> Products = new List<Product>();
        #endregion

        #region Computed Properties
        public string Title { get; set;} = "";
        public string Description { get; set;} = "";
        public bool IsProductGroup {
            get { return (Products.Count > 0); }
        }
        #endregion

        #region Constructors
        public Product ()
        {
        }

        public Product (string title, string description)
        {
            this.Title = title;
            this.Description = description;
        }
        #endregion
    }
}

Następnie musimy utworzyć podklasę, aby podać dane dla naszego konspektu NSOutlineDataSource zgodnie z żądaniem. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj>nowy plik... Wybierz pozycję Ogólna>Pusta klasa, wprowadź ProductOutlineDataSource nazwęi kliknij przycisk Nowy.

Zmodyfikuj ProductTableDataSource.cs plik i utwórz go w następujący sposób:

using System;
using AppKit;
using CoreGraphics;
using Foundation;
using System.Collections;
using System.Collections.Generic;

namespace MacOutlines
{
    public class ProductOutlineDataSource : NSOutlineViewDataSource
    {
        #region Public Variables
        public List<Product> Products = new List<Product>();
        #endregion

        #region Constructors
        public ProductOutlineDataSource ()
        {
        }
        #endregion

        #region Override Methods
        public override nint GetChildrenCount (NSOutlineView outlineView, NSObject item)
        {
            if (item == null) {
                return Products.Count;
            } else {
                return ((Product)item).Products.Count;
            }

        }

        public override NSObject GetChild (NSOutlineView outlineView, nint childIndex, NSObject item)
        {
            if (item == null) {
                return Products [childIndex];
            } else {
                return ((Product)item).Products [childIndex];
            }

        }

        public override bool ItemExpandable (NSOutlineView outlineView, NSObject item)
        {
            if (item == null) {
                return Products [0].IsProductGroup;
            } else {
                return ((Product)item).IsProductGroup;
            }

        }
        #endregion
    }
}

Ta klasa zawiera magazyn elementów widoku konspektu i zastępuje GetChildrenCount element , aby zwrócić liczbę wierszy w tabeli. Funkcja GetChild zwraca określony element nadrzędny lub podrzędny (zgodnie z żądaniem widoku konspektu) i ItemExpandable definiuje określony element jako element nadrzędny lub podrzędny.

Na koniec musimy utworzyć podklasę, NSOutlineDelegate aby zapewnić zachowanie naszego konspektu. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj>nowy plik... Wybierz pozycję Ogólna>Pusta klasa, wprowadź ProductOutlineDelegate nazwęi kliknij przycisk Nowy.

Zmodyfikuj ProductOutlineDelegate.cs plik i utwórz go w następujący sposób:

using System;
using AppKit;
using CoreGraphics;
using Foundation;
using System.Collections;
using System.Collections.Generic;

namespace MacOutlines
{
    public class ProductOutlineDelegate : NSOutlineViewDelegate
    {
        #region Constants
        private const string CellIdentifier = "ProdCell";
        #endregion

        #region Private Variables
        private ProductOutlineDataSource DataSource;
        #endregion

        #region Constructors
        public ProductOutlineDelegate (ProductOutlineDataSource datasource)
        {
            this.DataSource = datasource;
        }
        #endregion

        #region Override Methods

        public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
            // This pattern allows you reuse existing views when they are no-longer in use.
            // If the returned view is null, you instance up a new view
            // If a non-null view is returned, you modify it enough to reflect the new data
            NSTextField view = (NSTextField)outlineView.MakeView (CellIdentifier, this);
            if (view == null) {
                view = new NSTextField ();
                view.Identifier = CellIdentifier;
                view.BackgroundColor = NSColor.Clear;
                view.Bordered = false;
                view.Selectable = false;
                view.Editable = false;
            }

            // Cast item
            var product = item as Product;

            // Setup view based on the column selected
            switch (tableColumn.Title) {
            case "Product":
                view.StringValue = product.Title;
                break;
            case "Details":
                view.StringValue = product.Description;
                break;
            }

            return view;
        }
        #endregion
    }
}

Podczas tworzenia wystąpienia obiektu przekazujemy również wystąpienie ProductOutlineDelegateProductOutlineDataSource obiektu , które dostarcza dane dla konspektu. Metoda GetView jest odpowiedzialna za zwracanie widoku (danych) w celu wyświetlenia komórki dla kolumny i wiersza. Jeśli to możliwe, istniejący widok zostanie ponownie użyty do wyświetlenia komórki, jeśli nie zostanie utworzony nowy widok.

Aby wypełnić konspekt, edytujmy MainWindow.cs plik i utwórzmy metodę AwakeFromNib podobną do następującej:

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

    // Create data source and populate
    var DataSource = new ProductOutlineDataSource ();

    var Vegetables = new Product ("Vegetables", "Greens and Other Produce");
    Vegetables.Products.Add (new Product ("Cabbage", "Brassica oleracea - Leaves, axillary buds, stems, flowerheads"));
    Vegetables.Products.Add (new Product ("Turnip", "Brassica rapa - Tubers, leaves"));
    Vegetables.Products.Add (new Product ("Radish", "Raphanus sativus - Roots, leaves, seed pods, seed oil, sprouting"));
    Vegetables.Products.Add (new Product ("Carrot", "Daucus carota - Root tubers"));
    DataSource.Products.Add (Vegetables);

    var Fruits = new Product ("Fruits", "Fruit is a part of a flowering plant that derives from specific tissues of the flower");
    Fruits.Products.Add (new Product ("Grape", "True Berry"));
    Fruits.Products.Add (new Product ("Cucumber", "Pepo"));
    Fruits.Products.Add (new Product ("Orange", "Hesperidium"));
    Fruits.Products.Add (new Product ("Blackberry", "Aggregate fruit"));
    DataSource.Products.Add (Fruits);

    var Meats = new Product ("Meats", "Lean Cuts");
    Meats.Products.Add (new Product ("Beef", "Cow"));
    Meats.Products.Add (new Product ("Pork", "Pig"));
    Meats.Products.Add (new Product ("Veal", "Young Cow"));
    DataSource.Products.Add (Meats);

    // Populate the outline
    ProductOutline.DataSource = DataSource;
    ProductOutline.Delegate = new ProductOutlineDelegate (DataSource);

}

Jeśli uruchomimy aplikację, zostanie wyświetlona następująca wartość:

The collapsed view

Jeśli rozszerzymy węzeł w widoku konspektu, będzie on wyglądać następująco:

The expanded view

Sortowanie według kolumny

Zezwólmy użytkownikowi na sortowanie danych w konspekcie, klikając nagłówek kolumny. Najpierw kliknij dwukrotnie plik, aby otworzyć go do edycji w narzędziu Main.storyboard Interface Builder. Wybierz kolumnęProduct, wprowadź dla Titlepola Sort Key ( compare: Klucz sortowania) dla selektora i wybierz pozycję Ascending Order (Kolejność):

Setting the sort key order

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

Teraz edytujemy ProductOutlineDataSource.cs plik i dodajmy następujące metody:

public void Sort(string key, bool ascending) {

    // Take action based on key
    switch (key) {
    case "Title":
        if (ascending) {
            Products.Sort ((x, y) => x.Title.CompareTo (y.Title));
        } else {
            Products.Sort ((x, y) => -1 * x.Title.CompareTo (y.Title));
        }
        break;
    }
}

public override void SortDescriptorsChanged (NSOutlineView outlineView, NSSortDescriptor[] oldDescriptors)
{
    // Sort the data
    Sort (oldDescriptors [0].Key, oldDescriptors [0].Ascending);
    outlineView.ReloadData ();
}

Metoda Sort umożliwia sortowanie danych w źródle danych na podstawie danego Product pola klasy w kolejności rosnącej lub malejącej. Przesłonięta SortDescriptorsChanged metoda będzie wywoływana za każdym razem, gdy użycie kliknie nagłówek kolumny. Zostanie przekazana wartość Klucz ustawiona w narzędziu Interface Builder i kolejność sortowania dla tej kolumny.

Jeśli uruchomimy aplikację i klikniemy w nagłówkach kolumn, wiersze zostaną posortowane według tej kolumny:

Example of sorted output

Wybór wiersza

Jeśli chcesz zezwolić użytkownikowi na wybranie jednego wiersza, kliknij Main.storyboard dwukrotnie plik, aby otworzyć go do edycji w narzędziu Interface Builder. Wybierz widok konspektu w hierarchii interfejsu i usuń zaznaczenie pola wyboru Wiele w Inspektorze atrybutów:

Screenshot shows the Attribute Inspector where you can change the Multiple setting.

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

Następnie zmodyfikuj ProductOutlineDelegate.cs plik i dodaj następującą metodę:

public override bool ShouldSelectItem (NSOutlineView outlineView, NSObject item)
{
    // Don't select product groups
    return !((Product)item).IsProductGroup;
}

Umożliwi to użytkownikowi wybranie dowolnego wiersza w widoku konspektu. Zwróć false element dla ShouldSelectItem dowolnego elementu, którego nie chcesz, aby użytkownik mógł wybrać lub false dla każdego elementu, jeśli nie chcesz, aby użytkownik mógł wybrać jakiekolwiek elementy.

Wybór wielu wierszy

Jeśli chcesz zezwolić użytkownikowi na wybranie wielu wierszy, kliknij Main.storyboard dwukrotnie plik, aby otworzyć go do edycji w narzędziu Interface Builder. Wybierz widok konspektu w hierarchii interfejsu i zaznacz pole wyboru Wiele w Inspektorze atrybutów:

Screenshot shows the Attribute Inspector where you can select Multiple.

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

Następnie zmodyfikuj ProductOutlineDelegate.cs plik i dodaj następującą metodę:

public override bool ShouldSelectItem (NSOutlineView outlineView, NSObject item)
{
    // Don't select product groups
    return !((Product)item).IsProductGroup;
}

Umożliwi to użytkownikowi wybranie dowolnego wiersza w widoku konspektu. Zwróć false element dla ShouldSelectRow dowolnego elementu, którego nie chcesz, aby użytkownik mógł wybrać lub false dla każdego elementu, jeśli nie chcesz, aby użytkownik mógł wybrać jakiekolwiek elementy.

Wpisz, aby wybrać wiersz

Jeśli chcesz zezwolić użytkownikowi na wpisywanie znaku przy użyciu zaznaczonego widoku konspektu i zaznacz pierwszy wiersz, który ma ten znak, kliknij Main.storyboard dwukrotnie plik, aby otworzyć go do edycji w narzędziu Interface Builder. Wybierz widok konspektu w hierarchii interfejsu i zaznacz pole wyboru Typ Zaznacz w Inspektorze atrybutów:

Editing the row type

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

Teraz edytujemy ProductOutlineDelegate.cs plik i dodajmy następującą metodę:

public override NSObject GetNextTypeSelectMatch (NSOutlineView outlineView, NSObject startItem, NSObject endItem, string searchString)
{
    foreach(Product product in DataSource.Products) {
        if (product.Title.Contains (searchString)) {
            return product;
        }
    }

    // Not found
    return null;
}

Metoda GetNextTypeSelectMatch przyjmuje daną searchString wartość i zwraca element pierwszego Product , który zawiera ten ciąg w elemencie Title.

Zmienianie kolejności kolumn

Jeśli chcesz zezwolić użytkownikowi na przeciąganie kolumn zmiany kolejności w widoku konspektu, kliknij Main.storyboard dwukrotnie plik, aby otworzyć go do edycji w narzędziu Interface Builder. Zaznacz widok konspektu w hierarchii interfejsu i zaznacz pole wyboru Zmień kolejność w inspektorze atrybutów:

Screenshot shows the Attribute Inspector where you can select Reordering.

Jeśli nadasz wartość właściwości Autosave i sprawdzimy pole Informacje o kolumnie, wszelkie zmiany wprowadzone w układzie tabeli zostaną automatycznie zapisane i przywrócone przy następnym uruchomieniu aplikacji.

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

Teraz edytujemy ProductOutlineDelegate.cs plik i dodajmy następującą metodę:

public override bool ShouldReorder (NSOutlineView outlineView, nint columnIndex, nint newColumnIndex)
{
    return true;
}

Metoda ShouldReorder powinna zwracać true dowolną kolumnę, którą chce zezwolić na przeciąganie zmiany kolejności do newColumnIndexelementu , w przeciwnym razie zwróć wartość false;

Jeśli uruchomimy aplikację, możemy przeciągnąć nagłówki kolumn, aby zmienić kolejność kolumn:

Example of reordering columns

Edytowanie komórek

Jeśli chcesz zezwolić użytkownikowi na edytowanie wartości dla danej komórki, zmodyfikuj ProductOutlineDelegate.cs plik i zmień metodę GetViewForItem w następujący sposób:

public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
    // Cast item
    var product = item as Product;

    // This pattern allows you reuse existing views when they are no-longer in use.
    // If the returned view is null, you instance up a new view
    // If a non-null view is returned, you modify it enough to reflect the new data
    NSTextField view = (NSTextField)outlineView.MakeView (tableColumn.Title, this);
    if (view == null) {
        view = new NSTextField ();
        view.Identifier = tableColumn.Title;
        view.BackgroundColor = NSColor.Clear;
        view.Bordered = false;
        view.Selectable = false;
        view.Editable = !product.IsProductGroup;
    }

    // Tag view
    view.Tag = outlineView.RowForItem (item);

    // Allow for edit
    view.EditingEnded += (sender, e) => {

        // Grab product
        var prod = outlineView.ItemAtRow(view.Tag) as Product;

        // Take action based on type
        switch(view.Identifier) {
        case "Product":
            prod.Title = view.StringValue;
            break;
        case "Details":
            prod.Description = view.StringValue;
            break;
        }
    };

    // Setup view based on the column selected
    switch (tableColumn.Title) {
    case "Product":
        view.StringValue = product.Title;
        break;
    case "Details":
        view.StringValue = product.Description;
        break;
    }

    return view;
}

Teraz, jeśli uruchomimy aplikację, użytkownik może edytować komórki w widoku tabeli:

An example of editing cells

Używanie obrazów w widokach konspektu

Aby dołączyć obraz jako część komórki w NSOutlineViewobiekcie , należy zmienić sposób zwracania danych przez metodę widoku NSTableViewDelegate'sGetView konspektu, aby użyć elementu NSTableCellView zamiast typowego NSTextFieldelementu . Na przykład:

public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
    // Cast item
    var product = item as Product;

    // This pattern allows you reuse existing views when they are no-longer in use.
    // If the returned view is null, you instance up a new view
    // If a non-null view is returned, you modify it enough to reflect the new data
    NSTableCellView view = (NSTableCellView)outlineView.MakeView (tableColumn.Title, this);
    if (view == null) {
        view = new NSTableCellView ();
        if (tableColumn.Title == "Product") {
            view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
            view.AddSubview (view.ImageView);
            view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
        } else {
            view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
        }
        view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;
        view.AddSubview (view.TextField);
        view.Identifier = tableColumn.Title;
        view.TextField.BackgroundColor = NSColor.Clear;
        view.TextField.Bordered = false;
        view.TextField.Selectable = false;
        view.TextField.Editable = !product.IsProductGroup;
    }

    // Tag view
    view.TextField.Tag = outlineView.RowForItem (item);

    // Allow for edit
    view.TextField.EditingEnded += (sender, e) => {

        // Grab product
        var prod = outlineView.ItemAtRow(view.Tag) as Product;

        // Take action based on type
        switch(view.Identifier) {
        case "Product":
            prod.Title = view.TextField.StringValue;
            break;
        case "Details":
            prod.Description = view.TextField.StringValue;
            break;
        }
    };

    // Setup view based on the column selected
    switch (tableColumn.Title) {
    case "Product":
        view.ImageView.Image = NSImage.ImageNamed (product.IsProductGroup ? "tags.png" : "tag.png");
        view.TextField.StringValue = product.Title;
        break;
    case "Details":
        view.TextField.StringValue = product.Description;
        break;
    }

    return view;
}

Aby uzyskać więcej informacji, zobacz sekcję Using Images with Outline Views (Używanie obrazów z widokami konspektu) w dokumentacji dotyczącej pracy z obrazem .

Widoki konspektu powiązania danych

Korzystając z technik kodowania klucz-wartość i powiązania danych w aplikacji Xamarin.Mac, można znacznie zmniejszyć ilość kodu, który trzeba napisać i obsługiwać, aby wypełnić elementy interfejsu użytkownika i pracować z elementami interfejsu użytkownika. Masz również korzyść z dalszego oddzielenia danych zapasowych (modelu danych) od interfejsu użytkownika frontonu (Model-View-Controller), co prowadzi do łatwiejszego utrzymania, bardziej elastycznego projektowania aplikacji.

Kodowanie klucz-wartość (KVC) jest mechanizmem uzyskiwania dostępu do właściwości obiektu pośrednio przy użyciu kluczy (specjalnie sformatowanych ciągów) do identyfikowania właściwości zamiast uzyskiwania do nich dostępu za pośrednictwem zmiennych wystąpienia lub metod metod dostępu (get/set). Implementując metody dostępu zgodne z kodowaniem klucz-wartość w aplikacji Xamarin.Mac, uzyskujesz dostęp do innych funkcji systemu macOS, takich jak Obserwowanie wartości klucza (KVO), powiązanie danych, dane podstawowe, powiązania cocoa i możliwość tworzenia skryptów.

Aby uzyskać więcej informacji, zobacz sekcję Powiązanie danych widoku konspektu w dokumentacji powiązania danych i kodowania klucz-wartość.

Podsumowanie

W tym artykule szczegółowo przedstawiono pracę z widokami konspektu w aplikacji platformy Xamarin.Mac. Zobaczyliśmy różne typy i zastosowania widoków konspektu, sposób tworzenia i obsługi widoków konspektu w konstruktorze interfejsu Xcode oraz pracy z widokami konspektu w kodzie języka C#.