trapemiyaの日記

hatenablogが新しくなったんで新規一転また2019年1月からちょこちょこ書いてます。C#中心のプログラミングに関するお話です。

オプションメニュー

よちよち歩きで開発を進めているわけですが、おかげさまでネット上にはいろいろ情報が転がっていて助かっています。
ただ、Xamarin + MvvmCross の組み合わせの情報を探し出しても、そこで解説されているコードをどこに書いてよいのかわからず、MvvmCrossを導入していなくてXamarinのみで開発しているコードを参考にすると、うまく動かなかったりします。しかもエラーにならなくて動作しないだけだから質(タチ)が悪いんですね。まぁ、正確にはそのコードを書いても、その部分は全く通らないからエラーにならないだけなんですけどね。

なんで、ど素人がXamarin + MvvmCrossでアプリケーションを開発していく上での必要な情報をしばらく発信していこうかと思います。自分用のメモも兼ねていますので、内容はかなりベーシックになると思いますが、暖かい目でどうぞご覧下さい。

さて、早速ですが、オプションメニューの出し方を書きます。あ〜、ちなみにVisual Studioを使っています。基本的に慣れているのがその理由です。でも、C# + Visual Studioで開発できるなんでXamarinさまさまですね。ありがたい限りです。

オプションメニューを出すのは簡単とよく書いてあります。そう、

public override bool OnCreateOptionsMenu(IMenu menu)
{
    MenuInflater.Inflate(Resource.Menu.OptionMenu, menu);
    return true;
}

を追加すれば良いだけと。書く場所は、Activityクラスを継承したクラスだそうです。
しかし、これはMvvmCrossを導入していない場合なんですね。導入していると、MvxActivityクラスを継承したクラスになります。
このクラスは、通常、ViewフォルダーにViewの名前と同じ名前でC#のコードのファイルがあります。例えば、Resources\drawable\layout\MainView.axmlですと、Views\MainView.csになります。このファイルで、MvxActivityクラスを継承したMainViewというクラスが定義されています。

しかし、ど素人はまだはまります。そう、基本的にまだXamarin + MvvmCrossのお作法がわかっていないからです(苦笑)
MenuInflater.Inflate(Resource.Menu.OptionMenu, menu);
で、Resource.Menu のMenuなんてどこにも無いよというエラーになります。
そこで想像するに、ResourcesフォルダーにMenuフォルダーを作ればいいんじゃないかと思いました。
早速作ってみましたが、エラーは取れません。
仕方なのでもう少し調査してみると、Resourcesフォルダーに、Resource.Designer.csというファイルがあるのを見つけました。
この中身をみると、ここでリソースを定義していることがわかりました。おそらく、ここにMenuフォルダーの定義も必要だと思ったのですが、ありません。
手動で追加することも考えたのですが、注意書きとして、自動生成されるのでいじるなよ的なことが思いっきり書かれていたので断念しました。
じゃあ、どうすれば自動生成されるの?と思い、Menuフォルダーに何か突っ込めばいいんじゃないかと思いました。

そこで歩を進めることにし、Menuフォルダーに入れなければならないメニューを定義したXMLファイルを入れてみました。ちなみに、以下のファイルです。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/OptionMenu1"
        android:title="Menu1" />
  <item android:id="@+id/OptionMenu2"
        android:title="Menu2" />
  <item android:id="@+id/OptionMenu3"
        android:title="Menu3" />
</menu>

これがビンゴでした! Resource.Designer.csにも自動でMenuフォルダー等、メニューの定義が追加されました。
というわけで、今回はオプションメニューが無事に表示されるところまででした。最後に、Views\MainView.csにあるMainViewクラスと、動作中の画面を載せておきます。

[Activity(Label = "View for MainViewModel")]
public class MainView : MvxActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.MainView);
    }

    public override bool OnCreateOptionsMenu(IMenu menu)
    {
        MenuInflater.Inflate(Resource.Menu.OptionMenu, menu);
        return true;
    }
}



以上、超ベーシックでした! でも、なんか楽しいね。新しいことにチャレンジするってのは。