UserControl in ControlTemplate

I have a ControlTemplate for Telerik tiles and I prevail as shown below:

<ControlTemplate TargetType="{x:Type ctrl:Tile}"> <Border> <local:UserControl> <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> </local:UserControl> </Border> </ControlTemplate> 

My user control looks like this:

  <DockPanel> <!-- some content --> <ContentPresenter/> </DockPanel> 

The control panel does not display the contents of the UserControl.

If I change my control pattern to:

 <ControlTemplate TargetType="{x:Type ctrl:Tile}"> <Border> <StackPanel> <local:UserControl/> <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> </StackPanel> </Border> </ControlTemplate> 

He will find the content and place it accordingly. It seems that the ControlTemplate cannot find the content when it is nested in my UserControl. Is there anything I could do wrong?

Note that these ControlTemplate elements are displayed in ItemsPresenter.

+4
source share
1 answer

You are handling the UserControl as if it were the main ContentControl (e.g. Button ), which is slightly different from what it actually is. Using Button as an example, when you add a child (i.e. A TextBlock ) to a Button that actually sets that TextBlock as a Button Content property. The way it is processed is a Button ControlTemplate , which includes a ContentPresenter to enter Content in. The visual tree ends as follows:

 <Button> -start Template <Border> <ContentPresenter> -start Content <TextBlock> 

So far, basically a model of your code. The problem is that instead you use a (still ContentControl derivative) UserControl , which instead of using the ControlTemplate most often defined using the XAML + code-behind model, where XAML defines the Content UserControl . (You can switch these models and a UserControl template or make the Button derived class with XAML + code, but not shared)

If you want to determine how the appearance of your UserControl in XAML is both normal and still be able to enter other content, you can add another DependencyProperty , which reflects the setting of the Content property and sets the content for it. This approach is used with derivatives of the HeaderedContentControl (i.e. Expander ), which essentially has 2 content properties, Content and Header . Using the new property will look like this:

 <Border> <local:UserControl> <local:UserControl.OtherContent> <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> </local:UserControl.OtherContent> </local:UserControl> </Border> 

And then inside the UserControl XAML you need to explicitly configure the ContentPresenter bindings (you only get them for free inside the ContentControls templates):

 <DockPanel> <!-- some content --> <ContentPresenter Content="{Binding Path=OtherContent, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"/> </DockPanel> 

If you need ContentTemplate , ContentTemplateSelector or ContentStringFormat , you will also need to add properties and bindings for them.

+5
source

Source: https://habr.com/ru/post/1487354/


All Articles