wpf UserControl 和 ContentControl 之间有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18781679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference betwen a UserControl and a ContentControl?
提问by Mark A. Donohoe
According to all of the documentation, when you're creating a non-lookless control, you're supposed to subclass UserControl. However, UserControlis a simple subclass of ContentControlbut 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 ContentControland it appears to still work exactly the same.
根据所有文档,当您创建非外观控件时,您应该将UserControl. 然而,UserControl是一个简单的子类,ContentControl但它似乎没有向接口添加任何内容。因此,您可以使用设计器生成的代码并将基类更改为ContentControl,它看起来仍然完全相同。
So what's the point of UserControlover ContentControl?
那么什么是点UserControl了ContentControl?
Update:
更新:
For those who keep answering Visual Studio treats them differently, I'd argue that isn't the case. Try it! Create a new UserControlin 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 ContentControlor 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.
对于那些不断回答 Visual Studio 对待他们的人来说,我认为事实并非如此。尝试一下!UserControl在 Visual Studio 中新建一个,然后在生成的 XAML 文件中,将根标记更改为ContentControl. 然后在关联的类文件中,将基类更改为ContentControl或简单地将其删除,就像我在此处所做的那样(请参阅注释),您将看到它的工作方式完全相同,包括完整的 WYSIWYG 设计器支持。
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.
注意:您可以从代码隐藏中删除基类,因为它实际上是一个分部类,该类的另一个“部分”是由 XAML 设计器通过代码生成创建的。因此,基类将始终定义为 XAML 文件的根元素,因此您可以简单地在代码隐藏中省略它,因为它是多余的。
Here's the updated XAML...
这是更新的 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();
}
}
回答by Adam Caviness
UserControls are a good fit for aggregating existing controlswhen 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:
当您不需要为使用者提供 ControlTemplate 时,UserControls 非常适合聚合现有控件。这意味着UserControls 并非无懈可击。为什么不直接使用 ContentControl,因为它可以像 UserControl 一样耦合 XAML,并且实现看起来类似于 UserControl?好吧,您必须了解几个重要的技术差异:
- UserControls set themselves as the source to RoutedEventsraised by elements within them. This means that when an element outside the UserControl receives a bubbled event, the Source is the UserControl, not the thing you interacted withinthe UserControl. In the philosophical sense of what you often hear about UserControls, "It's for aggregating existing controls", this makes sense as you want the parent container element to think of your UserControl as a single unit. For example, your UserControl contains a button that the user clicks and the Grid that contains your UserControl instance receives the MouseLeftButtonUp event but the Button is not the Source of the event, your UserControl is.
- UserControl sets Focusable and IsTabStop to false. You can see the philosophy demonstrating itself again here as we don't want a grouping of existing controls to be Focusable.
- UserControl sets HorizontalAlignment and VerticalAlignment to Stretch. A ContentControl would automatically be set to Left and Top.
- UserControl's own AutomationPeer implementationallows you to change VisualStates via
VisualStateManager.GoToState(). ContentControl requires the VisualStateGroups to be at the top-level and you must call them withVisualStateManager.GoToElementState(). - UserControl's own ControlTemplate wraps your content in a Border. This again makes sense when thinking of the philosophical use case for UserControl.
- UserControl's own ControlTemplate provides more TemplateBindingsthan ContentControl. This is kind of a recapitulation of some above items but explains how they are possible. Recall that UserControl provides a Border so that relates to some of these free TemplateBindings you see below. This enables respect for BorderBrush, BorderThickness, Background and Padding properties on your control that would otherwise not work with just a ContentControl. For example, if you just derive your control from ContentControl and set the Background property on the root ContentControl element it will not work because the ControlTemplate of ContentControl has no TemplateBinding for Background. Of course you could set the Background property on the child content element that wraps your desired elements, like a Grid, but that isn't ideal IMO.
- UserControls 将自己设置为由其中的元素引发的RoutedEvents 的源。这意味着当 UserControl 外部的元素接收到冒泡事件时,Source 是 UserControl,而不是您在UserControl内交互的东西。从您经常听到的关于 UserControl 的哲学意义上来说,“它用于聚合现有控件”,这是有道理的,因为您希望父容器元素将您的 UserControl 视为一个单元。例如,您的 UserControl 包含一个用户单击的按钮,并且包含您的 UserControl 实例的 Grid 接收 MouseLeftButtonUp 事件,但该 Button 不是事件的源,您的 UserControl 是。
- UserControl 将 Focusable 和 IsTabStop 设置为 false。您可以在此处再次看到这一理念,因为我们不希望现有控件的分组成为可聚焦的。
- UserControl 将 HorizontalAlignment 和 VerticalAlignment 设置为 Stretch。ContentControl 将自动设置为 Left 和 Top。
- UserControl 自己的AutomationPeer 实现允许您通过
VisualStateManager.GoToState(). ContentControl 要求 VisualStateGroups 位于顶级,并且您必须使用VisualStateManager.GoToElementState(). - UserControl 自己的 ControlTemplate 将您的内容包装在 Border 中。当考虑 UserControl 的哲学用例时,这再次有意义。
- UserControl 自己的 ControlTemplate 提供了比 ContentControl更多的 TemplateBinding。这是对上述一些项目的概括,但解释了它们是如何实现的。回想一下,UserControl 提供了一个 Border,以便与您在下面看到的这些免费 TemplateBindings 中的一些相关。这允许尊重控件上的 BorderBrush、BorderThickness、Background 和 Padding 属性,否则这些属性将无法仅与 ContentControl 一起使用。例如,如果您只是从 ContentControl 派生控件并在根 ContentControl 元素上设置 Background 属性,则它不会起作用,因为 ContentControl 的 ControlTemplate 没有用于背景的 TemplateBinding。当然,您可以在包装所需元素的子内容元素(如网格)上设置 Background 属性,但这不是理想的 IMO。
ContentControl's ControlTemplate
ContentControl 的 ControlTemplate
<ControlTemplate TargetType="ContentControl">
<ContentPresenter
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" />
</ControlTemplate>
UserControl's 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>
回答by Sheridan
Basically, the UserControlclass is there for convenience. It enables us to build little parts of the UI from already existing controls, whereas ContentControls are really for creating new controls, generally with a single purpose and/or functionality.
基本上,这个UserControl类是为了方便而存在的。它使我们能够从现有控件构建 UI 的一小部分,而ContentControls 实际上用于创建新控件,通常具有单一目的和/或功能。
I read a book that had a good explanation of this and by good luck, someone has 'put a copy of it online'. From the linked book:
我读了一本书,对此有很好的解释,幸运的是,有人“把它的副本放到了网上”。从链接的书中:
The UserControl class is a container class that acts as a “black box” container for a collection of related controls. If you need a set of three controls to always appear together and be allowed to easily talk to each other, then a likely candidate for making that happen is the UserControl class.
UserControl 类是一个容器类,它充当相关控件集合的“黑匣子”容器。如果您需要一组三个控件总是一起出现并允许彼此轻松交谈,那么实现这一点的可能候选者是 UserControl 类。
Then relating to whether to create a CustomControl:
然后关于是否创建一个CustomControl:
The following is a summary of the decision process:
Use the framework as much as possible. WPF provides a variety of extensible controls, so make sure that the functionality you want doesn't already exist in a WPF control.
In many cases, the data structure you're working with requires different visual representation. Using ControlTemplates and DataTemplates can often get you the functionality you need.
Look at ValueConverters to see whether they can help bridge the gap between the stock functionality and what you need.
Finally, see whether you can't extend existing behavior with attached properties.
以下是决策过程的摘要:
尽量使用框架。WPF 提供了各种可扩展控件,因此请确保 WPF 控件中不存在所需的功能。
在许多情况下,您使用的数据结构需要不同的视觉表示。使用 ControlTemplates 和 DataTemplates 通常可以获得所需的功能。
查看 ValueConverters,看看它们是否可以帮助弥合库存功能与您需要的功能之间的差距。
最后,看看您是否不能使用附加属性扩展现有行为。
Take a look for an in depth answer to your question:
看看你的问题的深入答案:
WPF Control Development Unleashed
UPDATE >>>
更新 >>>
@MarqueIV, to answer your question more directly: The UserControlclass is provided to us for convenience. That's it. If you add a WPF CustomControlinto your project, you will see that it has no XAML file. This means that you have to design you control markup in a file called Generic.xamlin the Themesfolder. The UserControlclass gives us a XAML file so that it is easier to create them... so it is more convenient... that's it. That's the reason.
@MarqueIV,更直接地回答您的问题:UserControl为方便起见,我们提供了该课程。就是这样。如果将 WPF 添加CustomControl到项目中,您将看到它没有 XAML 文件。这意味着您必须在文件夹中调用Generic.xaml的Themes文件中设计控制标记。该UserControl班给了我们一个XAML文件,以便更容易创建它们...所以它更方便......就是这样。这就是原因。
回答by Florian Gl
One thing that is different from ContentControlis that UserControloverrides the OnCreateAutomationPeermethod, you might look for that. Maybe it has some different UI-behaviors than the ContentControl.
ContentControl与UserControl覆盖OnCreateAutomationPeer方法不同的一件事是,您可能会寻找它。也许它有一些与ContentControl.
This method creates an UserControlAutomationPeer-instance.
回答by leguminator
ContentControl
A ContentControl directly derives from Control class.
It hosts a single element which can be a container (eg Grid, Stackpanel, ...) hosting itself several elements (eg StackPanel with TextBlock and Image children).
Its appearance can be modified through a DataTemplate.
See MSDN Remarks section.
ContentControl
ContentControl 直接派生自 Control 类。
它承载一个元素,该元素可以是一个容器(例如 Grid、Stackpanel 等),它承载着多个元素(例如带有 TextBlock 和 Image 子项的 StackPanel)。
它的外观可以通过 DataTemplate 修改。
请参阅MSDN 备注部分。
UserControl
A UserControl derives from ContentControl.
It does NOT support templates, thus no customization.
It does not catch focus automatically like a Window would.
Still in the MSDN Remarks section.
UserControl
UserControl 派生自 ContentControl。
它不支持模板,因此没有自定义。
它不会像 Window 那样自动捕捉焦点。
仍在MSDN 备注部分。
回答by Gilad
UserControl and ContentControl maybe the same implementation but the use case are not the same.
UserControl 和 ContentControl 可能是相同的实现,但用例并不相同。
we need to answer two questions when to use UserControl or CustomControl?and when to use ContentControl?.
我们需要回答两个问题,什么时候使用 UserControl 或 CustomControl?而当使用ContentControl中?.
so when to use a UserControl or CustomControl?
Whenever I want to have a reusable piece of UI
for example if I want to have a FileDialogBrowser meaning a button with a TextBlock next to it so whenever i press the button and a user chooses a file i will show the chosen file in the TextBlock.
那么什么时候使用 UserControl 或 CustomControl 呢?
每当我想要一个可重用的 UI 时
,例如,如果我想要一个 FileDialogBrowser 意味着旁边有一个 TextBlock 的按钮,那么每当我按下按钮并且用户选择一个文件时,我将在 TextBlock 中显示所选文件。
same but not exactly goes for customControl however here we want to do something more sophisticated, anyway this is not the issue.
相同但不完全适用于 customControl 但是在这里我们想做一些更复杂的事情,无论如何这不是问题。
so when to use ContentControl?
那么什么时候使用ContentControl呢?
this is a little tricky to say but let's say we want to have progressBar with a message so we can inherit from BusyIndicator or Border, however if we use a ContentControl we have control which can Control the content inside it. we can have it wrapping around other xaml elements.
说起来有点棘手,但假设我们希望progressBar 带有一条消息,因此我们可以从BusyIndicator 或Border 继承,但是如果我们使用ContentControl,我们就可以控制其中的内容。我们可以让它环绕其他 xaml 元素。
hope this helps
希望这可以帮助
回答by Eriawan Kusumawardhono
UserControl is a composite control. It has similar concept with UserControl in ASP.NET Webforms. This means it's a control that is composed from many controls. In WPF, creating user control has supports for designer in Visual Studio 2008 and above. ContentControl is a control that is intended to have a single control as its content.
UserControl 是一个复合控件。它与 ASP.NET Webforms 中的 UserControl 具有相似的概念。这意味着它是一个由许多控件组成的控件。在 WPF 中,创建用户控件支持 Visual Studio 2008 及更高版本的设计器。ContentControl 是一个旨在将单个控件作为其内容的控件。
For more information: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx
更多信息:http: //msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx

