WPF: Cannot set properties on property elements weirdness

.net, c#, properties, wpf, xaml

Solution

I can explain what is going wrong and how to fix it.

First,

<l:CustomPanel>
  <l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" />

is a simple syntax error. The `<l:CustomPanel.Caption>` syntax does not accept XML attributes - the property value must be within the element.

This is proper property element syntax:

<l:CustomPanel>    
  <l:CustomPanel.Caption>  
    <TextBlock Text="Caption text" FontSize="18" Foreground="White" />   
  </l:CustomPanel.Caption>  
</l:CustomPanel>

but:

- Property element syntax works only with DependencyProperties (so it didn't work with your CLR property) and

- Property element syntax always honors the ContentPropertyAttribute of the property type

Since TextBlock has a [ContentPropertyAttribute("Inlines")], the property element syntax is trying to add the TextBlock to the Inlines collection.

The solution is simple: Declare your property as a DependencyProperty of type UIElement instead of type TextBlock. This has the additional advantage of not restricting the display of content to just a TextBlock. If you really do want to restrict it to just a TextBlock, you can use a validation callback.

public UIElement Content { get { ...
public static readonly DependencyProperty ContentProperty = ...

Problem

``` private TextBlock _caption = new TextBlock(); public TextBlock Caption { get { return _caption; } set { _caption = value; } } <l:CustomPanel> <l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" /> </l:CustomPanel> ``` Gives me the following error: Cannot set properties on property elements. If I use: ``` <l:CustomPanel> <l:CustomPanel.Caption> <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> </l:CustomPanel.Caption> </l:CustomPanel> ``` My TextBlock shows up fine but it's nested inside another TextBlock like so, it even seems to add itself outside of the Caption property: ``` <l:CustomPanel> <l:CustomPanel.Caption> <TextBlock> <InlineUIContainer> <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> </InlineUIContainer> </TextBlock> </l:CustomPanel.Caption> <TextBlock> <InlineUIContainer> <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> </InlineUIContainer> </TextBlock> </l:CustomPanel> ``` As you might have already guessed, what i'd like my code to do is to set my Caption property from XAML on a custom panel, if this is possible. I've also tried the same code with a DependencyProperty to no avail. So, anyone that can help me with this problem?

Original source