Xamarin. Mac içindeki iletişim kutuları

bir Xamarin. Mac uygulamasında C# ve .net ile çalışırken, Objective-C ve Objective-C üzerinde çalışan bir geliştiricinin kullandığı aynı iletişim kutularına ve kalıcı Windows erişebilirsiniz. Xamarin. Mac doğrudan xcode ile tümleştiğinden, kalıcı Windows oluşturmak ve sürdürmek (ya da isteğe bağlı olarak doğrudan C# kodunda oluşturmak) için xcode 'un Interface Builder kullanabilirsiniz.

Kullanıcı eylemine yanıt olarak bir iletişim kutusu görünür ve genellikle kullanıcıların eylemi tamamlayabilme yollarını sağlar. İletişim kutusu, kapatılmadan önce kullanıcıdan yanıt gerektirir.

Windows, geçici bir durumda (bir kerede birden fazla belge açık olabilecek bir metin düzenleyicisi gibi) veya kalıcı olarak (uygulama devam etmeden önce, bir dışarı aktarma iletişim kutusu gibi) kullanılabilir.

Açık iletişim kutusu

bu makalede, Xamarin. Mac uygulamasında iletişim kutuları ve kalıcı Windows ile çalışmanın temelleri ele alınacaktır. Bu makalede kullanacağımız temel kavramları ve teknikleri kapsadığından, ilk olarak Hello, Mac makalesi, özellikle de xcode ve Interface Builder ve diğer ve eylemler bölümlerine giriş yapmanız önerilir.

Exposing C# classes / methods to Objective-CExposing C# classes / methods to Objective-C belgesinin bölümüne de göz atmak Isteyebilirsiniz, RegisterExport C# sınıflarınızı Objective-C nesneler ve Kullanıcı Arabirimi öğelerine bağlamak için kullanılan ve komutlarını açıklamaktadır.

Iletişim kutularına giriş

Kullanıcı eylemine (örneğin, bir dosyayı kaydetme) karşılık gelen bir iletişim kutusu görünür ve kullanıcıların bu eylemi tamamlaması için bir yol sağlar. İletişim kutusu, kapatılmadan önce kullanıcıdan yanıt gerektirir.

Apple 'a göre bir Iletişim kutusu sunmak için üç yol vardır:

  • Belge kalıcı -bir belge kalıcı iletişim kutusu, kullanıcının, kapatılmış olana kadar belirli bir belge içinde başka bir şey gerçekleştirmesini engeller.
  • Uygulama kalıcı -uygulama kalıcı iletişim kutusu, kullanıcının, kapatılıncaya kadar uygulamayla etkileşime masını önler.
  • Kalıcı olmayan Kalıcı olmayan Iletişim kutusu, kullanıcıların belge penceresiyle etkileşime devam ederken iletişim kutusundaki ayarları değiştirmesine olanak sağlar.

Herhangi bir standart NSWindow , özel bir iletişim kutusu olarak görüntülenebilir.

Örnek bir kalıcı pencere

Belge kalıcı Iletişim kutusu sayfaları

Bir sayfa , belirli bir belge penceresine eklenmiş kalıcı bir iletişim kutusu olduğundan, iletişim kutusunu kapatıncaya kadar kullanıcıların pencere ile etkileşimde olmasını önler. Bir sayfa, çalıştığı pencereye iliştirilir ve herhangi bir anda bir pencere için yalnızca bir sayfa açık olabilir.

Örnek bir kalıcı sayfa

Tercihler Windows

Bir tercihler penceresi, kullanıcının seyrek olarak değiştirdiği uygulamanın ayarlarını içeren engelleyici olmayan bir iletişim kutusu. 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

Iletişim kutusunu aç

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

Aç iletişim kutusu

macOS, kullanıcılarınızın kullandıkları her uygulamada tutarlı bir yazdırma deneyimine sahip olması için uygulamanızın görüntüleyeceği standart yazdırma ve sayfa Kurulum Iletişimleri sağlar.

Yazdır Iletişim kutusu hem serbest bir kayan iletişim kutusu olarak görüntülenebilir:

Yazdır iletişim kutusu

Ya da bir sayfa olarak görüntülenebilir:

Yazdırma sayfası

Sayfa yapısı Iletişim kutusu hem serbest bir kayan iletişim kutusu olarak görüntülenebilir:

Sayfa Yapısı iletişim kutusu

Ya da bir sayfa olarak görüntülenebilir:

Sayfa kurulum sayfası

Iletişim kutularını Kaydet

Kaydet Iletişim kutusu kullanıcılara bir öğeyi bir uygulamaya kaydetmek için tutarlı bir yol sağlar. Kaydet Iletişim kutusunda iki durum vardır: minimal (daraltılmış olarak da bilinir):

Kaydet iletişim kutusu

Ve genişletilmiş durum:

Genişletilmiş bir Kaydet iletişim kutusu

Minimum Kaydet iletişim kutusu ayrıca bir sayfa olarak görüntülenebilir:

En küçük kayıt sayfası

, Genişletilmiş Kaydet iletişim kutusu gibi:

Genişletilmiş bir kayıt sayfası

Daha fazla bilgi için Apple 'ın OS X ınsan arabirimi yönergelerininiletişim kutuları bölümüne bakın.

Project kalıcı pencere ekleme

Ana belge penceresinden bir Xamarin. Mac uygulamasının, Kullanıcı için Tercihler veya Inspector paneli 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ı xcode 'un Interface Builder içinde düzenlenecek şekilde açın.

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

    Kitaplıktan bir görünüm denetleyicisi seçme

  3. Kimlik denetçisinde, sınıf adıiçin girin:

    Sınıf adı CustomDialogController olarak ayarlanıyor.

  4. Mac için Visual Studio 'e geri dönün, xcode ile eşitlemesine ve dosyayı oluşturmaya izin verin CustomDialogController.h .

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

    Xcode 'da Kullanıcı arabirimini tasarlama

  6. İletişim kutusu penceresine iletişim kutusunu açacak kullanıcı arabirimi öğesinden denetim sürükleme yoluyla uygulamanızın ana penceresinden yeni görünüm denetleyicisine bir kalıcı bakış oluştur. Tanımlayıcıyı ata :

    Kalıcı bir g

  7. Herhangi bir eylem ve aykırı kullanım olanağı:

    Bir eylemi yapılandırma

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

CustomDialogController.csDosyanı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, iptal edilen veya kabul edilen iletişim kutusuna tepki vermek için, iletişim kutusunun başlığını ve açıklamasını ve birkaç olayı ayarlamak için birkaç özellik sunar.

Sonra, 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 iletişim kutusundaki Interface Builder tanımladığımız ve başlık ve açıklamayı ayarlayan SEG 'yi başlatır. Ayrıca, kullanıcının iletişim kutusunda yaptığı seçeneği de işler.

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

Örnek bir iletişim kutusu

windows 'u bir Xamarin. Mac uygulamasında kullanma hakkında daha fazla bilgi için lütfen Windows ile çalıştığimize bakın.

Özel bir sayfa oluşturma

Bir sayfa , belirli bir belge penceresine eklenmiş kalıcı bir iletişim kutusu olduğundan, iletişim kutusunu kapatıncaya kadar kullanıcıların pencere ile etkileşimde olmasını önler. Bir sayfa, çalıştığı pencereye iliştirilir ve herhangi bir anda bir pencere için yalnızca bir sayfa açık olabilir.

Xamarin. Mac ' te özel bir sayfa oluşturmak için aşağıdakileri yapalim:

  1. Çözüm Gezgini, dosyayı xcode 'un Interface Builder içinde düzenlenecek şekilde açın.

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

    Kitaplıktan bir görünüm denetleyicisi seçme

  3. Kullanıcı arabiriminizi tasarlama:

    Kullanıcı arabirimi tasarımı

  4. Ana pencerenize yeni görünüm denetleyicisine bir sayfa kümesi oluşturun:

    Sayfa başlangıç türünü seçme

  5. Kimlik denetçisinde, görünüm denetleyicisinin sınıfınıadlandırın :

    Sınıf adı SheetViewController olarak ayarlanıyor.

  6. Gerekli aykırıişlemleri ve eylemleritanımlayın:

    Gerekli aykırı Işlemleri ve eylemleri tanımlama

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

Sonra, 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
    }
}

Sonra, dosyayı düzenleyin ViewController.cs , PrepareForSegue yöntemi düzenleyin 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ırdık ve sayfayı açdığımızda, pencereye eklenecektir:

Örnek bir sayfa

Tercihler Iletişim kutusu oluşturma

Interface Builder tercih görünümünü oluşturmadan önce, tercihleri değiştirmeyi işlemek için özel bir g/kapat türü eklememiz gerekir. Projenize yeni bir sınıf ekleyin ve bunu çağırın ReplaceViewSeque . Sınıfı 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 bir prolog oluşturulduğunda, tercihlerinizi işlemek için Xcode 'un Interface Builder yeni bir pencere ekleyebiliriz.

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

  1. Çözüm Gezgini, dosyayı xcode 'un Interface Builder içinde düzenlenecek şekilde açın.

  2. Tasarım Yüzeyi 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 ekleniyor

  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ıktanyeni bir araç çubuğu denetleyicisi sürükleyin:

    Kitaplıktan bir araç çubuğu denetleyicisi seçin

  6. Ve Tasarım Yüzeyi pencerede bırakın:

    Yeni bir araç çubuğu denetleyicisi ekleme

  7. Araç çubuğınızın tasarımını Düzenle:

    Araç çubuğunu Düzenle

  8. Control-Click ve her bir araç çubuğu düğmesinden yukarıda oluşturduğunuz görünümlere sürükleyin. Özel bir başlangıç türü seçin:

    Özel bir g/u türü ayarlanıyor.

  9. Yeni bir başlangıç seçin ve sınıfı şu şekilde ayarlayın :

    SEG sınıfını ayarlama

  10. Tasarım Yüzeyi menü çubuğu tasarımcısında , uygulama menüsünde Tercihler...' i seçin ve bir göster (göster ) oluşturmak için Tercihler penceresine sürükleyin.

    Tercihleri Tercihler penceresine sürükleyerek SEG türünü ayarlama.

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

Kodu çalıştırdık ve uygulama menüsündetercihleri... seçeneğini belirlerseniz pencere görüntülenir:

Word profilini görüntüleyen örnek bir tercihler penceresi.

Windows ve araç çubuklarıyla çalışma hakkında daha fazla bilgi için lütfen Windows ve araç çubukları belgelerinize bakın.

Tercihleri kaydetme ve yükleme

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

İlk olarak, projeye yeni bir AppPreferences sınıf ekleyin ve öğesinden öğesini alın NSObject . Tercihler, veri bağlama ve Key-Value kodlaması kullanmak üzere tasarlanacaktır ve bu da tercih formlarını oluşturma ve sürdürme sürecini çok daha basit hale getirir. Tercihler küçük miktarda basit veri türünde yer aladıklarından, NSUserDefaults değerleri depolamak ve almak için yerleşik ' i kullanın.

Dosyayı düzenleyin AppPreferences.cs 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 SaveInt , LoadIntSaveColorLoadColorNSUserDefaults daha kolay çalışmayı kolaylaştırmak için,,, vb. gibi birkaç yardımcı yordamlar içerir. Ayrıca, NSUserDefaults işlemek için yerleşik bir yola sahip olmadığından NSColors , NSColorToHexString ve NSColorFromHexString yöntemleri, renkleri kolayca depolanabilecek ve alınabilecek Web tabanlı onaltılık dizelere ( #RRGGBBAA burada AA Alfa saydamlığına) dönüştürmek için kullanılır.

AppDelegate.csDosyasında, uygulama genelinde kullanılacak AppDelegate.cs nesnesinin 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
        
        ...

Tercih görünümlerine yönelik bağlantı tercihleri

Ardından, tercih sınıfını, tercih penceresi ve yukarıda oluşturulan görünümlerde Kullanıcı Arabirimi öğelerine bağlayın. Interface Builder ' de 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üzenlenmek ü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 şeyi bitirdiğine dikkat edin: Ilk olarak AppApp 'e erişimi kolaylaştırmak için bir yardımcı özellik vardır. İkinci olarak, Preferences özelliği, bu görünüme yerleştirilmiş kullanıcı arabirimi denetimleriyle veri bağlama için genel Preferences sınıfını gösterir.

Sonra, film şeridi dosyasına çift tıklayarak Interface Builder (yalnızca yukarıda yapılan değişiklikleri görün) ' de yeniden açın. Tercihler arabirimini görünümünde oluşturmak için gereken tüm UI denetimlerini sürükleyin. Her denetim için bağlama denetçisine geçin ve apppreference sınıfının bireysel özelliklerine bağlayın:

Bağlama denetçisi

Tüm panellerin (görünüm denetleyicileri) ve tercih özelliklerinin tümü için yukarıdaki adımları tekrarlayın.

Tüm açık Windows tercih değişiklikleri uygulanıyor

Yukarıda belirtildiği gibi, tipik bir macOS uygulamasında, kullanıcı uygulamanın kullanıcı tercihlerinde değişiklik yaptığında, bu değişiklikler otomatik olarak kaydedilir ve Kullanıcı uygulamada açık olabilecek herhangi bir Windows 'a uygulanır.

Uygulamanızın tercihlerini ve pencerelerini dikkatli bir şekilde planlamak ve tasarlamak, en az sayıda kodlama çalışması sayesinde bu işlemin son kullanıcıya sorunsuz ve şeffaf bir şekilde gerçekleşmesini sağlar.

Uygulama tercihlerini kullanan herhangi bir pencerede, Appdelegate 'imize erişim kolaylaştırmak Için Içerik görünümü denetleyicisine aşağıdaki yardımcı özelliği ekleyin:

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

Sonra, kullanıcı tercihlerine bağlı olarak 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 pencere 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 pencereler için tercih değişikliklerini uygulamak üzere 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 kapandığında hiçbir tercih değişikliklerinin açık Windows gönderilmesine neden olur.

Son olarak, tercih penceresi denetleyicisini 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 varken, kullanıcı uygulamanın tercihlerini düzenler ve tercih penceresini kapatırsa, değişiklikler tüm açık Windows uygulanır:

Örnek bir tercihler penceresi, diğer birkaç açık pencereyle birlikte gösterilir.

Aç Iletişim kutusu

Aç Iletişim kutusu, kullanıcılara bir uygulamadaki bir öğeyi bulmak ve açmak için tutarlı bir yol sağlar. Xamarin. Mac uygulamasında açık bir Iletişim kutusu göstermek 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östermek için yeni bir belge penceresi açılıyor. Uygulamanız için bu kodun işlevlerini kullanmanız gerekir.

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

  • CanChooseFiles - Kullanıcı dosyaları seçip seç,.
  • CanChooseDirectories - Kullanıcı dizinleri seçebilir.
  • AllowsMultipleSelection - Kullanıcı bir seferde birden fazla dosya seçebilir.
  • Resolvealias - ve diğer ad seçilirse özgün dosyanın yolunda çözümlenmektedir.
  • AllowedFileTypes -kullanıcının uzantı veya UTİolarak seçebileceğiniz dosya türlerinin dize dizisidir. Varsayılan değer null , tüm dosyaların açılmasına izin veren ' dır.

RunModal ()Yöntemi aç Iletişim kutusunu görüntüler ve kullanıcının dosya veya dizinleri seçmesine izin verir (Özellikler tarafından belirtildiği gibi) ve 1 Kullanıcı RunModal () düğmesine tıkladığında döndürür.

Aç Iletişim kutusu, kullanıcının seçili dosyalarını veya dizinlerini, özelliğindeki URL 'lerin bir dizisi olarak döndürür URL .

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

Açık iletişim kutusu

Yazdırma ve sayfa Kurulum Iletişim kutuları

macOS, kullanıcılarınızın kullandıkları her uygulamada tutarlı bir yazdırma deneyimine sahip olması için uygulamanızın görüntüleyeceği standart yazdırma ve sayfa Kurulum Iletişimleri sağlar.

Aşağıdaki kod standart Yazdır Iletişim kutusunu 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 ();
        }
    }
}

ShowPrintAsSheetÖzelliğini olarak ayarlarsanız false , 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

ShowPrintAsSheetÖzelliğini olarak ayarlarsanız true , uygulamayı çalıştırın ve Yazdır iletişim kutusunu görüntüleyin, aşağıdakiler görüntülenir:

Yazdırma sayfası

Aşağıdaki kodda sayfa düzeni Iletişim kutusu görüntülenir:

[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 ();
        }
    }
}

ShowPrintAsSheetÖzelliğini olarak ayarlarsanız false , 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

ShowPrintAsSheetÖzelliğini olarak ayarlarsanız true , 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 kurulum sayfası

Yazdırma ve sayfa Kurulum Iletişim kutularıyla çalışma hakkında daha fazla bilgi için lütfen Apple 'ın Nsprintpanel ve nspagelayout belgelerine bakın.

Kaydet Iletişim kutusu

Kaydet Iletişim kutusu kullanıcılara bir öğeyi bir uygulamaya kaydetmek için tutarlı bir yol sağlar.

Aşağıdaki kod standart kaydet Iletişim kutusunu gösterir:

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ğiniz dosya türlerinin dize dizisidir. Dosya türü, bir uzantı veya UTİolarak belirtilebilir. Varsayılan değer null , tüm dosya türlerinin kullanılmasına izin verir.

özelliğini olarak ShowSaveAsSheetfalse ayarlarsanız, uygulamayı çalıştırın ve Dosya ShowSaveAsSheetfalse seçerse, aşağıdakiler görüntülenir:

Kaydet iletişim kutusu

Kullanıcı iletişim kutusunu genişlet kullanılabilir:

Genişletilmiş kaydetme iletişim kutusu

özelliğini olarak ShowSaveAsSheettrue ayarlarsanız, uygulamayı çalıştırın ve Dosya ShowSaveAsSheettrue seçerse, aşağıdakiler görüntülenir:

Bir kaydetme sayfası

Kullanıcı iletişim kutusunu genişlet kullanılabilir:

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 makale, Xamarin.Mac uygulamasında Kalıcı Windows, Sayfalar ve standart sistem İletişim Kutuları ile çalışmaya ayrıntılı bir bakış sağlar. Kalıcı Windows, Sayfalar ve İletişim Kutuları'nın farklı türlerini ve kullanımlarını, Xcode'un Interface Builder'sinde Kalıcı Windows ve Sayfaların nasıl oluşturularak korunarak korunarak C# kodunda Kalıcı Windows, Sayfalar ve İletişim Kutuları ile çalışma olduğunu gördük.