Aracılığıyla paylaş


Xamarin.Mac'te iletişim kutuları

Xamarin.Mac uygulamasında C# ve .NET ile çalışırken, ve Xcode'da çalışan bir geliştiricinin sahip olduğu İletişim Kutularına ve Kalıcı Windows'a Objective-C erişebilirsiniz. Xamarin.Mac doğrudan Xcode ile tümleştirildiği için, Kalıcı Windows'unuzu oluşturmak ve korumak için Xcode'un Arabirim Oluşturucusu'nu kullanabilirsiniz (veya isteğe bağlı olarak bunları doğrudan C# kodunda oluşturabilirsiniz).

Bir kullanıcı eylemine yanıt olarak bir iletişim kutusu görüntülenir ve genellikle kullanıcıların eylemi tamamlama yollarını sağlar. İletişim kutusu kapatılmadan önce kullanıcının yanıtını gerektirir.

Windows, Modeless durumunda (aynı anda birden çok belge açabilen bir metin düzenleyicisi gibi) veya Kalıcı (uygulama devam etmeden önce kapatılması gereken dışarı aktarma iletişim kutusu gibi) kullanılabilir.

Açık bir iletişim kutusu

Bu makalede, Xamarin.Mac uygulamasında İletişim Kutuları ve Kalıcı Windows ile çalışmanın temellerini ele alacağız. Bu makalede kullanacağımız temel kavramları ve teknikleri kapsarken öncelikle Hello, Mac makalesi, özellikle Xcode ve Interface Builder'a Giriş ve Çıkışlar ve Eylemler bölümleriyle çalışmanız önemle önerilir.

Xamarin.Mac Internals belgesinin C# sınıflarını / yöntemlerini kullanıma alma Objective-Cbölümüne de göz atmak isteyebilirsiniz. Bu belge, C# sınıflarınızı nesnelere ve UI Öğelerine Objective-C bağlamada kullanılan ve Export komutlarını açıklar.Register

İletişim Kutularına Giriş

Bir kullanıcı eylemine (dosya kaydetme gibi) yanıt olarak bir iletişim kutusu görüntülenir ve kullanıcıların bu eylemi tamamlaması için bir yol sağlar. İletişim kutusu kapatılmadan önce kullanıcının yanıtını gerektirir.

Apple'a göre, İletişim Kutusu sunmanın üç yolu vardır:

  • Belge Kalıcı - Belge Kalıcı iletişim kutusu, kapatılana kadar kullanıcının belirli bir belge içinde başka bir şey yapmasını engeller.
  • Uygulama Kalıcı - Uygulama Kalıcı iletişim kutusu, kapatılana kadar kullanıcının uygulamayla etkileşim kurmasını engeller.
  • Modeless A Modeless Dialog, kullanıcıların belge penceresiyle etkileşime devam ederken iletişim kutusundaki ayarları değiştirmesine olanak tanır.

Herhangi bir standart NSWindow , mod olarak görüntülenerek özelleştirilmiş bir iletişim kutusu olarak kullanılabilir:

Örnek kalıcı pencere

Belge Kalıcı İletişim Sayfaları

Sayfa, belirli bir belge penceresine eklenmiş, kullanıcıların iletişim kutusunu kapatana kadar pencereyle etkileşim kurmasını engelleyen kalıcı bir iletişim kutusudur. Sayfa, ortaya çıktığı pencereye eklenir ve bir pencere için tek seferde yalnızca bir sayfa açılabilir.

Örnek bir kalıcı sayfa

Tercihler Windows

Tercihler Penceresi, kullanıcının seyrek değiştirdiğini uygulamanın ayarlarını içeren modsuz bir iletişim kutusudur. Tercihler Windows genellikle kullanıcının farklı ayar grupları arasında geçiş yapmasına olanak tanıyan bir Araç Çubuğu içerir:

Örnek bir tercih penceresi

İletişim Kutusunu Aç

Aç İletişim Kutusu, kullanıcılara uygulamadaki bir öğeyi bulmak ve açmak için tutarlı bir yol sağlar:

Açık iletişim kutusu

macOS, kullanıcıların kullandıkları her uygulamada tutarlı bir yazdırma deneyimi yaşamaları için uygulamanızın görüntüleyebileceği standart Yazdırma ve Sayfa Yapısı İletişim Kutuları sağlar.

Yazdır İletişim Kutusu hem serbest kayan iletişim kutusu olarak görüntülenebilir:

Yazdır iletişim kutusu

Veya Sayfa olarak görüntülenebilir:

Yazdırma sayfası

Sayfa Yapısı İletişim Kutusu hem serbest kayan iletişim kutusu olarak görüntülenebilir:

Sayfa yapısı iletişim kutusu

Veya Sayfa olarak görüntülenebilir:

Sayfa yapısı sayfası

İletişim Kutularını Kaydet

Kaydet İletişim Kutusu, kullanıcılara uygulamadaki bir öğeyi kaydetmek için tutarlı bir yol sağlar. Kaydet İletişim Kutusu'nun iki durumu vardır: En az (Daraltılmış olarak da bilinir):

Kaydet iletişim kutusu

Ve Genişletilmiş durumu:

Genişletilmiş kaydetme iletişim kutusu

En Az Kaydet İletişim Kutusu, Sayfa olarak da görüntülenebilir:

En az kaydetme sayfası

Genişletilmiş Kaydet İletişim Kutusu gibi:

Genişletilmiş bir kaydetme sayfası

Daha fazla bilgi için Apple'ın OS X İnsan Arabirimi Yönergeleri'nin İletişim Kutuları bölümüne bakın

Projeye Kalıcı Pencere Ekleme

Ana belge penceresinin yanı sıra, bir Xamarin.Mac uygulamasının kullanıcıya Tercihler veya Denetçi Panelleri gibi diğer pencere türlerini görüntülemesi gerekebilir.

Yeni bir pencere eklemek için aşağıdakileri yapın:

  1. Çözüm Gezgini, dosyayı düzenlemek üzere Xcode'un Arabirim Oluşturucusu'nda açınMain.storyboard.

  2. Tasarım Yüzeyine yeni bir Görünüm Denetleyicisi sürükleyin:

    Kitaplıktan Görünüm Denetleyicisi Seçme

  3. Kimlik Denetçisi'nde Sınıf Adı için şunu girinCustomDialogController:

    Sınıf adını CustomDialogController olarak ayarlama.

  4. Mac için Visual Studio geri dönün, Xcode ile eşitlenmesine izin verin ve dosyayı oluşturunCustomDialogController.h.

  5. Xcode'a dönün ve arabiriminizi tasarlar:

    Xcode'da kullanıcı arabirimini tasarlama

  6. İletişim kutusunu iletişim kutusunun penceresine açacak kullanıcı arabirimi öğesinden denetimle sürükleyerek uygulamanızın Ana Penceresinden yeni Görünüm Denetleyicisi'ne kalıcı bir Segue oluşturun. Tanımlayıcıyı ModalSegueAtayın:

    Kalıcı bir segue

  7. Herhangi bir Eylem ve Prizi bağla:

    Eylem Yapılandırma

  8. Değişikliklerinizi kaydedin ve Xcode ile eşitlemek için Mac için Visual Studio dönün.

CustomDialogController.cs Dosyanın aşağıdaki gibi görünmesini sağlayın:

using System;
using Foundation;
using AppKit;

namespace MacDialog
{
    public partial class CustomDialogController : NSViewController
    {
        #region Private Variables
        private string _dialogTitle = "Title";
        private string _dialogDescription = "Description";
        private NSViewController _presentor;
        #endregion

        #region Computed Properties
        public string DialogTitle {
            get { return _dialogTitle; }
            set { _dialogTitle = value; }
        }

        public string DialogDescription {
            get { return _dialogDescription; }
            set { _dialogDescription = value; }
        }

        public NSViewController Presentor {
            get { return _presentor; }
            set { _presentor = value; }
        }
        #endregion

        #region Constructors
        public CustomDialogController (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void ViewWillAppear ()
        {
            base.ViewWillAppear ();

            // Set initial title and description
            Title.StringValue = DialogTitle;
            Description.StringValue = DialogDescription;
        }
        #endregion

        #region Private Methods
        private void CloseDialog() {
            Presentor.DismissViewController (this);
        }
        #endregion

        #region Custom Actions
        partial void AcceptDialog (Foundation.NSObject sender) {
            RaiseDialogAccepted();
            CloseDialog();
        }

        partial void CancelDialog (Foundation.NSObject sender) {
            RaiseDialogCanceled();
            CloseDialog();
        }
        #endregion

        #region Events
        public EventHandler DialogAccepted;

        internal void RaiseDialogAccepted() {
            if (this.DialogAccepted != null)
                this.DialogAccepted (this, EventArgs.Empty);
        }

        public EventHandler DialogCanceled;

        internal void RaiseDialogCanceled() {
            if (this.DialogCanceled != null)
                this.DialogCanceled (this, EventArgs.Empty);
        }
        #endregion
    }
}

Bu kod, iletişim kutusunun başlığını ve açıklamasını ayarlamak için birkaç özelliği ve iptal edilen veya kabul edilen iletişim kutusuna tepki vermek için birkaç olayı kullanıma sunar.

Ardından, dosyayı düzenleyin ViewController.cs , yöntemini geçersiz kılın PrepareForSegue ve aşağıdaki gibi görünmesini sağlayın:

public override void PrepareForSegue (NSStoryboardSegue segue, NSObject sender)
{
    base.PrepareForSegue (segue, sender);

    // Take action based on the segue name
    switch (segue.Identifier) {
    case "ModalSegue":
        var dialog = segue.DestinationController as CustomDialogController;
        dialog.DialogTitle = "MacDialog";
        dialog.DialogDescription = "This is a sample dialog.";
        dialog.DialogAccepted += (s, e) => {
            Console.WriteLine ("Dialog accepted");
            DismissViewController (dialog);
        };
        dialog.Presentor = this;
        break;
    }
}

Bu kod, Xcode'un Arabirim Oluşturucusu'nda iletişim kutusuna tanımladığımız segue'yi başlatır ve başlığı ve açıklamayı ayarlar. Ayrıca kullanıcının iletişim kutusunda yaptığı seçimi de işler.

Uygulamamızı çalıştırabilir ve özel iletişim kutusunu görüntüleyebiliriz:

Örnek iletişim kutusu

Xamarin.Mac uygulamasında windows kullanma hakkında daha fazla bilgi için lütfen Windows ile çalışma belgelerimize bakın.

Özel Sayfa Oluşturma

Sayfa, belirli bir belge penceresine eklenmiş, kullanıcıların iletişim kutusunu kapatana kadar pencereyle etkileşim kurmasını engelleyen kalıcı bir iletişim kutusudur. Sayfa, ortaya çıktığı pencereye eklenir ve bir pencere için tek seferde yalnızca bir sayfa açılabilir.

Xamarin.Mac'te Özel Sayfa oluşturmak için aşağıdakileri yapalım:

  1. Çözüm Gezgini, dosyayı düzenlemek üzere Xcode'un Arabirim Oluşturucusu'nda açınMain.storyboard.

  2. Tasarım Yüzeyine yeni bir Görünüm Denetleyicisi sürükleyin:

    Kitaplıktan Görünüm Denetleyicisi Seçme

  3. Kullanıcı arabiriminizi tasarla:

    Kullanıcı arabirimi tasarımı

  4. Ana Pencerenizden yeni Görünüm Denetleyicisine bir Sayfa Bölmesi oluşturun:

    Sayfa segue türünü seçme

  5. Kimlik Denetçisi'nde Görünüm Denetleyicisi'nin Sınıfını SheetViewController adlandırın:

    Sınıf adını SheetViewController olarak ayarlama.

  6. Gerekli çıkışları ve eylemleri tanımlayın:

    Gerekli Çıkışları ve Eylemleri Tanımlama

  7. Değişikliklerinizi kaydedin ve eşitlemek için Mac için Visual Studio dönün.

Ardından, dosyayı düzenleyin SheetViewController.cs ve aşağıdaki gibi görünmesini sağlayın:

using System;
using Foundation;
using AppKit;

namespace MacDialog
{
    public partial class SheetViewController : NSViewController
    {
        #region Private Variables
        private string _userName = "";
        private string _password = "";
        private NSViewController _presentor;
        #endregion

        #region Computed Properties
        public string UserName {
            get { return _userName; }
            set { _userName = value; }
        }

        public string Password {
            get { return _password;}
            set { _password = value;}
        }

        public NSViewController Presentor {
            get { return _presentor; }
            set { _presentor = value; }
        }
        #endregion

        #region Constructors
        public SheetViewController (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void ViewWillAppear ()
        {
            base.ViewWillAppear ();

            // Set initial values
            NameField.StringValue = UserName;
            PasswordField.StringValue = Password;

            // Wireup events
            NameField.Changed += (sender, e) => {
                UserName = NameField.StringValue;
            };
            PasswordField.Changed += (sender, e) => {
                Password = PasswordField.StringValue;
            };
        }
        #endregion

        #region Private Methods
        private void CloseSheet() {
            Presentor.DismissViewController (this);
        }
        #endregion

        #region Custom Actions
        partial void AcceptSheet (Foundation.NSObject sender) {
            RaiseSheetAccepted();
            CloseSheet();
        }

        partial void CancelSheet (Foundation.NSObject sender) {
            RaiseSheetCanceled();
            CloseSheet();
        }
        #endregion

        #region Events
        public EventHandler SheetAccepted;

        internal void RaiseSheetAccepted() {
            if (this.SheetAccepted != null)
                this.SheetAccepted (this, EventArgs.Empty);
        }

        public EventHandler SheetCanceled;

        internal void RaiseSheetCanceled() {
            if (this.SheetCanceled != null)
                this.SheetCanceled (this, EventArgs.Empty);
        }
        #endregion
    }
}

Ardından dosyayı düzenleyin ViewController.cs , yöntemini düzenleyin PrepareForSegue ve aşağıdaki gibi görünmesini sağlayın:

public override void PrepareForSegue (NSStoryboardSegue segue, NSObject sender)
{
    base.PrepareForSegue (segue, sender);

    // Take action based on the segue name
    switch (segue.Identifier) {
    case "ModalSegue":
        var dialog = segue.DestinationController as CustomDialogController;
        dialog.DialogTitle = "MacDialog";
        dialog.DialogDescription = "This is a sample dialog.";
        dialog.DialogAccepted += (s, e) => {
            Console.WriteLine ("Dialog accepted");
            DismissViewController (dialog);
        };
        dialog.Presentor = this;
        break;
    case "SheetSegue":
        var sheet = segue.DestinationController as SheetViewController;
        sheet.SheetAccepted += (s, e) => {
            Console.WriteLine ("User Name: {0} Password: {1}", sheet.UserName, sheet.Password);
        };
        sheet.Presentor = this;
        break;
    }
}

Uygulamamızı çalıştırır ve Sayfayı açarsak pencereye eklenir:

Örnek sayfa

Tercihler İletişim Kutusu Oluşturma

Arabirim Oluşturucusu'nda Tercih Görünümü'nü hazırlamadan önce, tercihleri değiştirme işlemini işlemek için özel bir segue türü eklememiz gerekir. Projenize yeni bir sınıf ekleyin ve adını ekleyin ReplaceViewSeque. sınıfını düzenleyin ve aşağıdaki gibi görünmesini sağlayın:

using System;
using AppKit;
using Foundation;

namespace MacWindows
{
    [Register("ReplaceViewSeque")]
    public class ReplaceViewSeque : NSStoryboardSegue
    {
        #region Constructors
        public ReplaceViewSeque() {

        }

        public ReplaceViewSeque (string identifier, NSObject sourceController, NSObject destinationController) : base(identifier,sourceController,destinationController) {

        }

        public ReplaceViewSeque (IntPtr handle) : base(handle) {
        }

        public ReplaceViewSeque (NSObjectFlag x) : base(x) {
        }
        #endregion

        #region Override Methods
        public override void Perform ()
        {
            // Cast the source and destination controllers
            var source = SourceController as NSViewController;
            var destination = DestinationController as NSViewController;

            // Is there a source?
            if (source == null) {
                // No, get the current key window
                var window = NSApplication.SharedApplication.KeyWindow;

                // Swap the controllers
                window.ContentViewController = destination;

                // Release memory
                window.ContentViewController?.RemoveFromParentViewController ();
            } else {
                // Swap the controllers
                source.View.Window.ContentViewController = destination;

                // Release memory
                source.RemoveFromParentViewController ();
            }

        }
        #endregion

    }

}

Özel segue oluşturulduktan sonra, tercihlerimizi işlemek için Xcode'un Interface Builder'ına yeni bir pencere ekleyebiliriz.

Yeni bir pencere eklemek için aşağıdakileri yapın:

  1. Çözüm Gezgini, dosyayı düzenlemek üzere Xcode'un Arabirim Oluşturucusu'nda açınMain.storyboard.

  2. Tasarım Yüzeyine yeni bir Pencere Denetleyicisi sürükleyin:

    Kitaplıktan Bir Pencere Denetleyicisi Seçin

  3. Pencereyi Menü Çubuğu tasarımcısının yakınında düzenleyin:

    Yeni Pencere Ekleme

  4. Tercih görünümünüzde sekmeler olacağı için ekli Görünüm Denetleyicisinin kopyalarını oluşturun:

    Gerekli Görünüm Denetleyicilerini ekleme

  5. Kitaplıktan yeni bir Araç Çubuğu Denetleyicisi sürükleyin:

    Kitaplıktan Bir Araç Çubuğu Denetleyicisi Seçin

  6. Tasarım Yüzeyi'ndeki Pencere'ye bırakın:

    Yeni araç çubuğu denetleyicisi ekleme

  7. Araç çubuğunuzun tasarımını düzenle:

    Araç çubuğunun düzenini oluşturma

  8. Control tuşunu basılı tutup her Araç Çubuğu Düğmesi'nden yukarıda oluşturduğunuz Görünümler'e sürükleyin. Özel bir segue türü seçin:

    Özel bir segue türü ayarlama.

  9. Yeni Segue'yi seçin ve Sınıfı olarak ReplaceViewSegueayarlayın:

    Segue sınıfını ayarlama

  10. Tasarım Yüzeyi'ndeki Menü Çubuğu Tasarımcısı'nda, Uygulama Menüsünden Tercihler...'i seçin, control tuşuna basıp tıklayıp Tercihler Penceresi'ne sürükleyerek Bir Gösteri segue oluşturun:

    Tercihler'i Tercihler Penceresi'ne sürükleyerek segue türünü ayarlama.

  11. Değişikliklerinizi kaydedin ve eşitlemek için Mac için Visual Studio dönün.

Kodu çalıştırır ve Uygulama Menüsünden Tercihler... öğesini seçersek, pencere görüntülenir:

Profil sözcüğünü gösteren örnek tercihler penceresi.

Windows ve Araç Çubukları ile çalışma hakkında daha fazla bilgi için lütfen Windows ve Araç Çubukları belgelerimize bakın.

Kaydetme ve Yükleme Tercihleri

Tipik bir macOS Uygulamasında, kullanıcı Uygulamanın Kullanıcı Tercihlerinden herhangi birinde değişiklik yaptığında, bu değişiklikler otomatik olarak kaydedilir. Xamarin.Mac uygulamasında bunu işlemenin en kolay yolu, kullanıcının tüm tercihlerini yönetmek ve bunu sistem genelinde paylaşmak için tek bir sınıf oluşturmaktır.

İlk olarak, projeye yeni AppPreferences bir sınıf ekleyin ve öğesinden NSObjectdevralın. Tercihler, tercih formlarını oluşturma ve sürdürme sürecini çok daha basit hale getirecek olan Veri Bağlama ve Anahtar-Değer Kodlaması'nı kullanacak şekilde tasarlanacaktır. Tercihler az miktarda basit veri türünden oluşacağı için, değerleri depolamak ve almak için yerleşik NSUserDefaults değerini kullanın.

AppPreferences.cs Dosyayı düzenleyin ve aşağıdaki gibi görünmesini sağlayın:

using System;
using Foundation;
using AppKit;

namespace SourceWriter
{
    [Register("AppPreferences")]
    public class AppPreferences : NSObject
    {
        #region Computed Properties
        [Export("DefaultLanguage")]
        public int DefaultLanguage {
            get {
                var value = LoadInt ("DefaultLanguage", 0);
                return value;
            }
            set {
                WillChangeValue ("DefaultLanguage");
                SaveInt ("DefaultLanguage", value, true);
                DidChangeValue ("DefaultLanguage");
            }
        }

        [Export("SmartLinks")]
        public bool SmartLinks {
            get { return LoadBool ("SmartLinks", true); }
            set {
                WillChangeValue ("SmartLinks");
                SaveBool ("SmartLinks", value, true);
                DidChangeValue ("SmartLinks");
            }
        }

        // Define any other required user preferences in the same fashion
        ...

        [Export("EditorBackgroundColor")]
        public NSColor EditorBackgroundColor {
            get { return LoadColor("EditorBackgroundColor", NSColor.White); }
            set {
                WillChangeValue ("EditorBackgroundColor");
                SaveColor ("EditorBackgroundColor", value, true);
                DidChangeValue ("EditorBackgroundColor");
            }
        }
        #endregion

        #region Constructors
        public AppPreferences ()
        {
        }
        #endregion

        #region Public Methods
        public int LoadInt(string key, int defaultValue) {
            // Attempt to read int
            var number = NSUserDefaults.StandardUserDefaults.IntForKey(key);

            // Take action based on value
            if (number == null) {
                return defaultValue;
            } else {
                return (int)number;
            }
        }

        public void SaveInt(string key, int value, bool sync) {
            NSUserDefaults.StandardUserDefaults.SetInt(value, key);
            if (sync) NSUserDefaults.StandardUserDefaults.Synchronize ();
        }

        public bool LoadBool(string key, bool defaultValue) {
            // Attempt to read int
            var value = NSUserDefaults.StandardUserDefaults.BoolForKey(key);

            // Take action based on value
            if (value == null) {
                return defaultValue;
            } else {
                return value;
            }
        }

        public void SaveBool(string key, bool value, bool sync) {
            NSUserDefaults.StandardUserDefaults.SetBool(value, key);
            if (sync) NSUserDefaults.StandardUserDefaults.Synchronize ();
        }

        public string NSColorToHexString(NSColor color, bool withAlpha) {
            //Break color into pieces
            nfloat red=0, green=0, blue=0, alpha=0;
            color.GetRgba (out red, out green, out blue, out alpha);

            // Adjust to byte
            alpha *= 255;
            red *= 255;
            green *= 255;
            blue *= 255;

            //With the alpha value?
            if (withAlpha) {
                return String.Format ("#{0:X2}{1:X2}{2:X2}{3:X2}", (int)alpha, (int)red, (int)green, (int)blue);
            } else {
                return String.Format ("#{0:X2}{1:X2}{2:X2}", (int)red, (int)green, (int)blue);
            }
        }

        public NSColor NSColorFromHexString (string hexValue)
        {
            var colorString = hexValue.Replace ("#", "");
            float red, green, blue, alpha;

            // Convert color based on length
            switch (colorString.Length) {
            case 3 : // #RGB
                red = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(0, 1)), 16) / 255f;
                green = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(1, 1)), 16) / 255f;
                blue = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(2, 1)), 16) / 255f;
                return NSColor.FromRgba(red, green, blue, 1.0f);
            case 6 : // #RRGGBB
                red = Convert.ToInt32(colorString.Substring(0, 2), 16) / 255f;
                green = Convert.ToInt32(colorString.Substring(2, 2), 16) / 255f;
                blue = Convert.ToInt32(colorString.Substring(4, 2), 16) / 255f;
                return NSColor.FromRgba(red, green, blue, 1.0f);
            case 8 : // #AARRGGBB
                alpha = Convert.ToInt32(colorString.Substring(0, 2), 16) / 255f;
                red = Convert.ToInt32(colorString.Substring(2, 2), 16) / 255f;
                green = Convert.ToInt32(colorString.Substring(4, 2), 16) / 255f;
                blue = Convert.ToInt32(colorString.Substring(6, 2), 16) / 255f;
                return NSColor.FromRgba(red, green, blue, alpha);
            default :
                throw new ArgumentOutOfRangeException(string.Format("Invalid color value '{0}'. It should be a hex value of the form #RBG, #RRGGBB or #AARRGGBB", hexValue));
            }
        }

        public NSColor LoadColor(string key, NSColor defaultValue) {

            // Attempt to read color
            var hex = NSUserDefaults.StandardUserDefaults.StringForKey(key);

            // Take action based on value
            if (hex == null) {
                return defaultValue;
            } else {
                return NSColorFromHexString (hex);
            }
        }

        public void SaveColor(string key, NSColor color, bool sync) {
            // Save to default
            NSUserDefaults.StandardUserDefaults.SetString(NSColorToHexString(color,true), key);
            if (sync) NSUserDefaults.StandardUserDefaults.Synchronize ();
        }
        #endregion
    }
}

Bu sınıf, ile NSUserDefaults çalışmayı kolaylaştırmak için , LoadInt, SaveColor, , LoadColorvb. gibi SaveIntbirkaç yardımcı yordam içerir. Ayrıca, NSUserDefaults işlemek NSColorsNSColorToHexString için yerleşik bir yolu olmadığından ve yöntemleri, renkleri kolayca depolanabilen ve NSColorFromHexString alınabilen web tabanlı onaltılık dizelere (#RRGGBBAAalfa saydamlığıdırAA) dönüştürmek için kullanılır.

AppDelegate.cs dosyasında appPreferences nesnesinin uygulama genelinde kullanılacak bir örneğini oluşturun:

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

namespace SourceWriter
{
    [Register ("AppDelegate")]
    public class AppDelegate : NSApplicationDelegate
    {
        #region Computed Properties
        public int NewWindowNumber { get; set;} = -1;

        public AppPreferences Preferences { get; set; } = new AppPreferences();
        #endregion

        #region Constructors
        public AppDelegate ()
        {
        }
        #endregion

        ...

Tercihleri Tercih Görünümlerine Kablolama

Ardından, Tercih sınıfını yukarıda oluşturulan Tercih Penceresi ve Görünümler'de kullanıcı arabirimi öğelerine bağlayın. Arabirim Oluşturucusu'nda bir Tercih Görünümü Denetleyicisi seçin ve Kimlik Denetçisi'ne geçin, denetleyici için özel bir sınıf oluşturun:

Kimlik Denetçisi

Değişikliklerinizi eşitlemek için Mac için Visual Studio geri dönün ve yeni oluşturulan sınıfı düzenlemek üzere açın. Sınıfın aşağıdaki gibi görünmesini sağlayın:

using System;
using Foundation;
using AppKit;

namespace SourceWriter
{
    public partial class EditorPrefsController : NSViewController
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Computed Properties
        [Export("Preferences")]
        public AppPreferences Preferences {
            get { return App.Preferences; }
        }
        #endregion

        #region Constructors
        public EditorPrefsController (IntPtr handle) : base (handle)
        {
        }
        #endregion
    }
}

Bu sınıfın burada iki şey yaptığına dikkat edin: İlk olarak, AppDelegate'e erişimi kolaylaştırmak için bir yardımcı App özelliği vardır. İkinci olarak özelliği, bu Görünüme Preferences yerleştirilen tüm ui denetimleriyle veri bağlama için genel AppPreferences sınıfını kullanıma sunar.

Ardından, Görsel Taslak dosyasına çift tıklayarak Dosyayı Arabirim Oluşturucusu'nda yeniden açın (ve yukarıda yapılan değişikliklere bakın). Tercihler arabirimini oluşturmak için gereken tüm kullanıcı arabirimi denetimlerini Görünüm'e sürükleyin. Her denetim için Bağlama Denetçisi'ne geçin ve AppPreference sınıfının tek tek özelliklerine bağlanın:

Bağlama Denetçisi

Yukarıdaki adımları gerekli tüm paneller (Görünüm Denetleyicileri) ve Tercih Özellikleri için yineleyin.

Tüm Açık Pencerelere Tercih Değişikliklerini Uygulama

Yukarıda belirtildiği gibi, tipik bir macOS Uygulamasında, kullanıcı Uygulamanın Kullanıcı Tercihlerinden herhangi birinde değişiklik yaptığında, bu değişiklikler otomatik olarak kaydedilir ve kullanıcının uygulamada açmış olabileceği tüm pencerelere uygulanır.

Uygulamanızın tercihlerinin ve pencerelerinin dikkatli bir şekilde planlanması ve tasarlanması, bu işlemin son kullanıcıya sorunsuz ve şeffaf bir şekilde gerçekleşmesini ve çok az miktarda kodlama çalışmasını sağlar.

Uygulama Tercihlerini kullanacak herhangi bir Pencere için, AppDelegate'imize erişimi kolaylaştırmak için İçerik Görünümü Denetleyicisi'ne aşağıdaki yardımcı özelliğini ekleyin:

#region Application Access
public static AppDelegate App {
    get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
}
#endregion

Ardından, kullanıcının tercihlerine göre içeriği veya davranışı yapılandırmak için bir sınıf ekleyin:

public void ConfigureEditor() {

    // General Preferences
    TextEditor.AutomaticLinkDetectionEnabled = App.Preferences.SmartLinks;
    TextEditor.AutomaticQuoteSubstitutionEnabled = App.Preferences.SmartQuotes;
    ...

}

Kullanıcının tercihlerine uygun olduğundan emin olmak için Window ilk açıldığında yapılandırma yöntemini çağırmanız gerekir:

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

    // Configure editor from user preferences
    ConfigureEditor ();
    ...
}

Ardından, dosyayı düzenleyin AppDelegate.cs ve tüm açık pencerelere tercih değişikliklerini uygulamak için aşağıdaki yöntemi ekleyin:

public void UpdateWindowPreferences() {

    // Process all open windows
    for(int n=0; n<NSApplication.SharedApplication.Windows.Length; ++n) {
        var content = NSApplication.SharedApplication.Windows[n].ContentViewController as ViewController;
        if (content != null ) {
            // Reformat all text
            content.ConfigureEditor ();
        }
    }

}

Ardından, projeye bir PreferenceWindowDelegate sınıf ekleyin ve aşağıdaki gibi görünmesini sağlayın:

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

namespace SourceWriter
{
    public class PreferenceWindowDelegate : NSWindowDelegate
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Computed Properties
        public NSWindow Window { get; set;}
        #endregion

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

        }
        #endregion

        #region Override Methods
        public override bool WindowShouldClose (Foundation.NSObject sender)
        {

            // Apply any changes to open windows
            App.UpdateWindowPreferences();

            return true;
        }
        #endregion
    }
}

Bu, tercih Penceresi kapatıldığında tüm tercih değişikliklerinin tüm açık Windows'a gönderilmesine neden olur.

Son olarak, Tercih Penceresi Denetleyicisi'ni düzenleyin ve yukarıda oluşturulan temsilciyi ekleyin:

using System;
using Foundation;
using AppKit;

namespace SourceWriter
{
    public partial class PreferenceWindowController : NSWindowController
    {
        #region Constructors
        public PreferenceWindowController (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void WindowDidLoad ()
        {
            base.WindowDidLoad ();

            // Initialize
            Window.Delegate = new PreferenceWindowDelegate(Window);
            Toolbar.SelectedItemIdentifier = "General";
        }
        #endregion
    }
}

Tüm bu değişiklikler uygulandığında, kullanıcı Uygulamanın Tercihlerini düzenler ve Tercih Penceresi'ni kapatırsa, değişiklikler tüm açık Windows'a uygulanır:

Diğer birkaç açık pencereyle görüntülenen örnek tercihler penceresi.

Aç İletişim Kutusu

Aç İletişim Kutusu, kullanıcılara uygulamadaki bir öğeyi bulmak ve açmak için tutarlı bir yol sağlar. Xamarin.Mac uygulamasında Açık İletişim Kutusunu görüntülemek için aşağıdaki kodu kullanın:

var dlg = NSOpenPanel.OpenPanel;
dlg.CanChooseFiles = true;
dlg.CanChooseDirectories = false;
dlg.AllowedFileTypes = new string[] { "txt", "html", "md", "css" };

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

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

        // Create a new window to hold the text
        var newWindowController = new MainWindowController ();
        newWindowController.Window.MakeKeyAndOrderFront (this);

        // Load the text into the window
        var window = newWindowController.Window as MainWindow;
        window.Text = File.ReadAllText(path);
        window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
        window.RepresentedUrl = url;

    }
}

Yukarıdaki kodda, dosyanın içeriğini görüntülemek için yeni bir belge penceresi açıyoruz. Bu kodu uygulamanız için gereken işlevlerle değiştirmeniz gerekir.

ile NSOpenPanelçalışırken aşağıdaki özellikler kullanılabilir:

  • CanChooseFiles - Kullanıcı dosyaları seçebiliyorsa true .
  • CanChooseDirectories - Kullanıcı dizinleri seçebiliyorsa true .
  • AllowsMultipleSelection - Kullanıcı aynı anda birden fazla dosya seçebiliyorsa true .
  • ResolveAliases - Seçilip diğer ad kullanılıyorsa true , bunu özgün dosyanın yoluna çözümler.
  • AllowedFileTypes - Kullanıcının uzantı veya UTI olarak seçebileceği dosya türlerinden oluşan bir dize dizisidir. Varsayılan değer, herhangi bir dosyanın açılmasına izin veren değeridir null.

yöntemi İletişim RunModal () Kutusunu Aç'ı görüntüler ve kullanıcının dosya veya dizinleri seçmesine izin verir (özellikler tarafından belirtildiği gibi) ve kullanıcı Aç düğmesine tıklarsa döndürür1.

Aç İletişim Kutusu, kullanıcının seçili dosyalarını veya dizinlerini özelliğindeki URL bir URL dizisi olarak döndürür.

Programı çalıştırır ve Dosya menüsünden Aç... öğesini seçersek, aşağıdakiler görüntülenir:

Açık bir iletişim kutusu

Yazdırma ve Sayfa Yapısı İletişim Kutuları

macOS, kullanıcıların kullandıkları her uygulamada tutarlı bir yazdırma deneyimi yaşamaları için uygulamanızın görüntüleyebileceği standart Yazdırma ve Sayfa Yapısı İletişim Kutuları sağlar.

Aşağıdaki kod, standart Yazdırma İletişim Kutusu'nu gösterir:

public bool ShowPrintAsSheet { get; set;} = true;
...

[Export ("showPrinter:")]
void ShowDocument (NSObject sender) {
    var dlg = new NSPrintPanel();

    // Display the print dialog as dialog box
    if (ShowPrintAsSheet) {
        dlg.BeginSheet(new NSPrintInfo(),this,this,null,new IntPtr());
    } else {
        if (dlg.RunModalWithPrintInfo(new NSPrintInfo()) == 1) {
            var alert = new NSAlert () {
                AlertStyle = NSAlertStyle.Critical,
                InformativeText = "We need to print the document here...",
                MessageText = "Print Document",
            };
            alert.RunModal ();
        }
    }
}

özelliğini olarak falseayarlarsakShowPrintAsSheet, uygulamayı çalıştırın ve yazdır iletişim kutusunu görüntüleyin, aşağıdakiler görüntülenir:

Yazdır iletişim kutusu

özelliği olarak trueayarlanırsaShowPrintAsSheet, uygulamayı çalıştırın ve yazdırma iletişim kutusunu görüntüleyin, aşağıdakiler görüntülenir:

Yazdırma sayfası

Aşağıdaki kod Sayfa Düzeni İletişim Kutusu'nu görüntüler:

[Export ("showLayout:")]
void ShowLayout (NSObject sender) {
    var dlg = new NSPageLayout();

    // Display the print dialog as dialog box
    if (ShowPrintAsSheet) {
        dlg.BeginSheet (new NSPrintInfo (), this);
    } else {
        if (dlg.RunModal () == 1) {
            var alert = new NSAlert () {
                AlertStyle = NSAlertStyle.Critical,
                InformativeText = "We need to print the document here...",
                MessageText = "Print Document",
            };
            alert.RunModal ();
        }
    }
}

özelliğini olarak falseayarlarsakShowPrintAsSheet, uygulamayı çalıştırın ve yazdırma düzeni iletişim kutusunu görüntüleyin; aşağıdakiler görüntülenir:

Sayfa yapısı iletişim kutusu

özelliği olarak trueayarlanırsaShowPrintAsSheet, uygulamayı çalıştırın ve yazdırma düzeni iletişim kutusunu görüntüleyin, aşağıdakiler görüntülenir:

Sayfa yapısı sayfası

Yazdırma ve Sayfa Yapısı İletişim Kutularıyla çalışma hakkında daha fazla bilgi için lütfen Apple'ın NSPrintPanel ve NSPageLayout belgelerine bakın.

Kaydet İletişim Kutusu

Kaydet İletişim Kutusu, kullanıcılara uygulamadaki bir öğeyi kaydetmek için tutarlı bir yol sağlar.

Aşağıdaki kodda standart Kaydet İletişim Kutusu gösterilir:

public bool ShowSaveAsSheet { get; set;} = true;
...

[Export("saveDocumentAs:")]
void ShowSaveAs (NSObject sender)
{
    var dlg = new NSSavePanel ();
    dlg.Title = "Save Text File";
    dlg.AllowedFileTypes = new string[] { "txt", "html", "md", "css" };

    if (ShowSaveAsSheet) {
        dlg.BeginSheet(mainWindowController.Window,(result) => {
            var alert = new NSAlert () {
                AlertStyle = NSAlertStyle.Critical,
                InformativeText = "We need to save the document here...",
                MessageText = "Save Document",
            };
            alert.RunModal ();
        });
    } else {
        if (dlg.RunModal () == 1) {
            var alert = new NSAlert () {
                AlertStyle = NSAlertStyle.Critical,
                InformativeText = "We need to save the document here...",
                MessageText = "Save Document",
            };
            alert.RunModal ();
        }
    }

}

AllowedFileTypes özelliği, kullanıcının dosyayı farklı kaydetmek için seçebileceği bir dosya türleri dizesi dizisidir. Dosya türü bir uzantı veya UTI olarak belirtilebilir. Varsayılan değer, herhangi bir dosya türünün kullanılmasına izin veren değeridir null.

özelliğini falseolarak ayarlarsakShowSaveAsSheet, uygulamayı çalıştırın ve Dosya menüsünden Farklı Kaydet... öğesini seçin, aşağıdakiler görüntülenir:

Kaydet iletişim kutusu

Kullanıcı iletişim kutusunu genişletebilir:

Genişletilmiş kaydetme iletişim kutusu

özelliğini trueolarak ayarlarsakShowSaveAsSheet, uygulamayı çalıştırın ve Dosya menüsünden Farklı Kaydet... öğesini seçin, aşağıdakiler görüntülenir:

Bir kaydetme sayfası

Kullanıcı iletişim kutusunu genişletebilir:

Genişletilmiş bir kaydetme sayfası

Kaydet İletişim Kutusu ile çalışma hakkında daha fazla bilgi için lütfen Apple'ın NSSavePanel belgelerine bakın.

Özet

Bu makalede, bir Xamarin.Mac uygulamasında Kalıcı Windows, Sayfalar ve standart sistem İletişim Kutuları ile çalışma konusuna ayrıntılı bir bakış verilmiştir. Kalıcı Windows, Sayfalar ve İletişim Kutularının farklı türlerini ve kullanımlarını, Xcode'un Arabirim Oluşturucusu'nda Kalıcı Windows ve Sayfaların nasıl oluşturulup tutulacağını ve C# kodunda Kalıcı Windows, Sayfalar ve İletişim Kutuları ile nasıl çalışacağını gördük.