This article is currently in the process of being translated into Japanese (~92% done).
Creating & using a UserControl
UserControl で代表されるWPFのユーザーコントロールは、マークアップと再利用可能なコンテナをグループ化する概念です。同じインターフェースで同じ機能なので、アプリケーションの異なる場所や、異なるアプリケーションでさえ使用できます。
ユーザーコントロールはWPFのWindowとよく似た動作をします。それはコントロールを配置できる場所であり、それらのコントロールと相互作用できるコードビハインドファイルです。ユーザーコントロールが含まれるファイルもまた、Windowと同じ様に、.xaml で終わるなまえであり、コードビハインドファイルは .xaml.cs で終わる名前です。ただしマークアップの最初は少し異なります。
<UserControl x:Class="WpfTutorialSamples.User_Controls.LimitedInputUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
</Grid>
</UserControl>
しかしそんなに変でもありません。ルートにはWindowエレメントではなく UserControl エレメントがあります。そして、ユーザーコントロールの設計時のサイズを制御する DesignHeight と DesignWidth プロパティがあります(実行時のサイズはコントロールを保持するコンテナによって決まります)。コードビハインドも同じです。単純に Window の代わりに UserControl を継承しています。
ユーザーコントロールの作成
このスクリーンショットのように、追加したいプロジェクトやフォルダーの名前のところで右クリックして、他のウインドウを追加するのと同じ様にプロジェクトにユーザーコントロールを追加します。(使っている Visual Studio のバージョンによって表示が少し違うかもしれません)
この記事のために、テキストボックスの文字数を指定の数に制限し、入力済み文字数と入力できる総文字数を表示する機能を持った使いやすいユーザーコントロールを作ります。これは大変簡単に出来ます。また Twitter のようなウェブアプリケーションにも使われています。あなたのウィンドウだけにこの機能を追加するのは簡単ですが、アプリケーションの他の場所でも使えるので、簡単で再利用可能な UserControl でラップするのが理にかなっています。
コードに入る前に、目指す最終的な結果を見てみましょう。
ユーザーコントロールのコードです。
<UserControl x:Class="WpfTutorialSamples.User_Controls.LimitedInputUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Title}" />
<Label Grid.Column="1">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ElementName=txtLimitedInput, Path=Text.Length}" />
<TextBlock Text="/" />
<TextBlock Text="{Binding MaxLength}" />
</StackPanel>
</Label>
<TextBox MaxLength="{Binding MaxLength}" Grid.Row="1" Grid.ColumnSpan="2" Name="txtLimitedInput" ScrollViewer.VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" />
</Grid>
</UserControl>
using System;
using System.Windows.Controls;
namespace WpfTutorialSamples.User_Controls
{
public partial class LimitedInputUserControl : UserControl
{
public LimitedInputUserControl()
{
InitializeComponent();
this.DataContext = this;
}
public string Title { get; set; }
public int MaxLength { get; set; }
}
}
マークアップはとても明快です。2つのカラムと2つのロウを持つグリッドです。上部のグリッドには2つのラベルがあり、一つはタイトルで、もう一つはステータスを示しています。これらは必要な情報を得るためにデータバインディングを使います。Title と MaxLength は通常のクラスの通常のプロパティとして定義されるコードビハインドのプロパティによってデータを得ます。
現在の文字数はユーザーコントロールの低位部を使って、テキストボックスコントロールの Text.Length プロパティで直接取得できます。この結果は上のスクリーンショットの通りです。これらのバインディングのおかげで、ラベルの更新やテキストボックスへの MaxLength プロパティの設定のために少しもC#のコードを書く必要がありません。代わりに、プロパティに直接バインドするだけです。
ユーザーコントロールの使用
上記のコードが整ったら、次はこのユーザーコントロールをウィンドウで使います。ユーザーコントロールのある namespace をウィンドウのXAMLコードの最初に追加します。
xmlns:uc="clr-namespace:WpfTutorialSamples.User_Controls"
次に、他のWPFコントロールと同じ様にucプレフィックスを使ってウィンドウにコントロールを追加します。
<uc:LimitedInputUserControl Title="Enter title:" MaxLength="30" Height="50" />
Title と MaxLength プロパティをXAMLで直接使っている事に注意して下さい。これがサンプルの全コードです。
<Window x:Class="WpfTutorialSamples.User_Controls.LimitedInputSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:WpfTutorialSamples.User_Controls"
Title="LimitedInputSample" Height="200" Width="300">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<uc:LimitedInputUserControl Title="Enter title:" MaxLength="30" Height="50" />
<uc:LimitedInputUserControl Title="Enter description:" MaxLength="140" Grid.Row="1" />
</Grid>
</Window>
これによって、この例で説明しているように、この全ての機能を1行のコードで再利用できます。例では制限されたテキストの入力コントロールを2回使っています。既に見ましたが、この最終結果は次のようになります。
まとめ
ユーザーコントロールによって、一般的に使用するインターフェースと機能を作成することは強く推奨されます。そして上記の例で見たように、これを作って使うことは大変簡単です。