1

I have built the following control:

MyContentControl.xaml.cs:

public partial class MyContentControl : UserControl { public MyContentControl() { InitializeComponent(); } public static readonly DependencyProperty MyContentProperty = DependencyProperty.Register( "MyContent", typeof(object), typeof(MyContentControl), new PropertyMetadata(default(object))); public object MyContent { get { return (object) GetValue(MyContentProperty); } set { SetValue(MyContentProperty, value); } } } 

MyContentControl.xaml:

<UserControl x:Class="MyContentControl" x:Name="self" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <Border BorderBrush="Gray" BorderThickness="1"> <ContentPresenter Content="{Binding ElementName=self, Path=MyContent}"/> </Border> </Grid> </UserControl> 

And it can be used like this:

<controls:MyContentControl> <controls:MyContentControl.MyContent> <TextBox Text="Some text..."/> </controls:MyContentControl.MyContent> </controls:MyContentControl> 

What I would like to achieve is being able to use my control like this:

<controls:MyContentControl> <TextBox Text="Some text..."/> </controls:MyContentControl> 

I would like to define the inner content like I would e.g. for a StackPanel.

How can this be achieved?

9
  • Any particular reason for imitating what StackPanel, DockPanel, Grid, Canvas, TabPanel would do? Commented Aug 8, 2021 at 21:31
  • @XAMlMAX: Yes, I would like to be able to simply wrap existing controls in my custom control, e.g. to provide custom design or other functionality. Is there a better way? Commented Aug 8, 2021 at 23:17
  • Oh, I see. Is WrapPanel or UniformGrid of any help? Cause if you want to have a custom logic, like adding controls in a certain position then custom control derived from Panel would be best option. For "other functionality" I would suggest attached property. So you can reuse it ion other places. Commented Aug 9, 2021 at 0:47
  • If I inherit from Panel, can I have my own custom XAML? Commented Aug 9, 2021 at 17:07
  • You could Inherit from contentcontrol rather than user control. See editrow here social.technet.microsoft.com/wiki/contents/articles/… Commented Aug 9, 2021 at 17:12

2 Answers 2

2

You need to decorate the MyContentControl class with the ContentPropertyAttribute https://learn.microsoft.com/de-de/dotnet/api/system.windows.markup.contentpropertyattribute?view=net-5.0

[ContentProperty("MyContent")] public partial class MyContentControl : UserControl { ... 

Then you should be able to directly add the content without explicitly specifying "<controls:MyContentControl.MyContent>" in Property Element syntax. So that the markup below should parse and be valid:

<controls:MyContentControl> <TextBox Text="Some text..."/> </controls:MyContentControl> 
Sign up to request clarification or add additional context in comments.

2 Comments

This works ok, as long as the wrapped content does not have any named elements, similar to this issue.
btw why do you need 'MyContent'? A UserControl is a ContentControl. So you could/should just use the UserControls Content property...
0

Although lidqy's answer was closest to what I had initially intended, I ended up following Andy's suggestion from the comments to the question.

The key to that approach is: the desired custom XAML is defined in a style/template, in any available resource dictionary:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:MyControls"> <Style TargetType="{x:Type controls:MyContentControl}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type controls:MyContentControl}"> <Grid> <Border BorderBrush="Gray" BorderThickness="1"> <ContentPresenter/> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> 

The MyContentControl class then only needs to inherit ContentControl - and does not need to be a UserControl (with .xaml and xaml.cs) files.

@Andy: Regarding the question of "named elements": the exception/error is "Error MC3093: Cannot set Name attribute value 'xxx' on element 'yyy'. 'yyy' is under the scope of element 'MyContentControl', which already had a name registered when it was defined in another scope.", pretty much like here.

@lidqy: I also thought "why not just use the Content property?", but when trying I apparently created some kind of recursive binding.

Thank you, both! :o)

NOTE: The above approach should work for all ContentControls, including UserControls, enabling re-templating of basically any custom control ;o)

2 Comments

So you don't need a custom control at all. You can just define this style for a content control. And the content of this could be defined in a data template.
@XAMlMAX: Very true. In my case the custom control is already there, the question should actually be (I know now): (How) can I re-template a control? Sometimes WPF does indeed offer pleasant suprises ;o)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.