According to all of the documentation, when you're creating a non-lookless control, you're supposed to subclass UserControl
. However, UserControl
is a simple subclass of ContentControl
but it doesn't appear to add anything to it, interface-wise. As such, you can take that designer-generated code and change the base class to ContentControl
and it appears to still work exactly the same.
So what's the point of UserControl
over ContentControl
?
For those who keep answering Visual Studio treats them differently, I'd argue that isn't the case. Try it! Create a new UserControl
in Visual Studio, then in the resulting XAML file, change the root tag to ContentControl
. Then in the associated class file, change the base class to ContentControl
or simply delete it as I have done here (see the note) and you'll see it appears to work exactly the same, including full WYSIWYG designer support.
Note: You can delete the base class from the code-behind because it's actually a partial class with the other 'part' of the class being created by the XAML designer via code-generation. As such, the base class will always be defined as the root element of the XAML file, so you can simply omit it in the code-behind as it's redundant.
Here's the updated XAML...
<ContentControl x:Class="Playground.ComboTest.InlineTextEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock Text="Success" />
</ContentControl>
...and the associated class file...
namespace Playground.ComboTest {
public partial class InlineTextEditor {
public InlineTextEditor()
=> InitializeComponent();
}
}
UserControls are a good fit for aggregating existing controls when you don't need to provide the consumer a ControlTemplate. This means that UserControls are not lookless. Why not just use ContentControl as it can have coupled XAML like a UserControl and the implementation looks similar to UserControl? Well, there are several important technical differences you must know:
VisualStateManager.GoToState()
. ContentControl requires the VisualStateGroups to be at the top-level and you must call them with VisualStateManager.GoToElementState()
.ContentControl's ControlTemplate
<ControlTemplate TargetType="ContentControl">
<ContentPresenter
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" />
</ControlTemplate>
UserControl's ControlTemplate
<ControlTemplate TargetType="UserControl">
<Border BorderBrush="{TemplateBinding Border.BorderBrush}"
BorderThickness="{TemplateBinding Border.BorderThickness}"
Background="{TemplateBinding Panel.Background}"
Padding="{TemplateBinding Control.Padding}"
SnapToDevicePixels="True">
<ContentPresenter
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
Content="{TemplateBinding ContentControl.Content}" />
</Border>
</ControlTemplate>