样式与资源 #
资源概述 #
什么是资源? #
资源是可以在应用中复用的对象,包括颜色、字体、样式、模板、转换器等。
text
┌─────────────────────────────────────────────────────────────┐
│ 资源类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ├── 颜色 (Color) │
│ │ - 主题色、背景色、文字颜色 │
│ │ │
│ ├── 字体 (Font) │
│ │ - 字体大小、字体族、字体属性 │
│ │ │
│ ├── 样式 (Style) │
│ │ - 控件外观、布局属性 │
│ │ │
│ ├── 数据模板 (DataTemplate) │
│ │ - 列表项模板、内容模板 │
│ │ │
│ ├── 控件模板 (ControlTemplate) │
│ │ - 控件结构定义 │
│ │ │
│ └── 值转换器 (IValueConverter) │
│ - 数据转换逻辑 │
│ │
└─────────────────────────────────────────────────────────────┘
资源字典 #
text
┌─────────────────────────────────────────────────────────────┐
│ 资源字典层级 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Application.Resources (全局) │
│ │ │
│ └── ContentPage.Resources (页面级) │
│ │ │
│ └── StackLayout.Resources (控件级) │
│ │
│ 查找顺序:控件级 → 页面级 → 全局 │
│ │
└─────────────────────────────────────────────────────────────┘
定义资源 #
页面级资源 #
xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="PrimaryColor">#2196F3</Color>
<Color x:Key="SecondaryColor">#FF9800</Color>
<Color x:Key="BackgroundColor">#FAFAFA</Color>
<Color x:Key="TextColor">#212121</Color>
<x:Double x:Key="TitleFontSize">24</x:Double>
<x:Double x:Key="BodyFontSize">16</x:Double>
<x:Double x:Key="CaptionFontSize">12</x:Double>
<OnPlatform x:Key="TitleFontFamily"
x:TypeArguments="x:String">
<On Platform="iOS" Value="SF Pro Display" />
<On Platform="Android" Value="Roboto" />
</OnPlatform>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout BackgroundColor="{StaticResource BackgroundColor}">
<Label Text="标题"
FontSize="{StaticResource TitleFontSize}"
FontFamily="{StaticResource TitleFontFamily}"
TextColor="{StaticResource PrimaryColor}" />
</StackLayout>
</ContentPage>
应用级资源 #
xml
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.App">
<Application.Resources>
<ResourceDictionary>
<Color x:Key="PrimaryColor">#2196F3</Color>
<Color x:Key="SecondaryColor">#FF9800</Color>
<Color x:Key="AccentColor">#E91E63</Color>
<Color x:Key="TextPrimaryColor">#212121</Color>
<Color x:Key="TextSecondaryColor">#757575</Color>
<Color x:Key="TextAccentColor">#FFFFFF</Color>
<Color x:Key="BackgroundColor">#FAFAFA</Color>
<Color x:Key="SurfaceColor">#FFFFFF</Color>
<Color x:Key="DividerColor">#BDBDBD</Color>
</ResourceDictionary>
</Application.Resources>
</Application>
外部资源字典文件 #
xml
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Styles.Colors">
<Color x:Key="PrimaryColor">#2196F3</Color>
<Color x:Key="SecondaryColor">#FF9800</Color>
<Color x:Key="AccentColor">#E91E63</Color>
</ResourceDictionary>
xml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/Colors.xaml" />
<ResourceDictionary Source="Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
使用资源 #
StaticResource #
xml
<Label Text="Hello"
TextColor="{StaticResource PrimaryColor}"
FontSize="{StaticResource TitleFontSize}" />
DynamicResource #
xml
<Label Text="Hello"
TextColor="{DynamicResource PrimaryColor}" />
csharp
public partial class App : Application
{
public App()
{
InitializeComponent();
Current.Resources["PrimaryColor"] = Color.FromHex("#4CAF50");
}
}
代码中使用资源 #
csharp
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var primaryColor = (Color)Application.Current.Resources["PrimaryColor"];
var titleFontSize = (double)Resources["TitleFontSize"];
myLabel.TextColor = primaryColor;
myLabel.FontSize = titleFontSize;
}
}
样式定义 #
基本样式 #
xml
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="LabelTitleStyle" TargetType="Label">
<Setter Property="FontSize" Value="24" />
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="TextColor" Value="{StaticResource PrimaryColor}" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
<Style x:Key="LabelBodyStyle" TargetType="Label">
<Setter Property="FontSize" Value="16" />
<Setter Property="TextColor" Value="{StaticResource TextPrimaryColor}" />
<Setter Property="LineBreakMode" Value="WordWrap" />
</Style>
<Style x:Key="ButtonPrimaryStyle" TargetType="Button">
<Setter Property="BackgroundColor" Value="{StaticResource PrimaryColor}" />
<Setter Property="TextColor" Value="White" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Padding" Value="20,12" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Label Text="标题" Style="{StaticResource LabelTitleStyle}" />
<Label Text="正文内容" Style="{StaticResource LabelBodyStyle}" />
<Button Text="提交" Style="{StaticResource ButtonPrimaryStyle}" />
</StackLayout>
隐式样式 #
xml
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Label">
<Setter Property="FontSize" Value="16" />
<Setter Property="TextColor" Value="{StaticResource TextPrimaryColor}" />
</Style>
<Style TargetType="Button">
<Setter Property="BackgroundColor" Value="{StaticResource PrimaryColor}" />
<Setter Property="TextColor" Value="White" />
<Setter Property="CornerRadius" Value="8" />
</Style>
<Style TargetType="Entry">
<Setter Property="PlaceholderColor" Value="Gray" />
<Setter Property="TextColor" Value="{StaticResource TextPrimaryColor}" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Label Text="自动应用样式" />
<Entry Placeholder="输入内容" />
<Button Text="提交" />
</StackLayout>
样式继承 #
xml
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="LabelBaseStyle" TargetType="Label">
<Setter Property="FontSize" Value="16" />
<Setter Property="TextColor" Value="Black" />
</Style>
<Style x:Key="LabelTitleStyle" TargetType="Label"
BasedOn="{StaticResource LabelBaseStyle}">
<Setter Property="FontSize" Value="24" />
<Setter Property="FontAttributes" Value="Bold" />
</Style>
<Style x:Key="LabelSubtitleStyle" TargetType="Label"
BasedOn="{StaticResource LabelBaseStyle}">
<Setter Property="FontSize" Value="14" />
<Setter Property="TextColor" Value="Gray" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
样式类 #
xml
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="Visual" TargetType="VisualElement">
<Setter Property="BackgroundColor" Value="White" />
</Style>
<Style x:Key="ButtonBase" TargetType="Button"
Class="ButtonStyle">
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Padding" Value="20,12" />
</Style>
<Style x:Key="ButtonPrimary" TargetType="Button"
Class="ButtonStyle"
BasedOn="{StaticResource ButtonBase}">
<Setter Property="BackgroundColor" Value="#2196F3" />
<Setter Property="TextColor" Value="White" />
</Style>
<Style x:Key="ButtonSecondary" TargetType="Button"
Class="ButtonStyle"
BasedOn="{StaticResource ButtonBase}">
<Setter Property="BackgroundColor" Value="#757575" />
<Setter Property="TextColor" Value="White" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<Button Text="主要按钮" StyleClass="ButtonStyle" />
视觉状态管理器 #
VisualStateManager 概述 #
text
┌─────────────────────────────────────────────────────────────┐
│ 视觉状态 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 常见状态: │
│ ├── Normal - 正常状态 │
│ ├── Disabled - 禁用状态 │
│ ├── Focused - 获得焦点 │
│ ├── Selected - 选中状态 │
│ └── Pressed - 按下状态 │
│ │
│ 状态组: │
│ ├── CommonStates (Normal, Disabled, Focused, Selected) │
│ └── CheckedStates (Checked, Unchecked) │
│ │
└─────────────────────────────────────────────────────────────┘
定义视觉状态 #
xml
<ContentPage.Resources>
<Style TargetType="Button">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="#2196F3" />
<Setter Property="TextColor" Value="White" />
<Setter Property="Scale" Value="1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="#1976D2" />
<Setter Property="Scale" Value="0.95" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="#BDBDBD" />
<Setter Property="TextColor" Value="#9E9E9E" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
Entry 视觉状态 #
xml
<Style TargetType="Entry">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="PlaceholderColor" Value="#9E9E9E" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="PlaceholderColor" Value="#2196F3" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="PlaceholderColor" Value="#BDBDBD" />
<Setter Property="TextColor" Value="#BDBDBD" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
自定义视觉状态 #
csharp
public class CustomButton : Button
{
public static readonly BindableProperty IsHighlightedProperty =
BindableProperty.Create(nameof(IsHighlighted), typeof(bool), typeof(CustomButton), false);
public bool IsHighlighted
{
get => (bool)GetValue(IsHighlightedProperty);
set => SetValue(IsHighlightedProperty, value);
}
}
xml
<local:CustomButton Text="Custom Button">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CustomStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="#2196F3" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Highlighted">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="#FF9800" />
<Setter Property="Scale" Value="1.1" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
</local:CustomButton>
csharp
private void UpdateVisualState()
{
if (IsHighlighted)
{
VisualStateManager.GoToState(this, "Highlighted");
}
else
{
VisualStateManager.GoToState(this, "Normal");
}
}
主题定制 #
深色/浅色主题 #
xml
<Application.Resources>
<ResourceDictionary>
<Color x:Key="PageBackgroundColor">White</Color>
<Color x:Key="NavigationBarColor">#2196F3</Color>
<Color x:Key="PrimaryColor">#2196F3</Color>
<Color x:Key="SecondaryColor">#FF9800</Color>
<Color x:Key="TextColor">#212121</Color>
<Color x:Key="SecondaryTextColor">#757575</Color>
</ResourceDictionary>
</Application.Resources>
xml
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Themes.DarkTheme">
<Color x:Key="PageBackgroundColor">#121212</Color>
<Color x:Key="NavigationBarColor">#1F1F1F</Color>
<Color x:Key="PrimaryColor">#BB86FC</Color>
<Color x:Key="SecondaryColor">#03DAC6</Color>
<Color x:Key="TextColor">#FFFFFF</Color>
<Color x:Key="SecondaryTextColor">#B0B0B0</Color>
</ResourceDictionary>
csharp
public partial class App : Application
{
public App()
{
InitializeComponent();
SetTheme(AppTheme.Light);
}
public void SetTheme(AppTheme theme)
{
var mergedDictionaries = Current.Resources.MergedDictionaries;
mergedDictionaries.Clear();
switch (theme)
{
case AppTheme.Dark:
mergedDictionaries.Add(new DarkTheme());
break;
default:
mergedDictionaries.Add(new LightTheme());
break;
}
}
}
public enum AppTheme
{
Light,
Dark
}
响应系统主题 #
csharp
public partial class App : Application
{
public App()
{
InitializeComponent();
Application.Current.RequestedThemeChanged += OnRequestedThemeChanged;
}
private void OnRequestedThemeChanged(object sender, AppThemeChangedEventArgs e)
{
SetTheme(e.RequestedTheme == OSAppTheme.Dark ? AppTheme.Dark : AppTheme.Light);
}
}
使用 DynamicResource #
xml
<ContentPage BackgroundColor="{DynamicResource PageBackgroundColor}">
<StackLayout>
<Label Text="标题"
TextColor="{DynamicResource PrimaryColor}" />
<Label Text="正文内容"
TextColor="{DynamicResource TextColor}" />
</StackLayout>
</ContentPage>
控件模板 #
定义控件模板 #
xml
<ControlTemplate x:Key="CardViewControlTemplate">
<Frame BindingContext="{Binding Source={RelativeSource TemplatedParent}}"
BackgroundColor="White"
CornerRadius="10"
HasShadow="True"
Padding="0">
<Grid RowDefinitions="Auto, *">
<BoxView Grid.Row="0"
Color="{Binding CardColor}"
HeightRequest="150" />
<Label Grid.Row="0"
Text="{Binding Title}"
FontSize="20"
FontAttributes="Bold"
TextColor="White"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Grid.Row="1"
Text="{Binding Description}"
FontSize="14"
TextColor="Gray"
Padding="15" />
</Grid>
</Frame>
</ControlTemplate>
使用控件模板 #
xml
<ContentView ControlTemplate="{StaticResource CardViewControlTemplate}">
<local:CardViewModel Title="卡片标题"
Description="卡片描述内容"
CardColor="#2196F3" />
</ContentView>
ContentPresenter #
xml
<ControlTemplate x:Key="PageTemplate">
<Grid RowDefinitions="Auto, *, Auto">
<Label Grid.Row="0"
Text="{Binding Title}"
FontSize="20"
FontAttributes="Bold"
Padding="15" />
<ContentPresenter Grid.Row="1" />
<Button Grid.Row="2"
Text="确定"
Command="{Binding ConfirmCommand}"
Margin="15" />
</Grid>
</ControlTemplate>
xml
<ContentPage ControlTemplate="{StaticResource PageTemplate}">
<StackLayout>
<Label Text="页面内容" />
</StackLayout>
</ContentPage>
样式最佳实践 #
1. 组织资源文件 #
text
Resources/
├── Colors.xaml # 颜色定义
├── Fonts.xaml # 字体定义
├── Sizes.xaml # 尺寸定义
├── Styles.xaml # 样式定义
└── Themes/
├── LightTheme.xaml
└── DarkTheme.xaml
2. 使用命名约定 #
xml
<Color x:Key="ColorPrimary">#2196F3</Color>
<Color x:Key="ColorSecondary">#FF9800</Color>
<Color x:Key="ColorAccent">#E91E63</Color>
<Color x:Key="ColorTextPrimary">#212121</Color>
<Color x:Key="ColorTextSecondary">#757575</Color>
<Color x:Key="ColorBackground">#FAFAFA</Color>
<Color x:Key="ColorSurface">#FFFFFF</Color>
<x:Double x:Key="FontSizeTitle">24</x:Double>
<x:Double x:Key="FontSizeBody">16</x:Double>
<x:Double x:Key="FontSizeCaption">12</x:Double>
<Style x:Key="StyleLabelTitle" TargetType="Label">
<Setter Property="FontSize" Value="{StaticResource FontSizeTitle}" />
</Style>
<Style x:Key="StyleButtonPrimary" TargetType="Button">
<Setter Property="BackgroundColor" Value="{StaticResource ColorPrimary}" />
</Style>
3. 避免硬编码 #
xml
<Style x:Key="BadStyle" TargetType="Label">
<Setter Property="TextColor" Value="#2196F3" />
<Setter Property="FontSize" Value="16" />
</Style>
<Style x:Key="GoodStyle" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource ColorPrimary}" />
<Setter Property="FontSize" Value="{StaticResource FontSizeBody}" />
</Style>
下一步 #
现在你已经掌握了样式与资源管理,接下来学习 平台特性,了解如何调用平台特定功能!
最后更新:2026-03-29