2017年5月2日火曜日

C# VisualStudio for Mac で Xamarin.Mac を使ってみる。


「VisualStudio for Mac」を使うと、
「C#」の記述で「Xamarin.Mac」を経由して「Cocoa」を使う事ができます。
XamarinでMacネイティブのプロジェクトを試してみます。


「Xamarin.Mac」から「Cocoa」を使ってみる


「VisualStudio for Mac」で新しいプロジェクトを作成します。
「Mac -> アプリ」の「Cocoa App」を選択
私は「AppName」を「testCocoa」として、
「プロジェクト名」と「ソリューション名」も「testCocoa」にしました。

このように表示されます。

・「AppDelegate.cs」…
  「DidFinishLaunching」メソッドはアプリケーションの開始時に呼ばれます。
  「WillTerminate」メソッドはアプリケーションの終了時に呼ばれます。
・「Entitlements.plist」…
  サンドボックス等セキュリティ範囲の制御。
・「Info.plist」…
  「Xamarin.Mac」のアプリケーション情報。
・「Main.cs」…
  メインエントリポイント。プログラムの開始場所です。
・「Main.storyboard 」…
  「Xcode」の「Interface Builder」を使用してこのファイルを編集し、UIを作ります。(ここでは、最初にUIへボタンとラベルを配置します。)
・「ViewController.cs」…
  「MVCモデル」の「コントローラー」となる部分。
  「storyboard」で作成された「ビュー(Form)」の「コントローラー」を受け持ちます。
  主にこのファイルに
  「ビュー(Form)」からの「イベント通知(ボタンクリック等)」の受け取りと、
  「ビュー(Form)」内の「コントロール(ラベル等)」の操作、参照の
  コードを記述します。
  「ViewDidLoad」メソッドは「View(Form)」がインスタンス化した直後に呼ばれます。
  「RepresentedObject」プロパティは「View(Form)」間での値の受け渡し用に使います。
・「ViewController.Designer.cs」…
  「Xcode」の「Interface Builder」でUI作成時、「VisualStudio for Mac」によって、
  自動更新される。手動で変更してはいけません。
  (「Xcode」側の「ViewController.h」とこのファイルが自動で同期される。)


UIを変更したいので
「Main.storyboard」をダブルクリックして、
「Xcode」の「Interface Builder」で開きます。


開かれた「Xcode」側のプロジェクトに変更を加えると、
「VisualStudio for Mac」側のプロジェクトに同期されます。

一番下のウィンドウ「View Controller」へ「Push Button」の「コントロール」を配置します。


配置した「Push Button」の「コントロール」のプロパティを表示して、
「title」を「開始」に変更します。



続いて、「Label」の「コントロール」を配置します。



配置したらこの画像に従って「下部のアイコン」をクリック。
「Add New Constraints」が表示されます。
「上、右、左」空き量の値を全て「30」と入力します。
設定後、「Add 3 Constraints」を押します。
これで「View(Form)」に対して「Label」の表示位置が左上に固定されます。

コードへ「接続」…
 Macの「Interface Builder」の場合、
 配置した「コントロール」をコードへ「接続」させる必要があります。
 「アウトレッド接続」と「アクション接続」があります。
 ・「Outlets」…
  「コントロール」の「プロパティ」が「アウトレッド接続」のコードを介して、
  公開されます。
  (「コントロール」の「プロパティ」は最初Publicではありません。
  「プロパティ」を参照する為には公開する必要があります。)
 ・「Action」…
  「コントロール」の「イベント」を「アウトレッド接続」のコードを介して、
  「イベントハンドラ」へと割り当てます。
  「コントロール」に対して「クリックイベント」等の「イベント」時に、
  実行するメソッドの割り当て(「アクション接続」)を行います。
  この方法を使うと、複数の「コントロールのイベント」を
  1つのメソッドに対して割り当てる事も可能です。

「コントロール」を「アウトレッド接続」と「アクション接続」させる
コードは「ViewController.h」へ記述されます。
ここでは、
「Label」を「アウトレッド接続」、「Push Button」を「アクション接続」させる
コードを「ViewController.h」内へ記述させます。
「Xcode」側「ViewController.h」への記述は、
「VisualStudio for MAC」側「ViewController.Designer.cs」へ
自動的に同期されます。
手順を書きます。最初は少し戸惑うかもしれません。
まず、
「Main.storyboard」を「Xcode」で以下のような形で表示させておきます。


次に、「Xcode」の右上の「丸が二つ重なったアイコン」をクリック。
コードの編集ウィンドウが開きます。
(「ViewController.h」でないコードが表示された状態になります。)


表示させたいコードをフォルダ階層のリストから選択できます。
ここで、「ViewController.h」のコードを表示させておいて下さい。
これで「コントロール」をコードへ「接続」させる準備ができました。

「Label」を「アウトレッド接続」させるコードを記述させて、
「プロパティ」を公開します。
「Label」を「Control」キーを押しながらドラッグして…

「ViewController.h」の画面の位置の行へドロップします。
(「@interface 〜{}」と「@end」の間の行)
ドロップすると以下の表示になります。
「Conection」が「Outlet」である事を確認後、
「Name」に「Label1」と記入し、「Connect」を押します。


「ViewController.h」に
「Label」を「アウトレッド接続」させるコードが記述され、
「プロパティ」が公開されました。

次に、
「Push Button」を「アクション接続」させるコードが記述させ、
「クリックイベント」をメソッド(イベントハンドラ)へ割り当てます。
「開始ボタン」を「Control」キーを押しながらドラッグして…
「ViewController.h」の画面の位置の行へドロップ。
(「@interface 〜{}」と「@end」の間の行)


「Conection」を「Action」にします。
「Name」に「ClickedButton」と記入し、「Connect」を押します。

「ViewController.h」に
「Push Button」を「アクション接続」させるコードが記述され、
「クリックイベント」がメソッド(イベントハンドラ)へ割り当てられました。

「Xcode」を終了させて下さい。
終了したら「VisualStudio for Mac」を表示させ、
「ViewController.designer.cs」のファイルを確認してみて下さい。


「ViewController.h」と同期され、
「Label1」の「プロパティ」が公開され、
「ClickedButton」メソッドへのイベントハンドラが設定されているのが確認できます。

最後に処理を実装します。
「ViewController.cs」を開いて下さい。
「ViewController」クラス内へ以下のコードを貼り付けます。
  private int ClickedCount = 0;
  partial void ClickedButton(NSObject sender)
  {
   int MyClickedCount = ++ClickedCount;
   //非同期処理
   var task = System.Threading.Tasks.Task.Run(() =>
   {
    for (int i = 0; i < 6; i++)
    {
     //ワーカースレッドからメインスレッドUIの更新
     InvokeOnMainThread(delegate
     {
      Label1.StringValue = MyClickedCount.ToString() + "回目" + i.ToString() + "秒";
     });
     System.Threading.Thread.Sleep(1000);
    }
    InvokeOnMainThread(delegate
    {
     var alert = new NSAlert();
     alert.InformativeText = MyClickedCount.ToString() + "回目非同期処理終了";
     alert.RunModal(); //モーダルダイアログ表示
    });
   });
  }
気をつけたいのは、
イベントハンドラのメソッドが「partial」となっているところです。

これで完成となります。
実行すると、
「1回目0秒→1回目1秒→…→1回目5秒」「1回目非同期処理終了」
の順に表示されます。
「非同期処理」の為、
「開始」ボタンを何回か押すと並列的に処理されます。





以下サイトを参考にしました。
https://developer.xamarin.com/guides/mac/getting_started/hello,_mac/
https://github.com/ytabuchi/XamarinHOL

0 件のコメント:

コメントを投稿

↑Topへ