gpt4 book ai didi

c# - 了解 XAML/WPF 中的样式和模板

转载 作者:行者123 更新时间:2023-11-30 23:31:09 27 4
gpt4 key购买 nike

我将从代码开始。这是简单的按钮:

<Grid>
<Button Height="20" Width="100"
Background="Brown"
BorderBrush="Blue"
Foreground="Aqua">Test button</Button>
</Grid>

我在Button 控件中设置了Background、BorderBrush 和Foreground。

下面我有一个代码,结果完全一样,但是定义了样式和模板:

<Window.Resources>
<Style TargetType="Button">
<Setter Property="Content" Value="foo"></Setter>
<Setter Property="BorderBrush" Value="Blue"></Setter>
<Setter Property="Background" Value="Brown"></Setter>
<Setter Property="Foreground" Value="Aqua"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">

<ContentPresenter Content="{TemplateBinding Content}"></ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Height="20" Width="100">
Test button
</Button>
</Grid>

这是让我感到困惑的地方:

  1. 我声明样式和模板,然后声明 ControlTemplate , 然后里面ControlTemplate我声明Border然后... Background里面Border标签。为什么?它是按钮内容的背景——与边框无关。这对我来说没有意义。

  2. 更奇怪的是,现在我想为 Button 设置的每个属性(例如背景)都必须为 Button 的边框设置。甚至按钮的内容。为什么 ContentPresenter必须在里面 Border ?

顺便说一句。如果我放弃边框而只想要内容,那么这是正确的:

<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}"></ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>

所以,我的问题是:为什么在声明模板时我必须设置 Background按钮内部按钮的 Border

此示例带有 Button这只是一个例子。更一般的答案/解释会很棒!

最佳答案

当您覆盖 Control 的模板时喜欢Button您基本上可以控制 Control 的整体外观和感觉.您正在替换 Control 的可视化树.

所以当你把 Button在您的应用程序中,它将包含在其 ControlTemplate 中找到的子树.

这可以在 Visual Studio 2015 的实时可视化树 Pane 或 Snoop 中观察到:

Visual Tree of default Button

ButtonContentControl ,这意味着它的 ContentPropertyAttribute设置为 "Content" . ContentPresenterContentControlControlTemplate会捡起你放在 ContentControl 里的任何东西的 Content属性(在你的情况下,你甚至不需要 TemplateBindingContentPresenterContent)。如果您使用简单的字符串 Content喜欢<Button Content="Whatever" />它将被转换为 <TextBlock Text="Whatever" /> ,因此图片中可视化树中的 TextBlock。

在示例中,您提供了 Border元素用于让用户能够为 Button 设置背景。 .因为ContentPresenter没有 Background您必须将其包装在 Border 中的属性元素并设置 BackgroundBorder 上.

我觉得名字Border可能会让人感到困惑,它并不总是严格用于渲染边框(尽管在本例中,它也用于渲染边框和 Background)。

我希望这有点道理,如果您还有其他问题,请随时提问。

关于c# - 了解 XAML/WPF 中的样式和模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34708452/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com