子要素を持てるカスタムコントロールを作成して画面作成を省力化する

##はじめに
デザイン性の高い画面をXAML化しているとUserControlから派生させたカスタムコントロールを幾つも作って配置する作業が多くなります。その際微妙に異なる要素を持ったカスタムコントロールを都度作るのは不効率です。WPF(XAML)には、ContentPresenterというタグがあり、子供の要素を持つこのできるカスタムコントロールを作成することができます。

```xaml:App.xaml
  <Application x:Class="ContentPresenterSample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:ContentPresenterSample"
             StartupUri="MainWindow.xaml">

    <Application.Resources>
        <ResourceDictionary>
            <Style TargetType="{x:Type local:SingleControl}">
                <Setter Property="Margin" Value="0" />
                <Setter Property="SnapsToDevicePixels" Value="True" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:SingleControl}">
                            <Border BorderBrush="Blue" BorderThickness="1">
                                <Button Margin="5">ボタン</Button>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            
            <Style TargetType="{x:Type local:ParentControl}">
                <Setter Property="Margin" Value="0" />
                <Setter Property="SnapsToDevicePixels" Value="True" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:ParentControl}">
                            <ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>
```

```csharp:SingleControl.cs
namespace ContentPresenterSample
{
    public class SingleControl: UserControl
    {
    }
}
```

```csharp:ParentControl.cs
namespace ContentPresenterSample
{
    public class ParentControl : UserControl
    {
    }
}
```

```xaml:MainWindow.xaml
<Window x:Class="ContentPresenterSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ContentPresenterSample"
        Title="MainWindow"
        Width="525"
        Height="350">

    <Grid>
        <StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
            <local:SingleControl Width="100" Height="100" Margin="0,0,10,0"/>
            
            <local:ParentControl Width="100" Height="100">
                <Border BorderBrush="Blue" BorderThickness="1">
                    <Button Margin="5">ボタン</Button>
                </Border>
            </local:ParentControl>
        </StackPanel>
    </Grid>
</Window>
```
![ContentPresenter説明1.png](https://qiita-image-store.s3.amazonaws.com/0/7839/8a3fe036-104f-28cc-d9f7-4868c98c835f.png)

左側のコントロールは、Styleの中にデザインと子要素を内包していますが、右側のコントロールはContentPresenterを使用して子要素を持てるようにしています。ContentPresenterを使えば子要素の違う枠だけ描画するカスタムコントロールなども作成できます。