I feel like this should have been a simple thing, but obviously I'm doing something dumb.
I am trying to make a UserControl
with a DependencyProperty
(an enum) that controls whether it simply displays the text supplied in its Content
property verbatim, or appends it with some additional text.
UserControl:
<UserControl x:Class="Controls.UserControls.IndicatorLabel"
x:Name="indicatorLabel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:enum="clr-namespace:MyNamespace;assembly=EnumAssembly">
<Label>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Content, ElementName=indicatorLabel}" />
<TextBlock FontStyle="Italic"
Margin="5,0,0,0">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility"
Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IndicatorType}"
Value="{x:Static enum:LabelIndicator.Optional}">
<Setter Property="Text"
Value="(Optional)" />
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding IndicatorType}"
Value="{x:Static enum:LabelIndicator.Required}">
<Setter Property="Text"
Value="(Required)" />
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Label>
</UserControl>
UserControl's code-behind:
public partial class IndicatorLabel : UserControl
{
public static DependencyProperty IndicatorTypeProperty = DependencyProperty.Register("IndicatorType", typeof(LabelIndicator), typeof(IndicatorLabel));
public LabelIndicator IndicatorType
{
get => (LabelIndicator)GetValue(IndicatorTypeProperty);
set => SetValue(IndicatorTypeProperty, value);
}
public IndicatorLabel()
{
InitializeComponent();
}
}
Usage of the UserControl in another XAML page:
<uc:IndicatorLabel Grid.Row="4"
Content="Description"
IndicatorType="Optional" />
I expected to see: Description (Optional)
In fact, I haven't been able to get what's in the UserControl's XAML to have any affect at all, so long as the Content
property is set.
EDIT:
The reason I say it has no effect is because even if put a literal string in the Text
property of the first TextBlock
, whatever is in the Content
property still displays. It seems as if neither TextBlock
is truly showing.
So why is this happening? Is it not possible to use the Content
property as a way to get text into the parts that I really mean to display? Am I breaking some WPF rule about Content
here?
First off; yes you don't want to use Content
. What your XAML for your UC really says is:
<UserControl>
<UserControl.Content>
... All that stuff
</UserControl.Content>
</UserControl>
So when you assign Content in the parent XAML you are just overwriting all that. Use a different property (like "Text") instead. If instead of UserControl
you did an actual Control
(with separate ControlTemplate
and everything) then you could use that name
Also, the {Binding IndicatorType}
is looking at the inherited data context. You should either set the User Control's data context to itself or use x:Reference
to tell it to look at the user control itself.