

1.
2.
3.
4.











•

•

•





Xamarin をマスターするだけ
で両方作れる!

C# によるビジネス ロジック
Mono.NET Framework
Android UI
AndroidiOSWindows
iOS UIWindows UI

http://japan.unity3d.com



https://www.embarcadero.com/jp/products/rad-studio







•








•
http://www.xlsoft.com/jp/products/xamarin/price.html
製品名 価格 (税抜)
Xamarin.Android Business (年間サブスクリプション) 127,800 (税抜)
Xamarin.Android Enterprise (年間サブスクリプション) 243,000 (税抜)
Xamarin.iOS Business (年間サブスクリプション) 127,800 (税抜)
Xamarin.iOS Enterprise (年間サブスクリプション) 243,000 (税抜)
Xamarin.Mac Business (年間サブスクリプション) 127,800 (税抜)
Xamarin.Mac Enterprise (年間サブスクリプション) 243,000 (税抜)

iOS
• Xcode
• Objective-
C (C++/C)
Android
• Eclipse
• Java
(C++/C)
Windows
• Visual
Studio
• C#/C++
iOS
• Xamarin Studio/
Visual Studio
• C#
Android
• Xamarin Studio/
Visual Studio
• C#
Windows
• Visual Studio
• C#


iOS
View
ViewModel
Model
Android
View
ViewModel
Model
Windows
View
ViewModel
Model
iOS
View
ViewModel
Model
Android
View
ViewModel
Model
Windows
View
ViewModel
Model
ViewModel
Model


// ボタンが押されたときに呼ばれる
async void OnButtonClick(object sender, EventArgs e)
{
await 何か時間の掛かる処理1();
await 何か時間の掛かる処理2();
処理3();
}
// アラートのボタンが押された時に呼ばれるデリゲート
-(void)alertView:(UIAlertView*)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:
//1番目のボタンが押されたときの処理
break;
case 1:
//2番目のボタンが押されたときの処理
break;
}
}
UIAlertView *alert = [[UIAlertView alloc] init];
alert.delegate = self;
alert.title = @"確認";
alert.message = @"よろしいですか?";
[alert addButtonWithTitle:@"いいえ"];
[alert addButtonWithTitle:@"はい"];
[alert show];
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button1:
// 1番目のボタンが押されたときの処理
break;
case R.id.button2:
// 2番目のボタンが押されたときの処理
break;
}
}
}
public class MyActivity extends Activity
implements OnClickListener {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View showButton = findViewById(R.id.button1);
showButton.setOnClickListener(this);
}






マシン OS iOS アプリ開発 Android アプリ開発
Xamarin Studio Visual Studio +
Xamarin プラグイン
Xamarin Studio Visual Studio +
Xamarin プラグイン
PC Windows
× ○
(要 Mac 上の
Xamarin.iOS
Build Host)
○ ○
Mac Mac OS
○ × ○ ×
Windows
○ ○
(要 Mac 上の
Xamarin.iOS
Build Host)
○ ○
 Visual Studio
 Xamarin Studio
 Xamarin Studio
 Visual Studio
Android アプリ開発iOS アプリ開発



•
•
•



iOS
View
ViewModel
Model
Android
View
ViewModel
Model
Windows
View
ViewModel
Model
iOS
View
ViewModel
Model
Android
View
ViewModel
Model
Windows
View
ViewModel
Model
ViewModel
Model





View ViewModel Model
データバインド
参照/更新
更新通知
プレゼンテーション プレゼンテーション ロジック ビジネス ロジック/データ



https://ja.wikipedia.org/wiki/Model_View_ViewModel

http://www.slideboom.com/presentations/257972


•




View
(iOS アプリ)
View
(Android アプリ)
View
(Windows アプリ)
ViewModel Model
MVVMCross
PCL
先ず、NuGet をアドインとして追加
先ず、NuGet をアドインとして追加
プロジェクトに NuGet から MvvmCross をインストール
プロジェクトに NuGet から MvvmCross をインストール
using Cirrious.MvvmCross.ViewModels;
namespace MvvmDemo.Core.ViewModels
{
public class FirstViewModel : MvxViewModel
{
int price = 0;
public int Price
{
get { return price; }
set {
price = value;
RaisePropertyChanged(() => Price );
RaisePropertyChanged(() => TaxInclusivePrice);
}
}
int tax = 8;
public int Tax
{
get { return tax; }
set {
tax = value;
RaisePropertyChanged(() => Tax );
RaisePropertyChanged(() => TaxInclusivePrice);
}
}
public int TaxInclusivePrice
{
get { return (int)(Price * (1.0 + Tax / 100.0)) ; }
}
}
}
if (rootFrame.Content == null) {
//rootFrame.Navigate(typeof(MainPage), e.Arguments);
var setUp = new Setup(rootFrame);
setUp.Initialize();
var start = Cirrious.CrossCore.Mvx.Resolve
<Cirrious.MvvmCross.ViewModels.IMvxAppStart>();
start.Start();
}
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<TextBlock Text="Price" FontSize="64"/>
<TextBox Text="{Binding Price, Mode=TwoWay}" FontSize="64"/>
<TextBlock Text="Tax (%)" FontSize="64"/>
<TextBox Text="{Binding Tax, Mode=TwoWay}" FontSize="64"/>
<TextBlock Text="Tax Inclusive Price" FontSize="64"/>
<TextBlock Text="{Binding TaxInclusivePrice}" FontSize="64" />
</StackPanel>
</Grid>
<key>CFBundleDisplayName</key>
<string>MvvmDemo.iOS</string>
<key>CFBundleIdentifier</key>
<string>com.your-company.MvvmDemo.iOS</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>


public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
_window = new UIWindow (UIScreen.MainScreen.Bounds);
var setup = new Setup(this, _window);
setup.Initialize();
var startup = Mvx.Resolve<IMvxAppStart>();
startup.Start();
_window.MakeKeyAndVisible ();
return true;
}
public override void ViewDidLoad()
{
View = new UIView(){ BackgroundColor = UIColor.White};
base.ViewDidLoad();
if (RespondsToSelector(new Selector("edgesForExtendedLayout")))
EdgesForExtendedLayout = UIRectEdge.None;
var priceLabel = new UILabel(new RectangleF(10, 10, 300, 40));
priceLabel.Text = "Price";
Add(priceLabel);
var priceTextField = new UITextField(new
RectangleF(10, 50, 300, 40));
Add(priceTextField);
var taxLabel = new UILabel(new RectangleF(10, 90, 300, 40));
taxLabel.Text = "Tax (%)";
Add(taxLabel);
var taxTextField = new UITextField(new RectangleF(10, 130, 300,
40));
Add(taxTextField);
var taxInclusivePriceLabel = new UILabel(new RectangleF(10, 170,
300, 40));
Add(taxInclusivePriceLabel);
var set = this.CreateBindingSet<FirstView,
Core.ViewModels.FirstViewModel>();
set.Bind(priceTextField ).To(vm => vm.Price );
set.Bind(taxTextField ).To(vm => vm.Tax );
set.Bind(taxInclusivePriceLabel).To(vm => vm.TaxInclusivePrice);
set.Apply();
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize=“30dp"
android:text="Price" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize=“30dp"
local:MvxBind="Text Price" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="40dp"
android:text="Tax" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:tex
tSize="40dp"
local:MvxBind="Text Tax" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="40dp"
android:text="Tax Inclusive Price" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="40dp"
local:MvxBind="Text TaxInclusivePrice" />
</LinearLayout>
namespace MvvmDemo.Core.Converters
{
public class PriceValueConverter : MvxValueConverter<int, string>
{
protected override string Convert(int value, Type targetType, object
parameter, CultureInfo culture)
{
return string.Format("{0:#,0} 円", value);
}
protected override int ConvertBack(string value, Type
targetType, object parameter, CultureInfo culture)
{
value = ToDigitText(value) ?? "0";
int result;
return int.TryParse(value, out result) ? result : 0;
}
string ToDigitText(string text)
{
var stringBuilder = new StringBuilder();
foreach (var character in text) {
if (char.IsDigit(character))
stringBuilder.Append(character);
}
return stringBuilder.ToString();
}
}
}
namespace MvvmDemo.WindowsStore.NativeConverters
{
public class NativePriceValueConverter : MvxNativeValueConverter<PriceValueConverter> {}
}
<Application
x:Class="MvvmDemo.WindowsStore.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MvvmDemo.WindowsStore"
xmlns:nativeConverters="using:MvvmDemo.WindowsStore.NativeConverters">
<Application.Resources>
<ResourceDictionary>
<nativeConverters:NativePriceValueConverter
x:Key="Price"></nativeConverters:NativePriceValueConverter>
</ResourceDictionary>
</Application.Resources>
</Application>
<TextBox FontSize="64“
Text="{Binding Price, Mode=TwoWay, Converter={StaticResource Price}}" />
var set = this.CreateBindingSet<FirstView, Core.ViewModels.FirstViewModel>();
set.Bind(priceTextField ).To(vm => vm.Price ).WithConversion("Price");
set.Bind(taxTextField ).To(vm => vm.Tax );
set.Bind(taxInclusivePriceLabel).To(vm => vm.TaxInclusivePrice).WithConversion("Price");
set.Apply();
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
local:MvxBind="Text Price,Converter=Price" />




1.
2.
3.
4.
Xamarin
XLsoft エクセルソフト
Xamarin (ザマリン) ホーム - C# と .NET で iOS, Android (アンドロ
イド), Mac (マック), Windows アプリを開発
Xamarin 価格
Hello, iPhone 初めての Xamarin.iOS アプリケーション開発 - 入門ガ
イド
Hello, Android 初めての Xamarin.Android アプリケーション開発 -
入門ガイド
 Xamarin for Visual Studio 概説
 Visual Studio で iOS/Android アプリが書ける Xamarin を試してみた(iOS 編)
 Visual Studio で iOS/Android アプリが書ける Xamarin を試してみた(Android 編)
 インサイド Xamarin
 Xamarinを構成するソフトウェア。その主要な10要素とは?
 Xamarinの基盤となっている「Mono」と、C#コンパイラ「mcs」
 Xamarinの基盤「Mono」のmonoランタイムとクラスライブラリ
 Mono のモバイル化の流れ ― Xamarin.iOS/Xamarin.Androidの誕生
 Xamarin.iOS の仕組みとアプリケーションの構成
 Xamarin.iOS で使用するライブラリ
N plus 1 Videos Of MvvmCross ·
MvvmCross/MvvmCross Wiki
Xamarin - マルチプラットフォーム MVVMフレーム
ワーク「MvvmCross」を使う - Qiita
Xamarin+MvvmCrossでアプリ開発をはじめる準備
2014年3月版 - Qiita

Xamarin ~ iOS/Android/Windows アプリを C# で作ろう~