样式与资源 #

资源概述 #

什么是资源? #

资源是可以在应用中复用的对象,包括颜色、字体、样式、模板、转换器等。

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