I have a user control with this code behind:
/// <summary>
/// The text to use for the header.
/// </summary>
public UIElement HeaderText
{
get { return (UIElement) GetValue(HeaderTextProperty); }
set { SetValue(HeaderTextProperty, value); }
}
public static DependencyProperty HeaderTextProperty =
DependencyProperty.Register("HeaderText",
typeof(UIElement),
typeof(Panel),
new PropertyMetadata(null, new PropertyChangedCallback(HeaderTextPropertyChanged)));
private static void HeaderTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as Panel;
if (control != null)
{
control.HeaderText = (UIElement) e.NewValue;
}
}
And this XAML:
<TextBlock Text="{TemplateBinding local:CustomPanel.HeaderText}" />
And I'm trying to use the user control like this:
<controls:CustomPanel>
<controls:CustomPanel.HeaderText>
<TextBlock Text="Foo " />
<TextBlock Text="{Binding Bar}" />
<TextBlock Text=" baz." />
</controls:CustomPanel.HeaderText>
</controls:CustomPanel>
However, what I get is blank/empty text.
I can get it to work if I change UIElement
into string
in code-behind, but I want to accept both string
, TextBlock
and practically any UIElement
that makes sense for text.
How can I achieve this?
Don't use a TextBlock
in your control but a ContentPresenter
(and bind the Content
), it can host anything. Make the property type object
and change the name to Header
for consistency.
(As a side-note: Usually you have additional properties that go along with the Header
, namely a HeaderTemplate
and a HeaderTemplateSelector
. If the ContentPresenter
is in a template you can make it bind to all three properties by setting the ContentSource
to "Header"
)