[Xamarin.Mac] View Controller間でデータを受け渡すには

前回の記事では、View Controllerをコードから表示する方法について紹介しました。

今回は、View Controller間でのデータの受け渡し方法について見ていきましょう。

1.メインウィンドウの作成

はじめに新規でプロジェクトを作成して、メインウィンドウにButtonを1つ、その下にText Fieldを1つ貼り付けます。

続いて、貼り付けたButtonのアクション接続を作成します。アクション名は「showSubView」とします。

次に、貼り付けたText Fieldのアウトレット接続を作成します。接続名はfirstTextとしてください。

アクション接続とアウトレット接続の作成方法については「シンプルなアプリを作ってみよう 〜アクションとアウトレット〜」を参照ください。

作成したアクション接続とアウトレット接続のコードを以下に示します。

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>


@interface ViewController : NSViewController {
    NSTextField *firstText;
}
- (IBAction)showSubView:(id)sender;
@property (assign) IBOutlet NSTextField *firstText;

@end

2.サブウィンドウの作成

続いて、もう1つView Controllerを配置します。

このView ControllerにもButtonとText Fieldを配置します。

次にView Controllerを選択してCustom Classに「SecondViewController」と入力して[return]キーを押し、[command]+[s]で上書き保存をします。この操作によってサブウィンドウ用のクラスが作成されます。このクラスはNSViewControllerを継承しています。

次にアシスタントエディタでSecondViewController.hを開いておき、今配置したText Fieldのアウトレット接続を作成します。アウトレット接続の名前はsecondTextとしてください。

またButtonのアクション接続も作成します。アクション接続名はsubViewCloseとします。

SeconViewController.hのコードは以下のようになります。

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>

@interface SecondViewController : NSView {
    NSTextField *secondText;
}
@property (assign) IBOutlet NSTextField *secondText;
- (IBAction)subViewClose:(id)sender;

@end

ここまでできたら[command]+[s]を押して、Visual Studioへ戻ります。

3.セグエの作成

続いてセグエを作成しましょう。メインウィンドウからサブウィンドウに向かってドラッグ&ドロップし、セグエを作成します。表示されたManual SegueのダイアログではModalを選択することとします。

次に作成したSegueを選択して「MySegue」という名前を付けます。あとで、この名前でコードからサブウィンドウを開けるように作成します。

4.メインウィンドウのコードを作成する

続いてメインウィンドウのコードを作成するのですが、その前にサブビュー側でメインウィンドウから渡された値を受け取ることができるプロパティを作成しておきましょう。

Visual StudioでSecondViewController.csを開いて、以下のように、TextValueというプロパティを追加します。

// This file has been autogenerated from a class added in the UI designer.

using System;

using Foundation;
using AppKit;

namespace WindowSample5
{
  public partial class SecondViewController : NSViewController
  {
    // メインウィンドウから受け取る値用のプロパティ
    public string TextValue { get; set; }

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

次に、ViewController.csを開いてメインウィンドウのコードを以下のように入力します。

using System;

using AppKit;
using Foundation;

namespace WindowSample5
{
  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.
    }

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

    // ここから追加コード

    // Buttonクリック時の処理
    partial void showSubView(NSObject sender)
    {
      // Segueでサブビューを表示
      PerformSegue("MySegue", this);
    }

    // Segueでサブウィンドウが開かれる前に実行されるメソッド
    public override void PrepareForSegue(NSStoryboardSegue segue, NSObject sender)
    {
      base.PrepareForSegue(segue, sender);

      // サブウィンドウのインスタンスを取得
      SecondViewController sv = segue.DestinationController as SecondViewController;
      // サブウィンドウのプロパティに値をセット
      sv.TextValue = this.firstText.StringValue;
    }

    // サブウィンドウから呼び出してメインウィンドウのText Fieldに値をセットするメソッド
    public void SetTextValue(string textValue)
    {
        this.firstText.StringValue = textValue;
    }
  }
}

Buttonには、showSubView というアクション接続を作成したので、partial void showSubView というメソッドを追加しています。このめそっどの中では PerformForSegue メソッドを使用してサブウィンドウを開きます。

サブウィンドウを開く前に値を渡したいので、PrepareForSegue というメソッドをオーバーライドして追加しています。このメソッドは、セグエが実行される前に起動して処理が行われます。よってメソッドの中では、サブウィンドウのインスタンスを取得して、サブウィンドウのプロパティである TextValue にメインウィンドウの Text Field の値を設定しています。

最後に、サブウィンドウからメインウィンドウへ値をセットできるようにするために SetTextValue というメソッドを追加しています。引数で受け取った値をメインウィンドウのText Fieldに設定しています。

5.サブビューのコードを作成する

最後ににサブビュー側のコードを作成しましょう。

ソリューションエクスプローラーで SecondViewController.cs をダブルクリックして開き以下のようにコードを入力します。

// This file has been autogenerated from a class added in the UI designer.

using System;

using Foundation;
using AppKit;

namespace WindowSample5
{
  public partial class SecondViewController : NSViewController
  {
    // メインウィンドウから受け取る値用のプロパティ
    public string TextValue { get; set; }

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

    // ここから追加コード
    public override void ViewDidLoad()
    {
      base.ViewDidLoad();

      // Text Fieldにメインウィンドウから受け取った値をセット
      this.secondText.StringValue = this.TextValue;
    }

    partial void subViewClose(NSObject sender)
    {
      // メインウィンドウのインスタンスを取得
      ViewController vc = this.PresentingViewController as ViewController;
      // メインウィンドウのメソッドを呼び出して、サブウィンドウのText Fieldの値を渡す
      vc.SetTextValue(this.secondText.StringValue);
      // サブウィンドウを閉じる
      this.View.Window.Close();
    }
  }
}

オーバーライドした ViewDidLoad は、画面が開かれたときに初期化をするメソッドです。ここでは、メインウィンドウから受け取った値が入っている TextValue プロパティを、Text Fieldに設定しています。これによりサブウィンドウが開いたときに、メインウィンドウから受け取った値が Text Field に表示されます。

subViewClose というメソッドは Button がクリックされたときに実行されるメソッドです。この中ではメインウィンドウのインスタンスを取得して、SetTextValue というメソッドを使用して、サブウィンドウのText Fieldの値を渡しています。最後に Close メソッドを実行してサブウィンドウを閉じます。

6.実行してみよう

それでは実行して確認をしてみましょう。

メインウィンドに「メインウィンドウの値」と入力してButtoonをクリックすると、サブウィンドウが表示されText Fieldには「メインウィンドウの値」と表示されます(上がメインウィンドウ、下がサブウィンドウの図です)。

次にサブウィンドウのText Fieldに「終了」と入力してButtonをクリックすると、サブウィンドウが閉じられてメインウィンドウのText Fieldに「終了」が表示されます(上がサブウィンドウ、下がメインウィンドウの図です)。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です