独自のコンテンツをホストできるUserControl(この場合は、Backgroundcolorsが定義された正方形のボタン)を作成します。
UserControl:
<UserControl x:Class="SGDB.UI.Controls.ModernButton"
xmlns:local="clr-namespace:SGDB.UI.Controls"
xmlns:converter="clr-namespace:SGDB.UI.Converter"
x:Name="_modernButton">
<Button>
<Button.Resources>
<converter:EnumToColorConverter x:Key="ColorConverter"/>
</Button.Resources>
<Button.Template>
<ControlTemplate>
<Border Width="{Binding Size, ElementName=_modernButton}" Height="{Binding Size, ElementName=_modernButton}" BorderBrush="Black" BorderThickness="0.8,0.8,3,3">
<Grid Background="{Binding BackgroundColor, ElementName=_modernButton, Converter={StaticResource ColorConverter}}">
<ContentPresenter/>
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
さて、ご想像のとおり、MainView内でこのコントロールを使用すると、コンテンツを定義するまですべてが正常に機能します。
使用:
<control:ModernButton Size="200" BackgroundColor="Light">
TEST
</control:ModernButton>
この場合、「TEST」は、UserControlのコンテンツ全体(ボタンテンプレート全体)をオーバーライドします。これは、UserControl内のボタンが「コンテンツ」自体として定義されており、新しいコンテンツを定義するときにオーバーライドされるために発生すると思います。
だから最後の質問は:私が探しているものを達成することは可能ですか?はいの場合:方法は? MainViewで定義しているコンテンツを、ユーザーコントロールのContentPresenterではなく、ボタンテンプレート内の自己定義のContentPresenterに「リダイレクト」するにはどうすればよいですか?
可能であれば、コンテンツをホストする新しいdp-properyを作成したくありません。例:
<controls:MordernButton Size="200" BackgroundColor="Light">
<controls:ModernButton.Content>
I don't want this, if possible
</controls:ModernButton.Content>
</controls:ModernButton>
さあ行こう。
<UserControl x:Class="SGDB.UI.Controls.ModernButton"
xmlns:local="clr-namespace:SGDB.UI.Controls"
xmlns:converter="clr-namespace:SGDB.UI.Converter"
x:Name="_modernButton">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Button Content="{TemplateBinding Content}">
<Button.Resources>
<converter:EnumToColorConverter x:Key="ColorConverter"/>
</Button.Resources>
<Button.Template >
<ControlTemplate TargetType="Button">
<Border Width="{Binding Size,
ElementName=_modernButton}"
Height="{Binding Size,
ElementName=_modernButton}"
BorderBrush="Black"
BorderThickness="0.8,0.8,3,3">
<Grid Background="{Binding BackgroundColor, ElementName=_modernButton, Converter={StaticResource ColorConverter}}">
<ContentPresenter />
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</UserControl.Template>
</UserControl>
ContentPropertyAttribute
を使用して、実際のContentプロパティの代わりにこのプロパティを設定するようにxamlに指示します。
[ContentProperty("InnerContent")]
public partial class ModernButton : UserControl
{
public ModernButton()
{
InitializeComponent();
}
public static readonly DependencyProperty InnerContentProperty =
DependencyProperty.Register("InnerContent", typeof(object), typeof(ModernButton));
public object InnerContent
{
get { return (object)GetValue(InnerContentProperty); }
set { SetValue(InnerContentProperty, value); }
}
}
次に、xamlでコンテンツプレゼンターをバインドして、代わりにInnerContentプロパティを使用します。
<ContentPresenter Content="{Binding InnerContent, ElementName=_modernButton}"/>
これにより、実際のコンテンツを置き換えることなく、次のことができます。
<control:ModernButton Size="200" BackgroundColor="Light">
TEST
</control:ModernButton>
Youre UserControlが次のとおりであるとします。
<UserControl x:Class="QuickAndDirtyAttempt.Decorator" ....
<UserControl.Template>
<ControlTemplate TargetType="{x:Type local:Decorator}">
<StackPanel Orientation="Vertical">
<Label>Foo</Label>
<ContentPresenter/>
<Label>Bar</Label>
</StackPanel>
</ControlTemplate>
</UserControl.Template>
</UserControl>
テンプレートのTargetTypeプロパティに注意してください。これがないと、プロジェクトは正常にコンパイルされますが、ContentPresenterは機能しません。その後:
<Window ... >
<StackPanel Orientation="Vertical">
<local:Decorator>
<Label Background="Wheat">User supplied content here</Label>
</local:Decorator>
</StackPanel>
</Window>
何かを実装する前に これを読む をお勧めします
シンプル。 UserControlのテンプレートを回避して置き換えるだけです。
<UserControl.Template>
<ControlTemplate TargetType="{x:Type UserControl}">
<Button Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}">
<Button.Resources>
<converter:EnumToColorConverter x:Key="ColorConverter"/>
</Button.Resources>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Width="{Binding Size,
ElementName=_modernButton}"
Height="{Binding Size,
ElementName=_modernButton}"
BorderBrush="Black"
BorderThickness="0.8,0.8,3,3">
<Grid Background="{Binding BackgroundColor, ElementName=_modernButton, Converter={StaticResource ColorConverter}}">
<ContentPresenter />
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</UserControl.Template>
すべてのユーザーコントロール(少なくともXAMLとそのテンプレートの用語)は、ContentPresenterが内部にあるボーダーです。 ContentPresenterだけが本当に重要な部分です。
したがって、あなたがすることは、そのテンプレートを取り出して、UserControlが持っているContentプロパティを少し異なるものにフィードすることだけです。この場合はボタンです。
これは、usercontrol out ofを他のコントロールにすることと、いくつかのコントロールintoをユーザーコントロールにすることの違いです。他のコントロールからユーザーコントロールを作成すると、はるかに強力になります。