LoginSignup
6
8

More than 5 years have passed since last update.

[VS-Mac]VisualStudio for Mac (Cocoa)でファイルダイアログ表示

Posted at

 VisualStudio for Macをインストールしたものの、Cocoa GUアプリ作成にはXcodeとInterfaceBuilder及びAPIの知識が必要で、自分のようにWindowsから移行してXcodeとSwiftのGUアプリに挫折した者にとっては使いこなせない強敵です。
 幸いに、XamarinのMacに関するGuidesのページでサンプルアプリのチュートリアルと説明の記事があり、慣れないAPIと英語ではあるものの、なんとか自分でもできそうな気がしてしまいます。
 ところが、自分で新たなツールを作ろうとすると十分に理解できていないことから、何度も同じことを調べ直さなければならず大変でした。

 そこで、小物ツール作成時に役立つように、これらの記事とサンプルコードを元に、個人的に利用する可能性が高い機能を私的Tutorialとして記事にしておくことにします。

 第1回目は、InterfaceBuilderの使い方とコード実装を、ツールバーとファイルダイアログの表示を例にした備忘録です。

利用するAPI:

概要

  • ツールボタンのクリックでファイルを開くダイアログを表示。
  • Openで選択したファイル名をViewに配置したラベルに表示する。
  • ツールバーのParentであるWindowsControllerからViewControllerのViewに存在するコントロールを操作する例。
  • おまけとして、アプリを直接終了できるツールボタン。

ソリューションの新規作成

  • VisualStudioで「NewProject」
  • 「Mac」「Cocoa App」を選択
  • AppName 「MyTutorial_OpenFile」
  • 作成

InterfaceBuilderでの操作

Main.storyboardをダブルクリックして、Xcodeを起動

WindowsControllerのクラス名を設定

  1. ツールボタンのアクションを追加するためのWindowsController.hをXcodeで表示させるために必要。
  2. Window Controller を選択、Identify Inspectorを表示してClassを「WindowController」と入力。OpenFile01.png
  3. XcodeメニューからSaveして、VisualStudioに戻る。
  4. VisualStudioに「WindowController.cs」が追加された。OpenFile02.png
  5. Main.storyboardをダブルクリックして、Xcodeを再度表示してコードに「WindowController.h」が追加されていることを確認。OpenFile03.png
  • VisualStudioに戻る時に、Xcodeとの同期エラーのダイアログが出現することがまれにあるが、特に支障はないようだ。

コントロールの追加

  1. WindowsControllerにToolbarを追加し、これをクリックしてツールバーの編集モードにする。
  2. OpenFile用のImageToolbarItemを追加して、ImageName(アイコン)とLabelを「File」に変更。
  3. 同様にQuit用ImageToolbarItemを追加して、Labelを「Quit」に変更。
  4. AllowedToolbarItemsに追加したItemを、DefaultToolbarItemsにドラッグ。不要のツールバーをツールバー外にドロップして削除。OpenFile04.png

ツールボタンActionの追加

  1. XcodeでAssistantEditorを表示(右上のダブルサークル)
  2. AssistantEditorに「WindowController.cs」を表示OpenFile05.png

  3. ツールバーのAllowedToolbarItemから「File」Itemを選択して、Ctrlキーを押したまま「WindowController.h」の @end の前にドラッグ

  4. Connectionを「Actionに変更」。Nameに「FileButton_Click」と入力して「connect」ボタンをクリック。OpenFile06.png

  5. 同様に「Quit」ItemもActionとしてドラッグし、Nameを「QuitButton_Click」と入力。

  6. ツールバーの「done」ボタンをクリックして編集モードから抜ける。

  7. Save後のWindowController.designer.csにActionの関数宣言が追加されている。OpenFile08.png

ViewControllerにラベルを追加

  1. ViewControllerを表示
  2. LabelをViewにドラッグしてサイズを適当に変更
  3. AssistantEditorにViewController.hを表示
  4. 追加したLabelを選択肢、Ctrlキーを押したまま @end の前にドラッグ
  5. Connectionは「Outlet」のままで変更せず、Nameを「Label1」と入力してConnect。OpenFile07.png

  6. XcodeをSaveしてVisualStudioに戻る。

  7. ViewController.designer.csにLabel1がNSTextFieldの変数として宣言されている。

VisualStudioでコードの追加と編集

ViewController.csの編集

  1. Windowタイトルとラベルの表示テキストを変更する関数の追加
    //chnage title  UserInterface - Windows - Setting a Window's Title
    public override void ViewWillAppear()
    {
          base.ViewWillAppear();
          this.View.Window.Title = "My Tutorial NSOpenPanel";
          ChangeLabeltext("");
    }
    public void ChangeLabeltext(string str)
    {
          this.Label1.StringValue = str;
    }

WindowController.csの編集

  1. ViewControllerを参照するController変数を作成
    public ViewController Controller
    {
        get { return ContentViewController as ViewController; }
    }

 
2. FileButton_Click アクションプロシージャー

    partial void FileButton_Click(NSObject sender)
    {
              var dlg = NSOpenPanel.OpenPanel;
              dlg.CanChooseFiles = true;
              dlg.CanChooseDirectories = false;
              dlg.AllowsMultipleSelection = false;
              dlg.DirectoryUrl = NSUrl.FromString(Environment.SpecialFolder.MyPictures.ToString());
              dlg.AllowedFileTypes = new string[] { "png", "jpeg", "jpg" };

            if ( dlg.RunModal() == 1)
              {
                    if (dlg.Urls[0] != null)
                    {
                        Controller.ChangeLabeltext(dlg.Urls[0].Path);
                    }
              }
            else
            {
                  var alert = new NSAlert()
                  {
                        AlertStyle = NSAlertStyle.Informational,
                        InformativeText = "Cancel Button Clicked",
                        MessageText = "Alert",
                  };
                  alert.RunModal();
            }
    }
  1. QuitButton_Click アクションプロシージャー
        partial void QuitButton_Click(NSObject sender)
        {
                  NSApplication.SharedApplication.Terminate(Self);
        }

コード全体像

ViewController.cs

using System;

using AppKit;
using Foundation;

namespace MyTutorial_OpenFile
{
    public partial class ViewController : NSViewController
    {
        public ViewController(IntPtr handle) : base(handle)
        {
        }

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

            // Do any additional setup after loading the view.
        }

        //###### Quote from Xamarin page ##########
        //https://developer.xamarin.com/guides/mac/user-interface/working-with-windows/
        //chnage title  UserInterface - Windows - Setting a Window's Title
        public override void ViewWillAppear()
        {
            base.ViewWillAppear();
            this.View.Window.Title = "My Tutorial NSOpenPanel";
            ChangeLabeltext("");
        }
        //#########################################
        public void ChangeLabeltext(string str)
        {
            this.Label1.StringValue = str;
        }

        public override NSObject RepresentedObject
        {
            get
            {
                return base.RepresentedObject;
            }
            set
            {
                base.RepresentedObject = value;
                // Update the view, if already loaded.
            }
        }
    }
}

WindowController.cs

// This file has been autogenerated from a class added in the UI designer.
using System;
using Foundation;
using AppKit;
namespace MyTutorial_OpenFile
{
    public partial class WindowController : NSWindowController
    {
        //###### Quote from Xamarin page ##########
        //https://developer.xamarin.com/guides/mac/application_fundamentals/copy-paste/
        public ViewController Controller
        {
            get { return ContentViewController as ViewController; }
        }
        public WindowController(IntPtr handle) : base(handle)
        {
        }
        #region ToolButton Action
        partial void FileButton_Click(NSObject sender)
        {
            //###### Quote from Xamarin page ##########
            //https://developer.xamarin.com/guides/mac/user-interface/working-with-dialogs/#The_Open_Dialog
            var dlg = NSOpenPanel.OpenPanel;
            dlg.CanChooseFiles = true;
            dlg.CanChooseDirectories = false;
            dlg.AllowsMultipleSelection = false;
            dlg.DirectoryUrl = NSUrl.FromString(Environment.SpecialFolder.MyPictures.ToString());
            dlg.AllowedFileTypes = new string[] { "png", "jpeg", "jpg" };

            if ( dlg.RunModal() == 1)
            {
                if (dlg.Urls[0] != null)
                {
                    Controller.ChangeLabeltext(dlg.Urls[0].Path);
                }
            }
            else
            {
                //###### Quote from Xamarin page ##########
                //https://developer.xamarin.com/guides/mac/user-interface/working-with-alerts/
                var alert = new NSAlert()
                {
                    AlertStyle = NSAlertStyle.Informational,
                    InformativeText = "Cancel Button Clicked",
                    MessageText = "Alert",
                };
                alert.RunModal();
            }
        }
        partial void QuitButton_Click(NSObject sender)
        {
            //######## Refer to StackOverFlow ##########
            //http://stackoverflow.com/questions/1748895/how-to-properly-quit-application-call-exit0
            NSApplication.SharedApplication.Terminate(Self);
        }
        #endregion
    }
}

Reference:

  1. Monoのライセンス Mono Licensing
  2. Xamarine - Developers - Guides - Mac - Getting Started - Hello,Mac
  3. Xamarine - Developers - Guides - Mac - Application Fundamentals - Working with .xib Files   
  4. Xamarine - Developers - Guides - Mac - Application Fundamentals - Working with Copy and Paste WindowControllerからViewContorollerの操作(ContentViewController)
  5. Xamarine - Developers - Guides - Mac - User Interface - Toolbars
  6. Xamarine - Developers - Guides - Mac - User Interface - Dialogs
      file dialogの引用修正
  7. Xamarine - Developers - Guides - Mac - User Interface - [Windows]  (https://developer.xamarin.com/guides/mac/user-interface/working-with-windows/)   Window Title変更の引用修正
  8. Xamarine - Developers - Guides - Mac - User Interface - Alerts
  9. viva Cocoa Windowsなどのほかのプラットフォームから転向されてきた方へ
  10. stackoverflow How to properly quit application, call exit(0)?
      Swiftのコードを参考にした。

2-8で引用した部分の著作権はXamarinに帰属します。

License:

Copyright (c) 2017 grayhead0603
Released under the MIT license

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8