WPF的外观是从哪里来的?

5
我刚读了Thomas Claudius Huber关于WPF的书。他说,所有WPF控件都是"无外观"的。它们只是从它们的ControlTemplate获取它们的外观(和可视树)。这引出了一个问题:WPF的外观来自哪里? 我的意思是:Button有一个带有一些BorderContentPresenterControlTemplate。这两个(BorderContentPresenter)的外观来自哪里?
我已经谷歌搜索并发现,Border是一个Decorator,并在OnRender方法中设置其外观。
这是底线吗?所有其他没有ControlTemplate的元素是否在OnRender方法中定义其外观?
1个回答

7
简短回答:是的。所有非控件且具有“外观”的可视元素都在其UIElement.OnRender方法重写中定义了该外观。
详细回答:控件不使用OnRender方法来定义其外观。相反,它们的“外观”是在样式和模板中定义的。当应用程序中没有显式定义样式或模板时,WPF控件仅使用当前系统主题(有关主题的更多信息,请查看此MSDN文章)中默认的样式和模板。
可以说,框架具有自己的资源字典,其中包含所有内置控件的默认样式。例如,这是ComboBox的默认ControlTemplate:ComboBox Styles and Templates
那么,有几个视觉组件是通过代码定义其外观的,通常是通过OnRender重写。它们不是控件;它们是装饰器形状等等。这些东西有一个“外观”:边框、矩形等等。但最终,所有控件都有外观,因为所有ControlTemplates都由这些元素或其他控件组成。 、、和其他类似元素都是专门用于文本渲染的特殊元素。它们属于与形状或装饰器类似的类别,只是它们专门处理文本而不是图形。例如,TextBlock不是控件,并在其OnRender方法中定义其外观。另一方面,Label是一个控件;但如果您检查其模板,您将看到它最终使用TextBlock来显示文本。

还有其他元素(如ContentPresenterItemsPresenter),它们没有任何外观,不是默认的,也不是通过样式或模板隐式设置。这些是逻辑元素,定义了视图的结构。例如,ContentPresenter获取ContentControl的Content和ContentTemplate属性,并确保所述模板正确呈现并绑定到所述数据,可以这么说。但它们本身没有视觉表示。

哦,我差点忘了Panels。面板也不是控件,它们有自己的外观。但类似于Presenters,它们也是定义其他可视元素如何可视化的逻辑元素。更具体地说,是它们的布局。


2
这是正确的。事实上,您可以通过将任何控件的 "OverridesDefaultStyle" 属性设置为 "true" 来证明这一点。该控件将在视觉上消失,因为它现在没有应用默认的 "外观" 或 "样式"。 - olitee
从它的源代码(http://www.dotnetframework.org/default.aspx/Net/Net/3@5@50727@3053/DEVDIV/depot/DevDiv/releases/Orcas/SP/wpf/src/Framework/System/Windows/Controls/TextBlock@cs/1/TextBlock@cs)来看,我认为是的:在这种情况下,`OnRender`方法也执行了视觉工作。 - almulo
1
简短回答:是的,OnRender 是所有 UIElement 的唯一方式,包括 Controls、Shapes、Decorators、Panels、TextBlock 等等。 - almulo
所以在你的回答中,你说“不”,而在上一条评论中你说“是”。只要存在这种差异,我无法接受你的回答。也许如果你把你的评论添加到你的答案中会更有帮助。 - Rico-E
完成。我认为这是关于WPF可视元素的一个很好的摘要。 - almulo
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接