Xamarin.FormsContentView クラスは、1 つの子要素を含む Layout の一種であり、通常、カスタムの再利用可能なコントロールを作成するために使用されます。 ContentView クラスは TemplatedView から継承します。 この記事と関連するサンプルでは、ContentView クラスに基づいてカスタム CardView コントロールを作成する方法について説明します。
次のスクリーンショットは、ContentView クラスから派生した CardView コントロールを示しています。
ContentView クラスは、1 つのプロパティを定義します。
ContentはViewオブジェクト。 このプロパティはBindablePropertyオブジェクトによってサポートされるため、データ バインディングのターゲットにすることができます。
ContentView は、TemplatedView クラスからプロパティも継承します。
ControlTemplateは、コントロールの外観を定義またはオーバーライドできるControlTemplateです。
ControlTemplate プロパティの詳細については、「ControlTemplate を使用して外観をカスタマイズする」を参照してください。
カスタム コントロールの作成
ContentView クラスは単独ではほとんど機能しませんが、カスタム コントロールを作成するために使用できます。 サンプル プロジェクトでは、CardView コントロール (イメージ、タイトル、および説明をカードに似たレイアウトで表示する UI 要素) を定義します。
カスタム コントロールを作成するプロセスは次のとおりです。
- Visual Studio 2019 で
ContentViewテンプレートを使用して新しいクラスを作成します。 - 新しいカスタム コントロールの分離コード ファイル内で、独自のプロパティやイベントを定義します。
- カスタム コントロールの UI を作成します。
Note
XAML ではなくコードでレイアウトが定義されているカスタム コントロールを作成できます。 わかりやすくするために、サンプル アプリケーションでは、XAML レイアウトを持つ 1 つの CardView クラスのみが定義されます。 ただし、サンプル アプリケーションには、コードでのカスタム コントロール使用プロセスを示す CardViewCodePage クラスが含まれています。
分離コードのプロパティを作成する
CardView カスタム コントロールは、次のプロパティを定義します。
CardTitle: カードに表示されるタイトルを表すstringオブジェクト。CardDescription: カードに表示される説明を表すstringオブジェクト。IconImageSource: カードに表示されるイメージを表すImageSourceオブジェクト。IconBackgroundColor: カードに表示されるイメージの背景色を表すColorオブジェクト。BorderColor: カードの境界線、イメージの境界線、および分割線の色を表すColorオブジェクト。CardColor: カードの背景色を表すColorオブジェクト。
Note
BorderColor プロパティは、デモンストレーションの目的で複数の項目に影響します。 必要に応じて、このプロパティを 3 つのプロパティに分割できます。
各プロパティは、BindableProperty インスタンスでサポートされます。 バッキング BindableProperty では、MVVM パターンを使用して各プロパティのスタイルを設定し、バインドすることができます。
次の例は、バッキング BindableProperty を作成する方法を示しています。
public static readonly BindableProperty CardTitleProperty = BindableProperty.Create(
"CardTitle", // the name of the bindable property
typeof(string), // the bindable property type
typeof(CardView), // the parent object type
string.Empty); // the default value for the property
カスタム プロパティでは、次の GetValue メソッドと SetValue メソッドを使用して BindableProperty オブジェクト値を取得および設定します。
public string CardTitle
{
get => (string)GetValue(CardView.CardTitleProperty);
set => SetValue(CardView.CardTitleProperty, value);
}
BindableProperty オブジェクトの詳細については、「バインド可能なプロパティ」をご覧ください。
UI の定義
カスタム コントロール UI では、CardView コントロールのルート要素として ContentView が使用されます。 次の例は、CardView XAML を示しています。
<ContentView ...
x:Name="this"
x:Class="CardViewDemo.Controls.CardView">
<Frame BindingContext="{x:Reference this}"
BackgroundColor="{Binding CardColor}"
BorderColor="{Binding BorderColor}"
...>
<Grid>
...
<Frame BorderColor="{Binding BorderColor, FallbackValue='Black'}"
BackgroundColor="{Binding IconBackgroundColor, FallbackValue='Grey'}"
...>
<Image Source="{Binding IconImageSource}"
.. />
</Frame>
<Label Text="{Binding CardTitle, FallbackValue='Card Title'}"
... />
<BoxView BackgroundColor="{Binding BorderColor, FallbackValue='Black'}"
... />
<Label Text="{Binding CardDescription, FallbackValue='Card description text.'}"
... />
</Grid>
</Frame>
</ContentView>
ContentView 要素は、CardView インスタンスにバインドされているオブジェクトにアクセスするために使用できる x:Name プロパティをこれに設定します。 レイアウト内の要素は、バインドされたオブジェクトで定義された値へのプロパティのバインドを設定します。
データ バインディングの詳細については、「Xamarin.Forms のデータ バインディング」を参照してください。
Note
FallbackValue プロパティは、バインディングが null の場合の既定値を提供します。 これにより、Visual Studio の XAML Previewer で CardView コントロールをレンダリングすることもできます。
カスタム コントロールをインスタンス化する
カスタム コントロールのインスタンスを作成するページには、カスタム コントロールの名前空間への参照を追加する必要があります。 次の例は、XAML で ContentPage インスタンスに追加される コントロール と呼ばれる名前空間の参照を示しています。
<ContentPage ...
xmlns:controls="clr-namespace:CardViewDemo.Controls" >
参照が追加されたら、XAML で CardView のインスタンスを作成し、そのプロパティを定義できます。
<controls:CardView BorderColor="DarkGray"
CardTitle="Slavko Vlasic"
CardDescription="Lorem ipsum dolor sit..."
IconBackgroundColor="SlateGray"
IconImageSource="user.png"/>
CardView は、コード内でインスタンスを作成することもできます。
CardView card = new CardView
{
BorderColor = Color.DarkGray,
CardTitle = "Slavko Vlasic",
CardDescription = "Lorem ipsum dolor sit...",
IconBackgroundColor = Color.SlateGray,
IconImageSource = ImageSource.FromFile("user.png")
};
ControlTemplate を使用して外観をカスタマイズする
ContentView クラスから派生したカスタム コントロールは、XAML、コードを使用して外観を定義できます。また、外観をまったく定義しなくても構いません。 外観の定義方法に関係なく、ControlTemplate オブジェクトはカスタム レイアウトで外観をオーバーライドできます。
CardView レイアウトは、ユース ケースによってはスペースを取りすぎるかもしれません。 ControlTemplate は、CardView レイアウトをオーバーライドして、圧縮されたリストに適した、よりコンパクトなビューを提供できます。
<ContentPage.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="CardViewCompressed">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100*" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0"
Grid.Column="0"
Source="{TemplateBinding IconImageSource}"
BackgroundColor="{TemplateBinding IconBackgroundColor}"
WidthRequest="100"
HeightRequest="100"
Aspect="AspectFill"
HorizontalOptions="Center"
VerticalOptions="Center"/>
<StackLayout Grid.Row="0"
Grid.Column="1">
<Label Text="{TemplateBinding CardTitle}"
FontAttributes="Bold" />
<Label Text="{TemplateBinding CardDescription}" />
</StackLayout>
</Grid>
</ControlTemplate>
</ResourceDictionary>
</ContentPage.Resources>
ControlTemplate のデータ バインディングでは、TemplateBinding マークアップ拡張機能を使用してバインディングを指定します。 ControlTemplate プロパティは、その x:Key 値を使用して、定義された ControlTemplate オブジェクトに設定できます。 次の例では、ControlTemplate プロパティを CardView インスタンスに設定します。
<controls:CardView ControlTemplate="{StaticResource CardViewCompressed}"/>
次のスクリーンショットは、標準の CardView インスタンスと ControlTemplate がオーバーライドされた CardView インスタンスを示しています。
コントロール テンプレートの詳細については、「Xamarin.Forms のコントロール テンプレート」を参照してください。

