应用程序样式设计全解析
立即解锁
发布时间: 2025-08-13 02:53:33 阅读量: 33 订阅数: 31 AIGC 

### 应用程序样式设计全解析
#### 1. 样式资源命名
在应用程序中,为样式资源命名是一个重要的环节。例如,你有一个 `TextBlock` 样式资源,希望让文本加粗、字体大小为 12 磅且颜色为海军蓝。那么该如何命名这个样式资源呢?可能的选择有 `TextBlockStyle`、`BoldNavy12ptStyle` 或者 `PageHeaderStyle / PageHeaderTextBlockStyle`。
从管理和视觉设计的角度来看,`PageHeaderStyle` 或 `PageHeaderTextBlockStyle` 是最佳的命名方式。这样的命名能让你在浏览样式资源定义时,轻松了解每个样式的用途。而且,如果你正在为应用程序设计新主题(或计划支持多个主题),这种命名方式更有意义,因为它将每个样式与用途关联起来,而非与屏幕上的渲染方式关联。
即便两个不同的样式资源定义具有完全相同的属性值(例如,都是 12 磅加粗海军蓝),通常还是将它们定义为单独的样式资源更好。这可能会导致多个样式包含相同的属性值,但能为未来的样式重新设计提供更好的支持。
#### 2. 样式资源继承
一个控件只能应用一个样式资源,这在设计样式资源时可能会让人觉得有些受限。例如,你可能希望在一个基础样式资源中定义一些属性值,这些属性值适用于给定类型的大多数或所有控件,然后再定义另一个样式资源,为该类型的部分控件添加额外的属性值(而无需在新样式资源中再次定义基础样式资源中已定义的相同属性值)。
虽然不能将这两个样式资源同时应用于一个控件,但可以让新的样式资源继承基础样式资源的属性值定义,从而达到相同的目的。这可以通过 `Style` 对象的 `BasedOn` 属性来实现,你可以为该属性分配对另一个样式资源的引用,使其作为基础样式。由于需要将其作为资源引用,因此需要使用 `StaticResource` 标记扩展。
以下是一个示例,假设我们有一个基础样式资源:
```xml
<Style x:Key="UserFieldsStyleBase" TargetType="TextBox">
<Setter Property="Margin" Value="2" />
<Setter Property="Background" Value="LemonChiffon" />
</Style>
```
当定义一个基于此基础样式资源的新样式资源时,可以使用 `BasedOn` 属性进行引用:
```xml
<Style x:Key="UserFieldsStyle" TargetType="TextBox"
BasedOn="{StaticResource UserFieldsStyleBase}">
<Setter Property="TextAlignment" Value="Right" />
</Style>
```
需要注意的是,一个样式资源只能基于一个样式,但该样式可以基于另一个样式,以此类推。
使用这种方法,不仅可以继承基础样式资源的属性值定义,还可以覆盖其中的一些属性值定义。例如,尽管基础样式资源中的 `Background` 属性值为 `LemonChiffon`,但在这个样式资源中,我们将其覆盖为 `White`:
```xml
<Style x:Key="UserFieldsStyle" TargetType="TextBox"
BasedOn="{StaticResource UserFieldsStyleBase}">
<Setter Property="Background" Value="White" />
</Style>
```
如果你有一个继承了属性值的样式资源,但希望在该资源中使用默认值,只需将其值设为 `null` 即可:
```xml
<Setter Property="Background" Value="{x:Null}" />
```
另外,继承样式资源的目标控件类型必须与新样式资源的目标控件类型匹配。例如,不能让针对 `TextBox` 控件的样式资源继承针对 `ComboBox` 控件的样式资源。不过,一个样式资源可以继承针对其基类的样式资源,例如,针对 `TextBox` 控件的样式资源可以继承针对 `Control` 类的样式资源。
#### 3. 样式定义的约束
在定义样式资源时,需要注意以下几个问题:
- **单一样式应用**:一个控件只能分配一个样式资源,若需要应用更多属性值,必须在控件定义中内联设置。
- **类型匹配**:样式资源不能应用于不同类型的控件。每个样式资源都有一个单一的控件类型,这意味着不能让 `TextBox` 和 `ComboBox` 控件引用同一个样式资源。虽然可以将目标类型设置为这两个控件的公共基类(如 `Control`),但通常会发现你想要定义值的属性在该基类中并不存在,从而导致项目无法编译。需要注意的是,尝试对隐式样式资源使用这种方法是行不通的。自动使用隐式样式的控件类型必须与样式资源的给定目标类型匹配,否则样式将不会应用。
- **隐式样式失效**:一旦为控件分配了样式资源,该控件原本可能使用的任何隐式样式将不再使用。
#### 4. 控件模板
前面我们了解了如何定义样式资源并将其应用于控件,但如果想要完全改变控件的外观,包括控件未作为属性公开的元素的外观或功能,该怎么办呢?在 Silverlight 中,可以通过为控件应用替代的控件模板来实现这一点。
Silverlight 自定义控件的结构鼓励将表现和行为分离。控件的行为应在代码中定义,而其外观应在控件模板中定义。两者之间有一个契约,定义了代码需要从表现层访问的内容。通过这种清晰的关注点分离,只要遵守控件的行为/表现契约,就可以完全修改控件的外观而不影响其行为。这是 XAML 的一个强大功能,充分展示了其在定义用户界面时的灵活性。
需要注意的是,样式可以让你简单地为控件分配属性值,而控件模板可以让你直接修改控件的核心 XAML。
#### 5. 默认控件模板
默认的控件模板(和样式)定义在包含控件的项目或程序集的 `Themes` 文件夹中的 `Generic.xaml` 文件中。该文件中每个控件模板都有自己的资源字典。当你想为控件应用自己的替代自定义控件模板时,最简单的方法是先复制该控件的默认控件模板,然后在此基础上进行修改。
提取默认控件模板的最简单方法是使用 Expression Blend。它会从控件程序集的 `Generic.xaml` 文件中提取该控件的模板,并根据你的选择将其作为新资源放置在用户控件或应用程序的资源中。然后,你可以根据需要更改这个控件模板资源,如移动元素、添加额外的控件元素、删除元素和重新设置元素样式,但要保留控件本身引用的模板部分和状态。
如果不使用 Expression Blend,获取现有控件模板的唯一方法是按以下步骤操作:
1. 打开包含你要修改的控件的程序集的 `Generic.xaml` 文件。如果你没有该控件的源代码,则需要使用 Reflector 打开程序集并从中提取 `Generic.xaml` 文件。
2. 找到与该控件相关的样式资源/控件模板,并将其复制到你的项目中作为新的样式资源/控件模板。
3. 将新的样式资源/控件模板分配给你的控件。
可以看出,这是一个有些繁琐和复杂的过程,而 Expression Blend 有助于简化和优化这个过程。
#### 6. 控件模板化
要使用 Expression Blend 复制控件的默认模板(以便进行编辑),在设计视图中右键单击控件,然后选择“编辑控件部件(模板)” -> “编辑副本”。这将自动执行前面提到的过程,并使文件准备好供你进行所需的修改(你可以通过 Blend 设计视图直观地进行修改,也可以手动修改 XAML)。
需要注意的是,尽管该功能的名称如
0
0
复制全文
相关推荐









