echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

Visual Studio 2017でXamarinを動かしてみた。

ていうか、前回の記事から50日…
いくら仕事で体調が優れないからって、ちゃんと定期的に何か書かないと…

だれか、終業後も元気でいられる方法、教えてください…

Visual Studio2017正式リリース
先日、マイクロソフト本社で開催された、Infragistics Day 2017 Springに参加して、改めて「Xamarinは、いいぞ」って再認識したのですが、同時期にVisual Studio 2017が公開されました。

そして昨日、エクセルソフトの田淵さんが、こんな記事を公開されました。
ytabuchi.hatenablog.com

そこで、この記事を参考に、Visual Studio 2017でXamarinを動かしてみました。


ダウンロードとインストール
まずは公式サイトからインストーラーをインストールします。(今回は無料のCommunity版を選びましたが、もう少しビジネスが軌道に乗ったら、Pro版買いたいなあ。)

で、インストーラーを起動すると、下記画面になります。
f:id:Makky12:20170318212441p:plain

この中の「.netによるモバイル開発」にチェックを入れ、右の「概要」では下記項目にチェックを入れました。(個々の詳細については、先程の田淵さんの記事に詳しく説明がありますので、そちらを参考にされるとよいと思います。)

  • Xamarin Workbooks
  • Android SDK セットアップ (レベル23)
  • Java SE Development Kit (8.0.xxx.xx)
  • F# 言語サポート
  • Xamarin用ユニバーサルWindowsプラットフォーム

※F# 言語サポートは、必要ないなら不要かも。(僕は一応入れました)
※「Xamarinインストール&実行が重い!」と言われる根源である「Google Android エミュレーター」ですが、Android実機があり、Visual Studioで実機デバッグできる環境がある(作る)なら不要です。(実機デバッグ環境についてはこちらの「2.実機デバッグ環境構築」を参照)
またこれを入れないなら「Intel Hardware Accelerated Execution Manager (HAXM)」も必須ではないです。


実際に動かしてみる
インストールが完了したら、早速Visual Studio 2017を起動。(結構スタートページのデザインは変わっています。)
「新しいプロジェクト」から、[Visual C#]-[Cross-Platform>-[クロスプラットフォームアプリ (Xamarin.Forms またはネイティブ)]を選択します。

で、とりあえず何もせずにビルド&デバッグ
f:id:Makky12:20170318212502j:plain

動いた!

あれ?でも以前と違って、ContentPageをNavigationPageに(引数で)渡してないぞ?
というか、MainPageクラスのコンストラクタに、引数自体がない…

…という理由で焦ったので、少しソースコードを追ってみた所、違いが判明。
(上が前のソース、下が今回のソース)
f:id:Makky12:20170318212520p:plainf:id:Makky12:20170318212528p:plain

なるほど、今はContentPageを直書きではなく、MainPageクラス側でXAMLなどでガッツリContentPageを作り込んで、それをMainPageに渡すのか。
確かに、XAMLで作り込める分、この方が良いかも。
Infragisticsさんから4月に便利なツールも発売されるみたいですし。

※もちろん以前のように、ContentPageの直書きでもOKです。下の画像でコメントアウトしたソースのように、MainPage変数にContentPageのインスタンスを渡してあげるだけです。(↓その結果)
f:id:Makky12:20170318212512j:plain


Visual Studio 2015のプロジェクトを動かす
最後に、Visual Studio 2015のXamarinプロジェクトを直接開くと、こんなメッセージが表示されました。
f:id:Makky12:20170318212537p:plain

気にせずそのまま[OK]をクリックしたら、こんなレポートが表示されました。
f:id:Makky12:20170318212549p:plain

どうやら、Windows Phoneプロジェクトの移行に失敗したようですね。でも肝心のAndroidiOSプロジェクトは成功したようなので、問題ないでしょう。

このプロジェクトをビルド&デバッグすると、何も問題なく実機で動作しました。
(結果はさっきの画像と同じなので省略。)

あ、ちなみに実機デバッグ環境ですが、Visual Studio 2015で設定済ならば、特に何もしなくても、Visual Studio 2017で何の問題も無く動作しました。
(実機デバッグ環境についてはこちらの「2.実機デバッグ環境構築」を参照。←2度め)


それではみなさん、素敵なXamarinライフを!

最後に一言。


「Xamarinは、いいぞ。」

【2017/3/19追記】
このあとIoT(ラズパイ3)のプロジェクトをVisual Studio 2017で動かしたのですが、これについては変換のメッセージすら表示されることなく、Visual Studio 2015で作成したプロジェクトが全く問題なく動きました。
(「ユニバーサルWindowsプラットフォーム開発」や「Windows Core開発」あたりにチェックを入れればいいのかな?ちなみに「概要」はデフォルトのまま変えてません。)

今までのVisual Studioは、大抵リリース直後は何かあったのでインストールを見送っていたのですが、今回は今のところいい感じです。

ちなみに、合計40GB強のインストールに、下記スペックのPCで2時間ほどかかりました。参考までに。(Xamarinだけなら、こんなに容量ありません。)

■インストール先のスペック

  • OS:Windows10 Pro(64bit)
  • CPU:Intel Core i7-7500U
  • メモリ:8GB
  • HDD:1TB(約850GB空き)

一区切りしたので、色々考えてみる。

前の記事が昨年12月4日投稿…ちょっと期間が空きすぎですね。
定期的に書かないと、読んで貰えないってのに。

…まあ、別にサボってて書かなかったわけではないんですが。(精一杯の言い訳)

プロジェクト終了
はい。現在参画中のプロジェクトですが、今月末で終了となりました。
といっても、お世辞にも"Misssion completed"って訳ではなく、まあ半分「打ち切り」みたいなもんですが。

で、エージェント経由で理由を聞いたんですが、まあ色々ありました。
でも「協調性がない」とか、個人的には「どこが?」って感じです。
(結構言われるけど。でも「作業中に独り言が多い」というのは、反省しなければなりませんが。)

でも、コミュニケーションが全然噛み合わなかったり、そもそもベースの考え方が違ったりしていたので、その点が他メンバにはマイナスに写ったのかもしれません。(僕もかなり悩んでいて、メンタルが弱っていましたし…)

悩みに悩んだ末、記憶喪失に
さっき「今月末で終了」って言ったよね。アレは嘘だ。
正確に言えば、もう終わってます。

メンタルがかなり弱っていた事や、新しく処方された薬が合わなかった(?)などの不運もあったんですが、仕事中、急に「気持ち悪い…ていうか、猛烈な嘔吐感が」って思ったんです。
で、急いでトイレにダッシュしたんですが、間に合わず…って所までは覚えているんです。

…でも、そっから先の記憶がない(というか、全く思い出せない)んです。
ていうかマジで、あの日の記憶だけが頭からポッカリ抜けているんです。それくらいヤバイ状況でした。
(後で医師に聞いた所、一時は「命の危険もあった」らしいです。まあ個人的には「その日病院に行っていた」ことすら記憶に無いんですが…)*1

で、医師から診断書が出てしまったので、そりゃ「継続不可能」って判断しますわな、クライアントも。

初プロジェクト終了の感想
正直な話ですが、やっぱり人間関係にしろ、プロジェクトの空気にしろ「合う・合わない」は絶対あるんだ、と感じました。
そして「どうやっても無理」なプロジェクトだったら、その時点でバイバイしてしまったほうがいいです。

身勝手な言い方ですが、それが「フリー」の特権ですから。
合わないプロジェクトで無理して頑張るより、自分に合うプロジェクトで心の底から頑張ったほうが、絶対プラスになります。

あと「もう無理」と思った時点で、できるだけ早く対応してくれるエージェントだと、こちらとしても安心です。

反省点とか
でもやっぱり、反省点もあるのは事実で。

事前の情報で「フリーエンジニアは自分から積極的に意見を提案しないといけない」とか「言われたことやってるだけだったら、フリーの存在価値がない」っていうことを多く見かけたので、結構頑張って、自分から積極的なところを見せたのですが…

無理にそこまでする必要はないですね。

正直、フリーだからと言って、変に気張らずに「まずは相手の要求に、誠実に、謙虚に、全力で応える」事のほうが大事だと感じました。
(もちろん、+αで先述のことが出来れば最高ですけど)
そして「自分の求める事が出来ないと」感じたならば、そのプロジェクトを降りればいいだけですし。

で、現在は
ちょっと時間もあるので、今後の事とか、次に現場に入った時の事とか、色々と考えています。
やっぱり「お金」とか「体調」とか、あとやっぱり「自分らしい働き方」をするためには、自分のオフィスで働くのが一番!…という事を考え、現在は異業種交流会とか、人脈&業務拡大に精を出している今日このごろです。

仕事の依頼とか、増えないかなあ。

*1:もっと言うと、そんな状況にも関わらず、自分で車を運転して帰ったらしいです。奇跡的に無事故だったから良かったものの、今考えると恐ろしい…

おいパイ食わねえか?

いや、食うわけでもおみまいする訳でもないですが。

前から使ってた業務用オンボロPCの後継機としてDELLの通販で買ったPCが、先週ようやく届きました。
そして、それを契機に買ったRaspberry Piの開発が(やっと)Visual Studioで出来るようになったので、セットアップについて備忘録を書いておこうと思います。

作業1.Windows 10 IoT Core Dashboardの入手
1.「Windows Insider Program」のサイトで、アカウント登録します。(MSアカウントが必要)
https://insider.windows.com/

2.次の画面の「IoT Coreの入手」ボタンをクリック。

3.Windows Developer Centerの「Windows IoT」ページに移動するので「すぐに作業を開始」ボタンをクリック。

4.「Get Started」画面で、自分の環境に合わせて、以下を選択して、「Next」ボタンをクリック。
 ・Select your hardware:インストールするデバイス(Raspberry Pi3等)
 ・Select your installation media:Raspberry Piなら「microSD card」の方
 ・Select your OS version:「Windows10 IoT Core」(Insider Previewじゃない方)
  
5.「Step 1 of 4: Get the tools」ページの「Download Dashborad」ボタンをクリックして、Windows 10 IoT Core Dashboardをダウンロード&インストールする。


作業2.Windows 10 IoTのインストール
1.先程インストールした「Windows 10 IoT Core Dashboard」(以下、「ダッシュボード」)で「Set up a new device」をクリック。

2.右側のフレームで、以下を設定する
 ・デバイスの種類:「Raspberry Pi2 & 3」
 ・OSビルド:「Windows IoT Core」
 ・ドライブ:Raspberry Pi3用のmicroSDを挿しているドライブ名
 ・デバイス名:デフォルトで「minwinpc」となっていますが、変えるならデバイス名を入力。(そのままで良い場合は変更不要。)
 ・パスワード:(自分で決めた)Raspberry Pi3ログイン用のパスワードを入力。

3.micro SDにWindows IoT Core書き込みが始まるので、完了まで待機。(microSDの内容は全て消去されるので、ご注意を。)

4.書き込みが完了したら、microSDをRaspberry Pi3に差し込み、HDMIケーブルをディスプレイに接続し、ACアダプタをコンセントに挿す(Raspberry Piの出力はHDMIだけなので、HDMI対応ディスプレイがない場合、DVI変換ケーブルなどが必要になります。)

5.Raspberry Piの起動が完了し、ディスプレイに画面が表示されるまで、暫く待つ。(ちょっと時間がかかります。)

6.Raspberry Piの「設定」画面から、以下の3つを設定します。(最低限、これを設定すればOKのはずです。)
 ・「使用言語」&「キーボード言語」:どちらも「日本語」
 ・ネットワークとWifi:自分の環境に合わせて設定して下さい。
 ・Bluetooth:僕の環境では「ON」だと無線LANが上手く繋がらない現象があったので「OFF」にしました。(無線LANが上手くつながらない場合「OFF」にしたほうが良いかもしれません。)

Visual Studioデバッグ
1.Visual Studioを開き「新しいプロジェクト」から[Visual C#]-[Windows]-ユニバーサル-[空白のアプリ(Visual C#)]を選択。

2.ソリューションが開いたら、ツールメニューの「ターゲットCPU」(「ANY CPU」等が選択されている箇所)を「ARM」にする

3.ターゲットデバイス(「ローカルコンピュータ」などが選択されている場所)を「リモートPC」にして「手動で構成」欄で、以下を設定。
 ・アドレス:ディスプレイに表示されているRaspberry Piの「IPアドレス
 ・認証モード:ユニバーサル認証

デバッグ実行すれば、問題なければディスプレイに実行画面が表示されるはずです。(ソースは1行もいじらなくてOKです。)

※なお、上手くデバッグ出来ない場合、以下の事をチェックしてみて下さい。
 ・Raspberry Piのインターネット接続(無線の場合、これが結構切れます。)
 ・「認証モード」が「ユニバーサル認証」になっていない(Raspberry Pi3では「なし」ではダメみたいです)
 ・「参照の設定」の[ユニバーサルアプリ]-[拡張]-[Windows IoT Core]でチェックされているものが最新バージョンではない。(そもそもチェックされていないなら不要)

おまけ.Device Portalに接続
Raspberry Piの詳細設定は、ダッシュボード画面の「自分のデバイス」を右クリック-[Device Portalを開く]で起動できる「Device Portal」画面で行なえます。
(ちなみにログイン認証ですが、初期IDは「administrator」、初期パスワードは「作業2の手順1で設定したパスワード」です。)

「ここで何か作業をしないとデバッグできない」わけではないですが、とりあえず「タイムゾーン」は「Tokyo,Osaka,Sapporo」に変えておいたほうが良いかもしれません。

と、急ぎ足なうえ、画像もなくて申し訳ないですが、とりあえず実機デバッグが出来る環境を構築できました。
Xamarin.Formsも環境を再度構築したので、その話はまた後日書こうと思います。

本当の「フリー」について考える

何か、気づいたら前回の記事から1ヶ月近く経ってたんですね。
てっきり2週間位かと思ってました…反省です。

さて、気がつけば昨日、2回目の請求も完了していました。
しかし支払サイトは45日…早く入金されないと、マジで金が底をつく…(切実)

で、そんな訳でフリーになって約2ヶ月が経過したわけですが、この間に切実に感じたことがあります。
それは「早く自分のスペースで仕事が出来る環境を見つけないとマズイ…」という事です。

これまで2ヶ月契約先で働いた訳ですが、正直「何か結局、サラリーマンと変わらないなあ」という感じです。結局、週5日通勤して…という生活ですし。

まあそれだけならまだ良いんですが、僕は性格上、仕事に関しては非常に厳しいというか、ハッキリと物を言う性格なんですが、まあそれのせいで意見が衝突する…というか、相手によっては一触即発、なんてことも場合によってはあるわけです。(というか、今回も実際にあった)

個人的には「仕事での事なら、多少衝突しても意見を言い合ったほうが良い」という性格なので、臆する事はないのですが、それでも正直、あまり気分がいいもんではないです。
そうなると、仕事のモチベーションというか、どれだけ「なるべくなら楽しく仕事をしよう」と頑張っても、やっぱり仕事が嫌になっています。

でも、かといって「自分が我慢さえすれば」なんて考えは全く持ってないので、そういう場合でもハッキリと言ってしまうわけです。(まあ自分が我慢して自分だけストレスが溜まるのなんて勘弁ですし、そもそも自分の意見も言えないような人物なら、お客からしたら高い金を払って来てもらう価値も無いわけだし。)

となると「協調性が無い…というか、やっぱ個人(というか一人)で働くほうが性に合ってるんだ」と実感するわけです。
だって個人なら全てにおいて自分の好きなように(自分が責任を持って)やれますし、そもそもそういう働き方に憧れてフリーになったんだし。
だから早いところ、本当の「フリー」な状態で仕事をしなければ!と、最近強く思うのです。

ただ、そういう状態を確立しようとなると、まだまだ色々調べたり、勉強しなければならないです。
リモート案件も無いことはないけど、まだまだ数は少ないですから。(というか、僕が住んでいる地方では絶望的)

本当は営業とかして、クライアントを増やさないといけないんですが、そういうノウハウもなければ、人脈もまだまだ不足している。
そういう事も考えて、12月…そして来年以降、積極的に活動して、早めにそういう働き方を確立しなければいけないです。

それにリモートワークなら、地域に限定されることもないですし、週1回出向くくらいなら全く問題ないですから、仕事の幅も広がりますし。
(まあ、個人的には長野とか北海道みたいな、個人的に好きな場所なら、むしろ喜んで、って感じですし。単に「温泉が好き」なだけかもしれませんが…)

それに、そういう人脈などを通してビジネススキルを磨かないといけないですし、いろんなノウハウも学ばないといけない。
それに12月になればお金も入金されますし、新しいPCが届きますから、トレンドの技術や興味のある技術をもっと勉強して、同じ趣向の技術者の方とも交流を持ちたい、なんて思ってます。

そのためにも…というか来年、再来年につらい思いをしないためにも、今もっと頑張らなくては。

※ちなみに、個人的にはXamarin.FormsやIoTに大変興味を持っており、ネットで情報収集しまくってます。
…ていうか、何だかんだで結局C#大好きだなあ、自分。

フリーになって1ヶ月経った感想

手塚規雄さんが、Twitterでこんなつぶやきをしていた。

面白そうだったので、僕もやってみました。
https://shindanmaker.com/568560

その結果がこちら。
これを見てくれ。こいつをどう思う?

おそらく、以前(というか、闘病中で文字通り「一寸先が闇」だった頃)だったら、何が何でも飛びついたと思います。
ただ、病気から回復して、こうしてフリーとして生きている今の自分なら、間違いなく断ります。

なぜかって?

だって、基本給46万ってことは、大雑把に考えて、手取り40万弱ですよ?
って事は残業代含め、まあ良くて45~50万ってとこですよね?
しかも月50時間の残業は確定です。(まあ「男性が多い」ってのは、「一生この業界で食べていく」と決心した時点で諦めてます。)

そんなの、どう考えても割に合わないですもん。
フリーなら残業ゼロでも、基本給+10~15万くらいは堅いですし。(東京ならもっと多いと思います)

そりゃ退職金とか老後の生活とか福利厚生とかありますが、よく考えたら

  • 退職金:今はない企業も多い。というか退職まで生きている保証なんて無いから、それなら生きてるうちに多く貰って、自分で蓄えたい。
  • 老後の生活:これも退職金と同じで、死んだらもそうだけど、そもそも会社に何かあったら終わりだし。
  • 福利厚生:よく考えたら、福利厚生って、言うほど世話になったことがないや。

まあ簡単に言えば「自分の事は全部自分で責任持つから、その分時間やお金や自由がたくさんある働き方をすべきだ」ってのが、僕がフリーになった理由でもあるわけです。

実際、フリーになって1ヶ月経ちましたが、別にそういった面での大変さはそれほど感じていません。(むしろ「何から何まで、全部自分の責任でやっているんだ」という満足感のほうが大きいです。)

(僕みたいな)そういう「自分の事は、全部自分が責任を持たないと」というような考えの人には、フリーという働き方はお勧めだと思います。

逆に「そんなの面倒くさい」とか「そんなの誰かがやってくれるよ」って人は、フリーになるのはやめたほうが良いです。多分身が持ちません。
(あと「業務時間外では自分の業務関連の事に1ミリも関わらない」という人も、フリーには不向きだと思います。やっぱりどんな形でも、スキルアップは必要です。僕もフリーになってから、何かしら勉強する時間が大幅に増えました。)

まあ、僕のように人生波乱万丈で「フリーしか生きていく道がなかった」場合は別としても、そういう「自分の事は、全部自分が責任を持たないと」みたいな人は、一度フリーを検討するのも、決して悪くないと思いますよ。
(逆に言えば、そんな僕でもやっていけるのですから、決して選択肢としては悪くないと思います。)

…少なくとも、会社(特にブラック企業)に飼い殺しにされて、最悪な事態になる前に。

ASP.netの「依存関係エラー」でエラーになる時

昨日、フリー生活初の「請求処理」を行いました。
やはり「請求処理」みたいな事を自分で行うと「俺、本当にフリーでやっているんだなあ」って実感します。
今月は1ヶ月フルで働いてないので(途中からスタートしたから)満額もらえるわけではないですが、それでも報酬が振り込まれたら、嬉しいんでしょうね。

…しかし、支払サイトって、何であんなに長いんでしょう?もっと短くして
(金欠なので…)
あと、どんなに切羽詰まった状況でも、契約内容は妥協してはダメですよ。
(内税/外税の違いだけでも、割と大きな差ですから…)

就業先は変わりたくないけど、エージェントだけ、もっと良い所に変われないかなあ…


とまあ、そんなことは置いといて…

さて、今の就業先ではチームで作業をしておりまして、当然Visual Studioのプロジェクトもチームで共有しております。
で、何かMS側のトラブルか何かで、長いことチーム開発の参加申請ができなかったのですが、ようやく申請が可能になり、承認もおりました。
で、早速プロジェクトをチェックアウトして、デバッグを走らせたら…

f:id:Makky12:20161027215301j:plain

なんですと?

当然、他の人のところでは問題なく動いてるから、ソースに大きな不具合が…とは考えにくい。
それに、事前に指定された環境構築作業はすべてやっているから、そこら辺は問題ないはず。

てことは、単純に僕のPC環境とか、それとも就業先での「暗黙の了解」みたいなことをまだやってないとか、そういうこと?

…とか思ってましたが、なんてことは無い、ググったら普通にありました。
https://www.ipentec.com/document/document.aspx?page=visual-studio-2015-asp-net-runtime-error-in-64bit

要は「IIS Expressがデフォルトで32bitだから、64bitバイナリは動かせません」ということですね。
…こういう所って、Visual Studio側で事前に判断してくれると嬉しかったり。

というか、以前もこういうエラーに直面して、そのときも確か32bitと64bitの違いが原因だった事を思いました。(そういう事こそ、しっかり覚えておけよ、と。)

…ていうか「てっきり就業先では必要なことをやってないだけ」と判断して、他の方の時間も使ってしまいました。反省です。
そういう事は、自分でちゃんとやるべき事をやってから聞かないといけませんね。

という訳で、今後は十分気をつけなくては、と思いました。

Xamarinの導入 その2(コーディング)

前回、エラー出まくりながらもXamarinの環境構築が何とか完了しました。
PCLはまだまだ問題ありですが、Android単体なら何とかなりそうなので、下記のサイトを参照して、Android用の簡単なサンプルを作成してみました。
sys-guard.com

まずはVSを起動して、プロジェクトから[Visual C#]]-[Android]-[Blank App(Android)]を選択。
現在Android(というかJava)を絶賛勉強中ということもあり、とりあえずソースはAndroid Studioで作成したものをそのままコピペして、いきなりビルド。

こいつ…動かないぞ!(当たり前)

まあ、そのままでは動きませんので、修正を。
とはいえ、まだまだソースの細かい部分を一から説明すると大変なので、現時点ではとりあえず感じたことを。

  • 基本的なクラスとかコントロールは、デフォルトでインポートされてるもので大丈夫っぽい。(今回個別に追加したのは「Android.Graphics」のみです。またヒントに結構「この名前空間のこのクラスを使え」って直に表示されます。)
  • プロパティ・メソッド名は同じものが多く、せいぜい大文字・小文字の違いのみ。(マウスオーバーで提示される修正で、大半のエラーは直りました。)
  • イベントリスナーとか、ダイアログとかの固定処理(onCreateDialog()など)が、ちょっとだけ違う(まあ、ここは慣れ…なのかな?)

※先程のSYSTEM GUARDIANさんのページとか、https://developer.xamarin.com/api/root/MonoAndroid-lib/さんなんかが参考になると思います。

もちろんJavaとXamarinの違いに苦戦はしましたが、何とかビルドも通り、実行。
f:id:Makky12:20161022224054j:plain
こんな感じでボタンが表示されて、クリックすると…(しかし「ここをクリック」って、1クリック詐欺かよ…)

f:id:Makky12:20161022224102j:plain
ちゃんとメッセージボックスが表示されました。

というわけで、とりあえずAndroid単体なら、何とかなりそうですね。(iOSも試せれば良いんですが…Mac購入の日は遠い)

今後は、もっと突っ込んだ所に手を出せるといいなあ。
まあ、まずはAndroid(というかJava)の勉強が先ですね。

※おまけ
・先述のSYSTEM GUARDIANさんのページにもありますが、ちゃんとGUIデザインも出来るみたいです。(Android SDKが古かったらしく、実行できなかった。)

・「フレームがモジュールにありません」と表示され、ステップ実行が出来ませんでした。実機デバッグだとこうなるんでしょうか。
あ、PCがヘボいから?(もう6年前のPCですから…報酬入ったら、DELL通販あたりで買うかな…)


あと、最後にソースコードを。

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

using Android.Graphics;

namespace AndroidApp
{
    [Activity(Label = "AndroidApp", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity, View.IOnClickListener
    {
        private readonly int WC = LinearLayout.LayoutParams.WrapContent;
        private readonly String TAG_MESSAGE = "0";
        private readonly String TAG_YESNO = "1";
        private readonly String TAG_TEXT = "2";
        private readonly String TAG_IMAGE = "3";

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            RequestWindowFeature(WindowFeatures.NoTitle);

            LinearLayout layout = new LinearLayout(this);
            layout.SetBackgroundColor(Color.White);
            layout.Orientation = Orientation.Vertical;
            SetContentView(layout);

            layout.AddView(makeButton("ここをクリック!", TAG_MESSAGE));
        }

        private Button makeButton(String text, String tag)
        {
            Button button = new Button(this);
            button.SetText(text, TextView.BufferType.Normal);
            button.Tag = tag;
            button.SetOnClickListener(this);
            button.LayoutParameters = new LinearLayout.LayoutParams(WC, WC);

            return button;
        }

        void View.IOnClickListener.OnClick(View view)
        {
            String tag = (String)view.Tag;

            if (this.TAG_MESSAGE.Equals(tag))
            {
                MessageDialog.show(this, "メッセージボックス", "Hello World!");
            }
            else
            {
                return;
            }
        }

        public class MessageDialog : DialogFragment, IDialogInterfaceOnClickListener
        {
            public override Dialog OnCreateDialog(Bundle bundle)
            {
                var ad = new AlertDialog.Builder(this.Activity);
                ad.SetTitle(this.Arguments.GetString("title"));
                ad.SetMessage(this.Arguments.GetString("text"));
                ad.SetPositiveButton("OK", this);

                return ad.Create();
            }

            public static void show(Activity activity, String title, String text)
            {
                MessageDialog f = new MessageDialog();
                Bundle args = new Bundle();
                args.PutString("title", title);
                args.PutString("text", text);
                f.Arguments = args;

                f.Show(activity.FragmentManager, "messageDialog");
            }

            void IDialogInterfaceOnClickListener.OnClick(IDialogInterface dialog, int which)
            {
                // throw new NotImplementedException();
            }
        }
    }
}