Xamarin.Forms クイック スタート Deep Dive
Xamarin.Forms クイック スタートでは、Notes アプリケーションをビルドしました。 この記事では、Xamarin.Forms シェル アプリケーションのしくみの基礎を理解するために構築された内容を確認します。
Visual Studio の概要
Visual Studio は、コードをソリューションとプロジェクトに分けて整理しています。 ソリューションとは、1 つまたは複数のプロジェクトを保持できるコンテナーです。 プロジェクトは、アプリケーション、サポートするライブラリ、テスト アプリケーションなどの場合があります。 Notes アプリケーションは、次のスクリーンショットに示されているように、3 つのプロジェクトを含む 1 つのソリューションで構成されています。
プロジェクトの内容:
- Notes - このプロジェクトは、すべての共有コードと共有 UI を保持する .NET Standard ライブラリ プロジェクトです。
- Notes.Android: このプロジェクトは、Android 固有のコードを保持しており、Android アプリケーションのエントリ ポイントです。
- Notes.iOS: このプロジェクトは、iOS 固有のコードを保持しており、iOS アプリケーションのエントリ ポイントです。
Xamarin.Forms アプリケーションの構造
次のスクリーンショットは、Visual Studio の Notes .NET Standard プロジェクトの内容です。
このプロジェクトには、NuGet ノードと SDK ノードを含む Dependencies ノードがあります。
- NuGet – Xamarin.Forms、Xamarin.Essentials、プロジェクトに追加されている Newtonsoft.Json、sqlite-net-pcl の各 NuGet パッケージ。
- SDK – .NET Standard を定義する NuGet パッケージの完全なセットを参照する
NETStandard.Library
メタパッケージ。
Visual Studio for Mac の概要
Visual Studio for Mac は、コードをソリューションとプロジェクトに分けて整理するという Visual Studio の方法に従っています。 ソリューションとは、1 つまたは複数のプロジェクトを保持できるコンテナーです。 プロジェクトは、アプリケーション、サポートするライブラリ、テスト アプリケーションなどの場合があります。 Notes アプリケーションは、次のスクリーンショットに示されているように、3 つのプロジェクトを含む 1 つのソリューションで構成されています。
プロジェクトの内容:
- Notes - このプロジェクトは、すべての共有コードと共有 UI を保持する .NET Standard ライブラリ プロジェクトです。
- Notes.Android: このプロジェクトは、Android 固有のコードを保持した、Android アプリケーションのエントリ ポイントです。
- Notes.iOS: このプロジェクトは、iOS 固有のコードを保持しており、iOS アプリケーションのエントリ ポイントです。
Xamarin.Forms アプリケーションの構造
次のスクリーンショットは、Visual Studio for Mac の Notes .NET Standard プロジェクトの内容を示しています。
このプロジェクトには、NuGet ノードと SDK ノードを含む Dependencies ノードがあります。
- NuGet – Xamarin.Forms、Xamarin.Essentials、プロジェクトに追加されている Newtonsoft.Json、sqlite-net-pcl の各 NuGet パッケージ。
- SDK – .NET Standard を定義する NuGet パッケージの完全なセットを参照する
NETStandard.Library
メタパッケージ。
このプロジェクトには、複数のファイルも含まれています。
- Data\NoteDatabase.cs – このクラスには、データベースを作成し、それに対してデータの読み込み、データの書き込み、データの削除を行うためのコードが含まれます。
- Models\Note.cs – このクラスにより、
Note
モデルが定義されます。このインスタンスにアプリケーション内の各メモに関するデータが格納されます。 - Views\AboutPage.xaml –
AboutPage
クラスの XAML マークアップ。About ページの UI が定義されています。 - Views\AboutPage.xaml.cs –
AboutPage
クラスのコードビハインド。ユーザーがページを操作するときに実行されるビジネス ロジックが含まれています。 - Views\NotesPage.xaml –
NotesPage
クラスの XAML マークアップ。アプリケーションの起動時に表示されるページの UI が定義されています。 - Views\NotesPage.xaml.cs –
NotesPage
クラスのコードビハインド。ユーザーがページを操作したときに実行されるビジネス ロジックが含まれています。 - Views\NoteEntryPage.xaml –
NoteEntryPage
クラスの XAML マークアップ。ユーザーがメモを入力するときに表示されるページの UI が定義されています。 - Views\NoteEntryPage.xaml.cs –
NoteEntryPage
クラスのコードビハインド。ユーザーがページを操作するときに実行されるビジネス ロジックが含まれています。 - App.xaml:
App
クラスの XAML マークアップ。アプリケーションのリソース ディクショナリを定義します。 - App.xaml.cs –
App
クラスのコードビハインド。シェル アプリケーションのインスタンス化と、アプリケーションのライフサイクル イベントの処理が行われます。 - AppShell.xaml –
AppShell
クラスの XAML マークアップ。アプリケーションのビジュアル階層が定義されています。 - AppShell.xaml.cs –
AppShell
クラスのコードビハインド。プログラムによって移動できるように、NoteEntryPage
のルートが作成されます。 - AssemblyInfo.cs – このファイルには、アセンブリ レベルで適用されるプロジェクトに関するアプリケーション属性が含まれています。
Xamarin.iOS アプリケーションの構造については、「Anatomy of a Xamarin.iOS Application」(Xamarin.iOS アプリケーションの構造) を参照してください。 Xamarin.Android アプリケーションの構造については、「Anatomy of a Xamarin.Android Application」(Xamarin.Android アプリケーションの構造) を参照してください。
アーキテクチャとアプリケーションの基礎
Xamarin.Forms アプリケーションは、従来のクロスプラットフォーム アプリケーションと同じ方法で設計されています。 通常、共有コードは .NET Standard ライブラリに配置され、プラットフォーム固有のアプリケーションは共有コードを使用します。 次の図は、Notes アプリケーションのこの関係の概要を示しています。
スタートアップ コードを最大限に再利用するため、Xamarin.Forms アプリケーションには App
という名前の 1 つのクラスがあり、各プラットフォームでのアプリケーションのインスタンス化が行われます。次にコード例を示します。
using Xamarin.Forms;
namespace Notes
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
// ...
}
}
このコードにより、App
クラスの MainPage
プロパティが AppShell
オブジェクトに設定されます。 AppShell
クラスにより、アプリケーションのビジュアル階層が定義されます。 シェルによってこのビジュアル階層が取得されて、そのユーザー インターフェイスが生成されます。 アプリケーションのビジュアル階層を定義する方法の詳細については、「アプリケーションのビジュアル階層」を参照してください。
さらに、AssemblyInfo.cs ファイルには、アセンブリ レベルで適用される単一のアプリケーション属性が含まれています。
using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
XamlCompilation
属性により XAML コンパイラが有効になるため、XAML は中間言語に直接コンパイルされます。 詳細については、「XAML Compilation」(XAML のコンパイル) を参照してください。
各プラットフォームでアプリケーションを起動する
各プラットフォームでのアプリケーションの起動方法は、プラットフォームによって異なります。
iOS
iOS で最初の Xamarin.Forms ページを起動するため、Notes.iOS プロジェクトでは FormsApplicationDelegate
クラスを継承する AppDelegate
クラスが定義されます。
namespace Notes.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
}
FinishedLaunching
オーバーライドは、Init
メソッドを呼び出すことで Xamarin.Forms フレームワークを初期化します。 その結果、Xamarin.Forms の iOS 固有の実装がアプリケーションに読み込まれ、次に LoadApplication
メソッドの呼び出しによってルート ビュー コントローラーが設定されます。
Android
Android で最初の Xamarin.Forms ページを起動するために、Notes.Android プロジェクトには、MainLauncher
属性が指定され、FormsAppCompatActivity
クラスから継承したアクティビティがある Activity
を作成するコードが含まれています。
namespace Notes.Droid
{
[Activity(Label = "Notes",
Icon = "@mipmap/icon",
Theme = "@style/MainTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
}
}
OnCreate
オーバーライドは、Init
メソッドを呼び出すことで Xamarin.Forms フレームワークを初期化します。 それにより、Xamarin.Forms の Android 固有の実装がアプリケーションに読み込まれ、次に Xamarin.Forms アプリケーションが読み込まれます。
アプリケーションのビジュアル階層
Xamarin.Forms シェル アプリケーションでは、Shell
クラスをサブクラス化するクラスで、アプリケーションのビジュアル階層が定義されています。 Notes アプリケーションの場合、これは Appshell
クラスです。
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Notes.Views"
x:Class="Notes.AppShell">
<TabBar>
<ShellContent Title="Notes"
Icon="icon_feed.png"
ContentTemplate="{DataTemplate views:NotesPage}" />
<ShellContent Title="About"
Icon="icon_about.png"
ContentTemplate="{DataTemplate views:AboutPage}" />
</TabBar>
</Shell>
この XAML は、次の 2 つの主要なオブジェクトで構成されます。
TabBar
=TabBar
は下部のタブ バーを表し、アプリケーションのナビゲーション パターンで下部のタブを使用する場合は、これを使用する必要があります。TabBar
オブジェクトは、Shell
オブジェクトの子です。ShellContent
は、TabBar
の各タブのContentPage
オブジェクトを表します。 各ShellContent
オブジェクトは、TabBar
オブジェクトの子です。
これらのオブジェクトは、ユーザー インターフェイスではなく、アプリケーションのビジュアル階層の編成を表しています。 シェルでは、これらのオブジェクトを取得して、コンテンツのナビゲーション ユーザー インターフェイスを生成します。 したがって、AppShell
クラスにより、下部のタブから移動できる 2 つのページが定義されています。 ページは、ナビゲーションに応じて、オンデマンドで作成されます。
シェル アプリケーションの詳細については、「Xamarin.Forms シェル」を参照してください。
ユーザー インターフェイス
Xamarin.Forms アプリケーションのユーザー インターフェイスを作成するには、複数のコントロール グループが使用されます。
- ページ: Xamarin.Forms のページは、クロスプラットフォーム モバイル アプリケーション画面を表しています。 Notes アプリケーションでは、1 つの画面を表示するために
ContentPage
クラスが使用されます。 ページの詳細については、「Xamarin.Forms のページ」を参照してください。 - ビュー: Xamarin.Forms のビューは、ユーザー インターフェイスに表示されるコントロールで、ラベル、ボタン、テキスト入力ボックスなどです。 完成した Notes アプリケーションでは、
CollectionView
、Editor
、Button
のビューが使用されます。 ビューの詳細については、「Xamarin.Forms のビュー」を参照してください。 - レイアウト: Xamarin.Forms のレイアウトは、ビューを論理構造にまとめるために使用されるコンテナーです。 Notes アプリケーションでは、ビューを垂直方向に並べて配置するために
StackLayout
クラスが使用され、ボタンを水平方向に配置するためにGrid
クラスが使用されます。 レイアウトの詳細については、「Xamarin.Forms のレイアウト」を参照してください。
実行時に、各コントロールはネイティブの同等のものにマップされます。そしてそれがレンダリングされます。
レイアウト
Notes アプリケーションでは、StackLayout
を使用して、画面サイズにかかわらず、画面上のビューを自動的に配置することで、クロスプラットフォーム アプリケーションの開発が簡素化されます。 各子要素は、追加した順に、水平または垂直方向に 1 つずつ配置されます。 StackLayout
が使用する領域の量は、HorizontalOptions
プロパティと VerticalOptions
プロパティの設定によって異なりますが、StackLayout
は既定で全画面を使用しようとします。
次の XAML コードは、StackLayout
を使用して NoteEntryPage
をレイアウトする例を示しています。
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Notes.Views.NoteEntryPage"
Title="Note Entry">
...
<StackLayout Margin="{StaticResource PageMargin}">
<Editor Placeholder="Enter your note"
Text="{Binding Text}"
HeightRequest="100" />
<Grid>
...
</Grid>
</StackLayout>
</ContentPage>
既定では、StackLayout
は垂直方向を前提としています。 ただし、StackLayout.Orientation
プロパティを StackOrientation.Horizontal
列挙メンバーに設定することによって、水平方向に変更することができます。
Note
ビューのサイズは、HeightRequest
と WidthRequest
のプロパティを使用して設定できます。
StackLayout
クラスの詳細については、「Xamarin.Forms StackLayout」を参照してください。
ユーザー操作に対する応答
XAML に定義されているオブジェクトによって、分離コード ファイルで処理されるイベントが発生する可能性があります。 次のコード例は、[保存] ボタンによって発生する Clicked
イベントに応答して実行される、NoteEntryPage
クラスのコードビハインドの OnSaveButtonClicked
メソッドを示しています。
async void OnSaveButtonClicked(object sender, EventArgs e)
{
var note = (Note)BindingContext;
note.Date = DateTime.UtcNow;
if (!string.IsNullOrWhiteSpace(note.Text))
{
await App.Database.SaveNoteAsync(note);
}
await Shell.Current.GoToAsync("..");
}
OnSaveButtonClicked
メソッドは、データベースにメモを保存し、前のページに戻ります。 ナビゲーションの詳細については、「ナビゲーション」を参照してください。
Note
XAML クラスの分離コード ファイルは、x:Name
属性を指定して割り当てられた名前を使用して、XAML に定義されているオブジェクトにアクセスできます。 この属性に割り当てられている値は、C# 変数と同じルールを持っています。つまり、英字またはアンダースコアから始まり、埋め込みスペースが含まれる必要があります。
保存ボタンから OnSaveButtonClicked
メソッドに接続する処理は、NoteEntryPage
クラスの XAML マークアップで発生します。
<Button Text="Save"
Clicked="OnSaveButtonClicked" />
表示内容
CollectionView
により、項目のコレクションがリストに表示されます。 既定では、リスト項目は垂直方向に表示され、各項目が 1 つの行に表示されます。
次のコード例は、NotesPage
からの CollectionView
を示しています。
<CollectionView x:Name="collectionView"
Margin="{StaticResource PageMargin}"
SelectionMode="Single"
SelectionChanged="OnSelectionChanged">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="10" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Text}"
FontSize="Medium" />
<Label Text="{Binding Date}"
TextColor="{StaticResource TertiaryColor}"
FontSize="Small" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
CollectionView
の各行のレイアウトは CollectionView.ItemTemplate
要素内で定義され、データ バインディングを使用して、アプリケーションによって取得されたすべてのメモが表示されます。 CollectionView.ItemsSource
プロパティは、NotesPage.xaml.cs でデータ ソースに設定されています。
protected override async void OnAppearing()
{
base.OnAppearing();
collectionView.ItemsSource = await App.Database.GetNotesAsync();
}
このコードにより、データベースに格納されているすべてのメモが CollectionView
に設定され、これはページが表示されるときに実行されます。
CollectionView
で項目が選択されると、SelectionChanged
イベントが発生します。 イベントが発生すると、OnSelectionChanged
という名前のイベント ハンドラーが実行されます。
async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection != null)
{
// ...
}
}
SelectionChanged
イベントでは、e.CurrentSelection
プロパティを使用することで、項目に関連付けられているオブジェクトにアクセスできます。
CollectionView
クラスの詳細については、「Xamarin.Forms CollectionView」を参照してください。
ナビゲーション
ナビゲーションは、移動先の URI を指定して、シェル アプリケーション内で実行されます。 ナビゲーション URI には、3 つのコンポーネントがあります。
- "ルート"。シェルの視覚階層の一部として存在するコンテンツへのパスを定義します。
- "ページ"。 シェルの視覚階層に存在しないページは、シェル アプリケーション内の任意の場所からナビゲーション スタック上にプッシュできます。 たとえば、
NoteEntryPage
は、シェルのビジュアル階層では定義されていませんが、必要に応じてナビゲーション スタックにプッシュできます。 - 1 つまたは複数の "クエリ パラメーター"。 クエリ パラメーターは、ナビゲーション中に移動先ページに渡すことができるパラメーターです。
ナビゲーション URI に 3 つのコンポーネントがすべて含まれる必要はありませんが、含まれている場合は //route/page?queryParameters という構造になります
Note
ルートは、Route
プロパティを使用して、シェルのビジュアル階層内の要素で定義できます。 ただし、Route
プロパティが設定されていない場合は (Notes アプリケーションなど)、実行時にルートが生成されます。
シェルのナビゲーションの詳細については、「Xamarin.Forms シェルのナビゲーション」を参照してください。
ルートを登録する
シェルのビジュアル階層に存在しないページに移動するには、最初にシェルのルーティング システムに登録する必要があります。 Routing.RegisterRoute
メソッドを使用します。 Notes アプリケーションの場合、これは AppShell
コンストラクターで行われます。
public partial class AppShell : Shell
{
public AppShell()
{
// ...
Routing.RegisterRoute(nameof(NoteEntryPage), typeof(NoteEntryPage));
}
}
この例では、NoteEntryPage
という名前のルートが、NoteEntryPage
型に登録されています。 このページには、URI ベースのナビゲーションを使用して、アプリケーション内の任意の場所から移動できます。
ナビゲーションを実行する
ナビゲーションは、移動先のルートを表す引数を受け取る GoToAsync
メソッドによって実行されます。
await Shell.Current.GoToAsync("NoteEntryPage");
この例では、NoteEntryPage
に移動します。
重要
シェルのビジュアル階層にないページに移動するときは、ナビゲーション スタックが作成されます。
ページに移動するときに、クエリ パラメーターとしてデータをページに渡すことができます。
async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection != null)
{
// Navigate to the NoteEntryPage, passing the ID as a query parameter.
Note note = (Note)e.CurrentSelection.FirstOrDefault();
await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}");
}
}
この例では、CollectionView
で現在選択されている項目を取得し、NoteEntryPage
に移動します。Note
オブジェクトの ID
プロパティの値が、クエリ パラメーターとして NoteEntryPage.ItemId
プロパティに渡されます。
渡されたデータを受け取るため、NoteEntryPage
クラスは QueryPropertyAttribute
で修飾されています
[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
public string ItemId
{
set
{
LoadNote(value);
}
}
// ...
}
QueryPropertyAttribute
の最初の引数では、渡されたデータを ItemId
プロパティで受け取ることが指定され、2 番目の引数ではクエリ パラメーター ID が指定されています。そのため、上の例にある QueryPropertyAttribute
では、GoToAsync
メソッドの呼び出しにおいて URI から ItemId
クエリ パラメータ―に渡されたデータを ItemId
プロパティが受信するように、指定しています。 その後、ItemId
プロパティによって LoadNote
メソッドが呼び出されて、デバイスからメモが取得されます。
".." を GoToAsync
メソッドへの引数として指定すると、後方ナビゲーションが実行されます。
await Shell.Current.GoToAsync("..");
後方ナビゲーションの詳細については、「後方ナビゲーション」を参照してください。
データ バインディング
Xamarin.Forms アプリケーションがデータを表示し、相互作用するしくみを簡素化するために、データ バインディングが使用されます。 データ バインディングはユーザー インターフェイスと基礎アプリケーションの間で接続を確立します。 BindableObject
クラスには、データ バインディングをサポートするためのインフラストラクチャの大部分が含まれています。
データ バインディングでは、ソースとターゲットと呼ばれる 2 つのオブジェクトを接続します。 ソース オブジェクトはデータを提供します。 ターゲット オブジェクトは、ソース オブジェクトのデータを使用し (またしばしば表示し) ます。 たとえば、Editor
("ターゲット" オブジェクト) は一般的にその Text
プロパティを "ソース" オブジェクトのパブリック プロパティ string
にバインドします。 次の図では、バインドの関係を示します。
データ バインディングの主な利点は、ビューとデータ ソース間でデータを同期する心配がないことです。 ソース オブジェクトの変更は、バインディング フレームワークによって背後で自動的にターゲット オブジェクトにプッシュされます。そして、ターゲット オブジェクトの変更は、オプションでソース オブジェクトに戻されます。
データ バインディングを確立するには、次の 2 つの手順を実行します。
- "ターゲット" オブジェクトの
BindingContext
プロパティは、"ソース" に設定する必要があります。 - バインディングはターゲットとソース間で確立する必要があります。 XAML でこれは、
Binding
マークアップ拡張を使用して実現できます。
Notes アプリケーションでは、 の NoteEntryPage
BindingContext
として設定された Note
インスタンスがバインディング ソースであるのに対し、バインディング ターゲットはメモを表示する Editor
です。 最初、ページ コンストラクターが実行されるときに、NoteEntryPage
の BindingContext
が設定されます。
public NoteEntryPage()
{
// ...
BindingContext = new Note();
}
この例では、NoteEntryPage
が作成されるときに、ページの BindingContext
に新しい Note
が設定されます。 これにより、アプリケーションに新しいメモを追加するシナリオが処理されます。
さらに、NotesPage
で既存のメモが選択されている場合は、NoteEntryPage
へのナビゲーションが発生したときにも、ページの BindingContext
を設定できます。
[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
public string ItemId
{
set
{
LoadNote(value);
}
async void LoadNote(string itemId)
{
try
{
int id = Convert.ToInt32(itemId);
// Retrieve the note and set it as the BindingContext of the page.
Note note = await App.Database.GetNoteAsync(id);
BindingContext = note;
}
catch (Exception)
{
Console.WriteLine("Failed to load note.");
}
}
// ...
}
}
この例では、ページ ナビゲーションが発生すると、選択されている Note
オブジェクトがデータベースから取得されて、ページの BindingContext
に設定されます。
重要
各 "ターゲット" オブジェクトの BindingContext
プロパティは個々に設定できますが、必ずしもそうする必要はありません。 BindingContext
は、その子がすべて継承する特殊なプロパティです。 したがって、ContentPage
の BindingContext
が Note
インスタンスに設定された場合、ContentPage
のすべての子は同じ BindingContext
を持ち、Note
オブジェクトのパブリック プロパティにバインドすることができます。
その後、NoteEntryPage
内の Editor
が Note
オブジェクトの Text
プロパティにバインドされます。
<Editor Placeholder="Enter your note"
Text="{Binding Text}" />
"ソース" オブジェクトの Editor.Text
プロパティと Text
プロパティ間のバインディングが確立されます。 Editor
での変更は Note
オブジェクトに自動的に伝達されます。 同様に、Note.Text
プロパティが変更された場合、Xamarin.Forms のバインド エンジンによって Editor
のコンテンツも更新されます。 これは、双方向のバインドとも呼ばれています。
データ バインディングの詳細については、「Xamarin.Forms のデータ バインディング」を参照してください。
スタイル
Xamarin.Forms アプリケーションには、多くの場合、同じ外観を持つ複数のビジュアル要素が含まれています。 各ビジュアル要素の外観を設定すると、繰り返し使用しやすく、エラーが発生しやすくなります。 代わりに、外観を定義し、必要なビジュアル要素に適用するスタイルを作成できます。
Style
クラスは、プロパティ値のコレクションを 1 つのオブジェクトにグループ化して、複数のビジュアル要素インスタンスに適用できるようにします。 スタイルは、アプリケーション レベル、ページ レベル、ビュー レベルのいずれかで ResourceDictionary
に格納されます。 Style
を定義する場所の選択は、それを使用できる場所に影響します。
- アプリケーション レベルで定義された
Style
インスタンスは、アプリケーション全体に適用できます。 - ページ レベルで定義された
Style
インスタンスは、ページとその子に適用できます。 - ビュー レベルで定義された
Style
インスタンスは、ビューとその子に適用できます。
重要
アプリケーション全体で使用されるスタイルは、重複を回避するために、アプリケーションのリソース ディクショナリに保存されます。 ただし、あるページに固有の XAML は、アプリケーションのリソース ディクショナリに含めるべきではありません。アプリのリソースは、ページが必要とするときではなく、アプリケーションの起動時に解析されるためです。 詳細については、「アプリケーション リソース ディクショナリのサイズを減らす」を参照してください。
各 Style
インスタンスには、1 つ以上の Setter
オブジェクトのコレクションが含まれています。各 Setter
には、Property
とValue
があります。 Property
は、スタイルが適用される要素のバインド可能なプロパティの名前で、Value
はプロパティに適用される値です。 次のコード例は、NoteEntryPage
のスタイルを示しています。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Notes.Views.NoteEntryPage"
Title="Note Entry">
<ContentPage.Resources>
<!-- Implicit styles -->
<Style TargetType="{x:Type Editor}">
<Setter Property="BackgroundColor"
Value="{StaticResource AppBackgroundColor}" />
</Style>
...
</ContentPage.Resources>
...
</ContentPage>
このスタイルは、ページ上の任意の Editor
インスタンスに適用されます。
Style
を作成する場合は、TargetType
プロパティが常に必要です。
Note
Xamarin.Forms アプリケーションのスタイル設定は、これまで XAML スタイルを使用して行われていました。 しかし Xamarin.Forms では、カスケード スタイル シート (CSS) を使用したビジュアル要素のスタイル設定もサポートされています。 詳細については、「カスケード スタイル シート (CSS) を使用した アプリのスタイル設定Xamarin.Forms」を参照してください。
XAML スタイルの詳細については、「XAML スタイルを使用した Xamarin.Forms アプリのスタイル設定」を参照してください。
テストと展開
Visual Studio for Mac と Visual Studio のいずれも、アプリケーションをテストおよび展開するためのオプションを多数用意しています。 アプリケーションのデバッグは、アプリケーション開発ライフサイクルの一般的な部分であり、コードの問題を診断するときに役立ちます。 詳細については、「Set a Breakpoint」(ブレークポイントの設定)、「Step Through Code」(コードのステップ スルー)、「Output Information to the Log Window」(ログ ウィンドウへの出力情報) を参照してください。
シミュレーターは、アプリケーションの展開とテストを始めるにはおすすめの場所です。また、テスト アプリケーションに役立つ機能があります。 ただし、ユーザーは完成したアプリケーションをシミュレーター上では使用しないので、早期に、そして何度も実際のデバイス上でアプリケーションをテストすることをお勧めします。 iOS デバイスのプロビジョニングの詳細については、「Device Provisioning」(デバイスのプロビジョニング) を参照してください。 Android デバイスのプロビジョニングの詳細については、「Set Up Device for Development」(開発用のデバイスの設定) を参照してください。
次の手順
この詳細では、Xamarin.Forms シェルを使用したアプリケーション開発の基礎について説明しました。 推奨される次の手順としては、次の機能の説明を読んでください。
- Xamarin.Forms シェルでは、ほとんどのモバイル アプリケーションが必要としている基本機能を提供することで、モバイル アプリケーション開発の複雑さが軽減されます。 詳細は、「Xamarin.Forms シェル」を参照してください。
- Xamarin.Forms アプリケーションのユーザー インターフェイスを作成するには、複数のコントロール グループが使用されます。 詳細については、「Controls Reference」 (コントロールのリファレンス) を参照してください。
- データ バインディングは、2 つのオブジェクトのプロパティをリンクして、片方のプロパティでの変更が自動的にもう片方のプロパティに反映されるようにする手法です。 詳細については、データ バインディングに関するページを参照してください。
- Xamarin.Forms には、使用されるページの種類に応じて、複数のページ ナビゲーション エクスペリエンスが用意されています。 詳細については、「ナビゲーション」を参照してください。
- スタイルは、繰り返されるマークアップを減らすのに役立ち、アプリケーションの外観をより簡単に変更できるようにします。 詳細については、「Xamarin.Forms アプリのスタイル設定」を参照してください。
- データ テンプレートでは、サポートされているビューでのデータの表現方法を定義する機能が提供されます。 詳細については、「Data Templates」 (データ テンプレート) を参照してください。
- エフェクトでは、各プラットフォームのネイティブ コントロールのカスタマイズを可能にします。 エフェクトは、プラットフォーム固有のプロジェクトで
PlatformEffect
クラスをサブクラス化することによって作成され、適切な Xamarin.Forms コントロールに添付することによって使用されます。 詳細については、「Effects」 (エフェクト) を参照してください。 - 各ページ、レイアウト、およびビューは
Renderer
クラスを使用して、プラットフォームごとに異なる方法でレンダリングされます。その後、ネイティブ コントロールが作成され、画面に配置され、共有コードで指定された動作が追加されます。 開発者は独自のRenderer
クラスを実装して、コントロールの外観や動作をカスタマイズできます。 詳細については、「Custom Renderers」 (カスタム レンダラー) を参照してください。 - 共有コードはネイティブ機能に
DependencyService
クラスを介してアクセスできます。 詳細については、「Accessing Native Features with DependencyService」 (DependencyService を使用したネイティブ機能へのアクセス) を参照してください。
関連リンク
- Xamarin.Forms のシェル
- eXtensible Application Markup Language (XAML)
- データ バインディング
- コントロールのリファレンス
- Xamarin.Forms API リファレンス