正如标记的答案所示,Reflector确认UserControl会覆盖一些方法,因此虽然两者之间的界面完全相同,并且您可以使用VS设计器,但行为上存在细微差别。我会让读者更多地研究这些差异,但这里是子类代码......
public class UserControl : ContentControl
{
// Fields
private static DependencyObjectType _dType;
// Methods
static UserControl()
{
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(UserControl), new FrameworkPropertyMetadata(typeof(UserControl)));
_dType = DependencyObjectType.FromSystemTypeInternal(typeof(UserControl));
UIElement.FocusableProperty.OverrideMetadata(typeof(UserControl), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));
KeyboardNavigation.IsTabStopProperty.OverrideMetadata(typeof(UserControl), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));
Control.HorizontalContentAlignmentProperty.OverrideMetadata(typeof(UserControl), new FrameworkPropertyMetadata(HorizontalAlignment.Stretch));
Control.VerticalContentAlignmentProperty.OverrideMetadata(typeof(UserControl), new FrameworkPropertyMetadata(VerticalAlignment.Stretch));
}
internal override void AdjustBranchSource(RoutedEventArgs e)
{
e.Source = this;
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new UserControlAutomationPeer(this);
}
// Properties
internal override DependencyObjectType DTypeThemeStyleKey
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return _dType;
}
}
internal override FrameworkElement StateGroupsRoot
{
get
{
return (base.Content as FrameworkElement);
}
}
}
根据所有文档,当您创建一个非外观控件时,您应该将UserControl
子类化。但是,UserControl
是ContentControl
的一个简单子类,但它似乎没有向接口添加任何内容。因此,您可以使用设计器生成的代码并将基类更改为ContentControl
,它似乎仍然完全相同。
那么UserControl
对ContentControl
的重点是什么?
更新:对于那些一直在回答VS的人来说,对待他们的方式不同,我认为事实并非如此。试试吧。在Visual Studio中创建一个新的UserControl
。然后在生成的XAML文件中,将根标记更改为ContentControl
。然后在关联的类文件中,将基类更改为ContentControl
。它似乎完全相同,包括完全所见即所得的设计师支持。
这是更新后的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>
...以及相关的类文件......
using System.Windows.Controls;
namespace Playground.ComboTest
{
public partial class InlineTextEditor : ContentControl
{
public InlineTextEditor()
{
InitializeComponent();
}
}
}
答案 0 :(得分:22)
当您不需要向消费者提供ControlTemplate时,UserControl非常适合聚合现有控件。这意味着 UserControls看起来并不像。为什么不使用ContentControl,因为它可以像UserControl一样耦合XAML,实现看起来类似于UserControl?那么,您必须知道几个重要的技术差异:
VisualStateManager.GoToState()
更改VisualStates。 ContentControl要求VisualStateGroups位于顶层,您必须使用VisualStateManager.GoToElementState()
调用它们。ContentControl的ControlTemplate
<ControlTemplate TargetType="ContentControl">
<ContentPresenter
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" />
</ControlTemplate>
UserControl的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>
答案 1 :(得分:7)
基本上,UserControl
类是为了方便起见。它使我们能够从已有的控件构建UI的一小部分,而ContentControl
实际上是用于创建新控件,通常只有一个目的和/或功能。
我读了一本书,对此有一个很好的解释,祝你好运,有人'在网上发了一份'。从链接的书中:
UserControl类是一个容器类,充当集合的“黑盒子”容器 相关控制。如果您需要一组三个控件始终一起显示 被允许轻松地互相交谈,然后一个可能的候选人来实现这一点 UserControl类。
然后是否要创建CustomControl
:
以下是决策过程的摘要:
尽可能使用框架。 WPF提供了各种可扩展的功能 控件,因此请确保您所需的功能尚不存在于 WPF控制。
在许多情况下,您正在使用的数据结构需要不同的可视化表示。 使用ControlTemplates和DataTemplates通常可以为您提供功能 你需要。
看看ValueConverters是否可以帮助弥合之间的差距 库存功能和您需要的东西。
最后,看看您是否无法使用附加属性扩展现有行为。
深入了解您的问题:
WPF Control Development Unleashed
更新&gt;&gt;&gt;
@MarqueIV,更直接地回答您的问题:为方便起见,我们提供了UserControl
课程。而已。如果将WPF CustomControl
添加到项目中,您将看到它没有XAML文件。这意味着您必须在Generic.xaml
文件夹中名为Themes
的文件中设计控制标记。 UserControl
类为我们提供了一个XAML文件,因此更容易创建它们......所以它更方便......就是这样。这就是原因。
答案 2 :(得分:3)
与ContentControl
不同的一点是,UserControl
会覆盖OnCreateAutomationPeer
方法,您可能会寻找它。也许它有一些不同于ContentControl
的UI行为。
答案 3 :(得分:1)
<强> ContentControl中强>
ContentControl直接派生自Control类
它托管一个单独的元素,可以是一个容器(例如Grid,Stackpanel,......),它自己托管几个元素(例如StackPanel with TextBlock和Image children)。
它的外观可以通过DataTemplate修改
请参阅MSDN Remarks section。
<强>用户控件强>
UserControl派生自ContentControl
它不支持模板,因此无需定制
它不像Window那样自动捕捉焦点
仍然在MSDN Remarks section。
答案 4 :(得分:0)
UserControl是一个复合控件。它与ASP.NET Webforms中的UserControl具有类似的概念。这意味着它是一个由许多控件组成的控件。在WPF中,创建用户控件支持Visual Studio 2008及更高版本中的设计器。 ContentControl是一个控件,旨在将单个控件作为其内容。
了解更多信息: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx
答案 5 :(得分:0)
UserControl和ContentControl可能是相同的实现,但用例不一样。
我们需要回答两个问题何时使用UserControl或CustomControl? 和何时使用ContentControl?。
所以何时使用UserControl或CustomControl? <
每当我想要一个可重用的UI 时
例如,如果我想让FileDialogBrowser意味着一个带有TextBlock的按钮,那么每当我按下按钮并且用户选择一个文件时,我将在TextBlock中显示所选文件。
相同但不完全适用于customControl但是在这里我们想做更复杂的事情,无论如何这不是问题。
所以何时使用ContentControl?
这说起来有点棘手,但让我们说我们想要一个带有消息的progressBar 所以我们可以继承BusyIndicator或Border,但是如果我们使用ContentControl,我们就可以控制它内部的内容。我们可以将它包裹在其他xaml元素周围。
希望这会有所帮助