为跨平台 Xamarin.Forms 应用程序设置样式

在本快速入门中,你将了解如何:

  • 使用 XAML 样式为 Xamarin.Forms Shell 应用程序设置样式。
  • 使用 XAML 热重载查看 UI 更改,无需重新生成应用程序。

本快速入门演练如何使用 XAML 样式为跨平台 Xamarin.Forms 应用程序设置样式。 此外,快速入门使用 XAML 热重载更新正在运行的应用程序的 UI,无需重新生成应用程序。 有关 XAML 热重载的详细信息,请参阅 Xamarin.Forms 的 XAML 热重载

最终的应用程序如下所示:

Notes 页面Note 输入页面“关于”页面

先决条件

在尝试本快速入门之前,应成功完成上一个快速入门

使用 Visual Studio 更新应用

  1. 启动 Visual Studio 并打开 Notes 解决方案。

  2. 在所选平台上生成并运行项目。 有关详细信息,请参阅生成快速入门

    让应用程序保持运行并返回到 Visual Studio。

  3. 在“解决方案资源管理器”的“Notes”项目中,打开“App.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="utf-8" ?>
    <Application xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.App">
    
        <!-- Resources used by multiple pages in the application -->         
        <Application.Resources>
    
            <Thickness x:Key="PageMargin">20</Thickness>
    
            <!-- Colors -->
            <Color x:Key="AppPrimaryColor">#1976D2</Color>
            <Color x:Key="AppBackgroundColor">AliceBlue</Color>
            <Color x:Key="PrimaryColor">Black</Color>
            <Color x:Key="SecondaryColor">White</Color>
            <Color x:Key="TertiaryColor">Silver</Color>
    
            <!-- Implicit styles -->
            <Style TargetType="ContentPage"
                   ApplyToDerivedTypes="True">
                <Setter Property="BackgroundColor"
                        Value="{StaticResource AppBackgroundColor}" />
            </Style>
    
            <Style TargetType="Button">
                <Setter Property="FontSize"
                        Value="Medium" />
                <Setter Property="BackgroundColor"
                        Value="{StaticResource AppPrimaryColor}" />
                <Setter Property="TextColor"
                        Value="{StaticResource SecondaryColor}" />
                <Setter Property="CornerRadius"
                        Value="5" />
            </Style>
    
        </Application.Resources>
    </Application>
    

    此代码定义一个 Thickness 值、一系列 Color 值以及用于 ContentPageButton 类型的隐式样式。 请注意,可以在整个应用程序中使用这些样式(处于应用程序级 ResourceDictionary 中)。 有关 XAML 样式的详细信息,请参阅 Xamarin.Forms 快速入门深入探讨中的样式

    对 App.xaml 进行更改后,XAML 热重载将更新正在运行的应用的 UI,且无需重新生成应用程序。 具体而言,每页的背景色都会发生变化。 默认情况下,停止键入后热重载会立即实施更改。 但如果愿意,有一个可以更改的首选项设置,可设置为等到文件保存时再应用更改。

  4. 在“解决方案资源管理器”的“Notes”项目中,打开“AppShell.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <Shell xmlns="http://xamarin.com/schemas/2014/forms"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           xmlns:views="clr-namespace:Notes.Views"
           x:Class="Notes.AppShell">
    
        <Shell.Resources>
            <!-- Style Shell elements -->
            <Style x:Key="BaseStyle"
                   TargetType="Element">
                <Setter Property="Shell.BackgroundColor"
                        Value="{StaticResource AppPrimaryColor}" />
                <Setter Property="Shell.ForegroundColor"
                        Value="{StaticResource SecondaryColor}" />
                <Setter Property="Shell.TitleColor"
                        Value="{StaticResource SecondaryColor}" />
                <Setter Property="Shell.TabBarUnselectedColor"
                        Value="#95FFFFFF"/>
            </Style>
            <Style TargetType="TabBar"
                   BasedOn="{StaticResource BaseStyle}" />
        </Shell.Resources>
    
        <!-- Display a bottom tab bar containing two tabs -->   
        <TabBar>
            <ShellContent Title="Notes"
                          Icon="icon_feed.png"
                          ContentTemplate="{DataTemplate views:NotesPage}" />
            <ShellContent Title="About"
                          Icon="icon_about.png"
                          ContentTemplate="{DataTemplate views:AboutPage}" />
        </TabBar>
    </Shell>
    

    此代码将两个样式添加到 Shell 资源字典,后者定义应用程序使用的一系列 Color 值。

    对 AppShell.xaml 进行更改后,XAML 热重载将更新正在运行的应用的 UI,且不用重新生成应用程序。 具体而言,Shell 镶边的背景色将发生变化。

  5. 在“解决方案资源管理器”的“Notes”项目中,打开“Views”文件夹中的“NotesPage.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.Views.NotesPage"
                 Title="Notes">
    
        <ContentPage.Resources>
            <!-- Define a visual state for the Selected state of the CollectionView -->
            <Style TargetType="StackLayout">
                <Setter Property="VisualStateManager.VisualStateGroups">
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="Selected">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor"
                                            Value="{StaticResource AppPrimaryColor}" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </Setter>
            </Style>
        </ContentPage.Resources>
    
        <!-- Add an item to the toolbar -->
        <ContentPage.ToolbarItems>
            <ToolbarItem Text="Add"
                         Clicked="OnAddClicked" />
        </ContentPage.ToolbarItems>
    
        <!-- Display notes in a list -->
        <CollectionView x:Name="collectionView"
                        Margin="{StaticResource PageMargin}"
                        SelectionMode="Single"
                        SelectionChanged="OnSelectionChanged">
            <CollectionView.ItemsLayout>
                <LinearItemsLayout Orientation="Vertical"
                                   ItemSpacing="10" />
            </CollectionView.ItemsLayout>
            <!-- Define the appearance of each item in the list -->
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout>
                        <Label Text="{Binding Text}"
                               FontSize="Medium" />
                        <Label Text="{Binding Date}"
                               TextColor="{StaticResource TertiaryColor}"
                               FontSize="Small" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </ContentPage>
    

    此代码为 StackLayout 添加了一个隐式样式,它将 CollectionView 中每个选定项的外观定义为页面级 ResourceDictionary,并将 CollectionView.MarginLabel.TextColor 属性设置为应用级 ResourceDictionary 中定义的值。 请注意,StackLayout 隐式样式已添加到页面级 ResourceDictionary,因为它仅由 NotesPage 使用。

    对 NotesPage.xaml 进行更改后,XAML 热重载将更新正在运行的应用的 UI,且不用重新生成应用程序。 具体而言,CollectionView 中的选定项的颜色将发生变化。

  6. 在“解决方案资源管理器”的“Notes”项目中,打开“Views”文件夹中的“NoteEntryPage.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.Views.NoteEntryPage"
                 Title="Note Entry">
        <ContentPage.Resources>
            <!-- Implicit styles -->
            <Style TargetType="{x:Type Editor}">
                <Setter Property="BackgroundColor"
                        Value="{StaticResource AppBackgroundColor}" />
            </Style>         
        </ContentPage.Resources>
    
        <!-- Layout children vertically -->
        <StackLayout Margin="{StaticResource PageMargin}">
            <Editor Placeholder="Enter your note"
                    Text="{Binding Text}"
                    HeightRequest="100" />
            <Grid ColumnDefinitions="*,*">
                <!-- Layout children in two columns -->
                <Button Text="Save"
                        Clicked="OnSaveButtonClicked" />
                <Button Grid.Column="1"
                        Text="Delete"
                        Clicked="OnDeleteButtonClicked"/>
            </Grid>
        </StackLayout>
    </ContentPage>
    

    此代码将 Editor 的隐式样式添加到页面级 ResourceDictionary,并将 StackLayout.Margin 属性设置为在应用程序级 ResourceDictionary 中定义的值。 请注意,Editor 隐式样式已添加到页面级 ResourceDictionary,因为它仅由 NoteEntryPage 使用。

  7. 在正在运行的应用程序中,导航到 NoteEntryPage

    XAML 热重载将更新应用程序的 UI,而无需重新生成应用程序。 具体而言,Editor 的背景色在运行的应用程序中将发生变化,Button 对象的外观也会发生变化。

  8. 在“解决方案资源管理器”的“Notes”项目中,打开“Views”文件夹中的“AboutPage.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.Views.AboutPage"
                 Title="About">
        <!-- Layout children in two rows -->
        <Grid RowDefinitions="Auto,*">
            <Image Source="xamarin_logo.png"
                   BackgroundColor="{StaticResource AppPrimaryColor}"
                   Opacity="0.85"
                   VerticalOptions="Center"
                   HeightRequest="64" />
            <!-- Layout children vertically -->       
            <StackLayout Grid.Row="1"
                         Margin="{StaticResource PageMargin}"
                         Spacing="20">
                <Label FontSize="22">
                    <Label.FormattedText>
                        <FormattedString>
                            <FormattedString.Spans>
                                <Span Text="Notes"
                                      FontAttributes="Bold"
                                      FontSize="22" />
                                <Span Text=" v1.0" />
                            </FormattedString.Spans>
                        </FormattedString>
                    </Label.FormattedText>
                </Label>
                <Label Text="This app is written in XAML and C# with the Xamarin Platform." />
                <Button Text="Learn more"
                        Clicked="OnButtonClicked" />
            </StackLayout>
        </Grid>
    </ContentPage>
    

    此代码将 Image.BackgroundColorStackLayout.Margin 属性设置为在应用程序级别 ResourceDictionary 中定义的值。

  9. 在正在运行的应用程序中,导航到 AboutPage

    XAML 热重载将更新应用程序的 UI,而无需重新生成应用程序。 具体而言,Image 的背景色在运行的应用程序中将发生变化。

使用 Visual Studio for Mac 更新应用

  1. 启动 Visual Studio for Mac 并打开“Notes”项目。

  2. 在所选平台上生成并运行项目。 有关详细信息,请参阅生成快速入门

    让应用程序保持运行并返回到 Visual Studio for Mac。

  3. 在“Solution Pad”的“Notes”项目中,打开“App.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="utf-8" ?>
    <Application xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.App">
    
        <!-- Resources used by multiple pages in the application -->                 
        <Application.Resources>
    
            <Thickness x:Key="PageMargin">20</Thickness>
    
            <!-- Colors -->
            <Color x:Key="AppPrimaryColor">#1976D2</Color>
            <Color x:Key="AppBackgroundColor">AliceBlue</Color>
            <Color x:Key="PrimaryColor">Black</Color>
            <Color x:Key="SecondaryColor">White</Color>
            <Color x:Key="TertiaryColor">Silver</Color>
    
            <!-- Implicit styles -->
            <Style TargetType="ContentPage"
                   ApplyToDerivedTypes="True">
                <Setter Property="BackgroundColor"
                        Value="{StaticResource AppBackgroundColor}" />
            </Style>
    
            <Style TargetType="Button">
                <Setter Property="FontSize"
                        Value="Medium" />
                <Setter Property="BackgroundColor"
                        Value="{StaticResource AppPrimaryColor}" />
                <Setter Property="TextColor"
                        Value="{StaticResource SecondaryColor}" />
                <Setter Property="CornerRadius"
                        Value="5" />
            </Style>  
        </Application.Resources>
    </Application>
    

    此代码定义一个 Thickness 值、一系列 Color 值以及用于 ContentPageButton 类型的隐式样式。 请注意,可以在整个应用程序中使用这些样式(处于应用程序级 ResourceDictionary 中)。 有关 XAML 样式的详细信息,请参阅 Xamarin.Forms 快速入门深入探讨中的样式

    对 App.xaml 进行更改后,XAML 热重载将更新正在运行的应用的 UI,且无需重新生成应用程序。 具体而言,每页的背景色都会发生变化。 默认情况下,停止键入后热重载会立即实施更改。 但如果愿意,有一个可以更改的首选项设置,可设置为等到文件保存时再应用更改。

  4. 在“Solution Pad”的“Notes”项目中,打开“AppShell.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <Shell xmlns="http://xamarin.com/schemas/2014/forms"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           xmlns:views="clr-namespace:Notes.Views"
           x:Class="Notes.AppShell">
    
        <Shell.Resources>
            <!-- Style Shell elements -->
            <Style x:Key="BaseStyle"
                   TargetType="Element">
                <Setter Property="Shell.BackgroundColor"
                        Value="{StaticResource AppPrimaryColor}" />
                <Setter Property="Shell.ForegroundColor"
                        Value="{StaticResource SecondaryColor}" />
                <Setter Property="Shell.TitleColor"
                        Value="{StaticResource SecondaryColor}" />
                <Setter Property="Shell.TabBarUnselectedColor"
                        Value="#95FFFFFF"/>
            </Style>
            <Style TargetType="TabBar"
                   BasedOn="{StaticResource BaseStyle}" />
        </Shell.Resources>
    
        <!-- Display a bottom tab bar containing two tabs -->
        <TabBar>
            <ShellContent Title="Notes"
                          Icon="icon_feed.png"
                          ContentTemplate="{DataTemplate views:NotesPage}" />
            <ShellContent Title="About"
                          Icon="icon_about.png"
                          ContentTemplate="{DataTemplate views:AboutPage}" />
        </TabBar>
    </Shell>
    

    此代码将两个样式添加到 Shell 资源字典,后者定义应用程序使用的一系列 Color 值。

    对 AppShell.xaml 进行更改后,XAML 热重载将更新正在运行的应用的 UI,且不用重新生成应用程序。 具体而言,Shell 镶边的背景色将发生变化。

  5. 在“Solution Pad”的“Notes”项目中,打开“Views”文件夹中的“NotesPage.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.Views.NotesPage"
                 Title="Notes">
    
        <ContentPage.Resources>
            <!-- Define a visual state for the Selected state of the CollectionView -->
            <Style TargetType="StackLayout">
                <Setter Property="VisualStateManager.VisualStateGroups">
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="Selected">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor"
                                            Value="{StaticResource AppPrimaryColor}" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </Setter>
            </Style>
        </ContentPage.Resources>
    
        <!-- Add an item to the toolbar -->
        <ContentPage.ToolbarItems>
            <ToolbarItem Text="Add"
                         Clicked="OnAddClicked" />
        </ContentPage.ToolbarItems>
    
        <!-- Display notes in a list -->
        <CollectionView x:Name="collectionView"
                        Margin="{StaticResource PageMargin}"
                        SelectionMode="Single"
                        SelectionChanged="OnSelectionChanged">
            <CollectionView.ItemsLayout>
                <LinearItemsLayout Orientation="Vertical"
                                   ItemSpacing="10" />
            </CollectionView.ItemsLayout>
            <!-- Define the appearance of each item in the list -->
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout>
                        <Label Text="{Binding Text}"
                               FontSize="Medium" />
                        <Label Text="{Binding Date}"
                               TextColor="{StaticResource TertiaryColor}"
                               FontSize="Small" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </ContentPage>
    

    此代码为 StackLayout 添加了一个隐式样式,它将 CollectionView 中每个选定项的外观定义为页面级 ResourceDictionary,并将 CollectionView.MarginLabel.TextColor 属性设置为应用级 ResourceDictionary 中定义的值。 请注意,StackLayout 隐式样式已添加到页面级 ResourceDictionary,因为它仅由 NotesPage 使用。

    对 NotesPage.xaml 进行更改后,XAML 热重载将更新正在运行的应用的 UI,且不用重新生成应用程序。 具体而言,CollectionView 中的选定项的颜色将发生变化。

  6. 在“Solution Pad”的“Notes”项目中,打开“Views”文件夹中的“NoteEntryPage.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.Views.NoteEntryPage"
                 Title="Note Entry">
        <ContentPage.Resources>
            <!-- Implicit styles -->
            <Style TargetType="{x:Type Editor}">
                <Setter Property="BackgroundColor"
                        Value="{StaticResource AppBackgroundColor}" />
            </Style>       
        </ContentPage.Resources>
    
        <!-- Layout children vertically -->
        <StackLayout Margin="{StaticResource PageMargin}">
            <Editor Placeholder="Enter your note"
                    Text="{Binding Text}"
                    HeightRequest="100" />
            <!-- Layout children in two columns -->
            <Grid ColumnDefinitions="*,*">
                <Button Text="Save"
                        Clicked="OnSaveButtonClicked" />
                <Button Grid.Column="1"
                        Text="Delete"
                        Clicked="OnDeleteButtonClicked"/>
            </Grid>
        </StackLayout>
    </ContentPage>
    

    此代码将 Editor 的隐式样式添加到页面级 ResourceDictionary,并将 StackLayout.Margin 属性设置为在应用程序级 ResourceDictionary 中定义的值。 请注意,Editor 隐式样式已添加到页面级 ResourceDictionary,因为它仅由 NoteEntryPage 使用。

  7. 在正在运行的应用程序中,导航到 NoteEntryPage

    XAML 热重载将更新应用程序的 UI,而无需重新生成应用程序。 具体而言,Editor 的背景色在运行的应用程序中将发生变化,Button 对象的外观也会发生变化。

  8. 在“Solution Pad”的“Notes”项目中,打开“Views”文件夹中的“AboutPage.xaml” 。 然后将现有代码替换为以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.Views.AboutPage"
                 Title="About">
        <!-- Layout children in two rows -->
        <Grid RowDefinitions="Auto,*">
            <Image Source="xamarin_logo.png"
                   BackgroundColor="{StaticResource AppPrimaryColor}"
                   Opacity="0.85"
                   VerticalOptions="Center"
                   HeightRequest="64" />
            <!-- Layout children vertically -->
            <StackLayout Grid.Row="1"
                         Margin="{StaticResource PageMargin}"
                         Spacing="20">
                <Label FontSize="22">
                    <Label.FormattedText>
                        <FormattedString>
                            <FormattedString.Spans>
                                <Span Text="Notes"
                                      FontAttributes="Bold"
                                      FontSize="22" />
                                <Span Text=" v1.0" />
                            </FormattedString.Spans>
                        </FormattedString>
                    </Label.FormattedText>
                </Label>
                <Label Text="This app is written in XAML and C# with the Xamarin Platform." />
                <Button Text="Learn more"
                        Clicked="OnButtonClicked" />
            </StackLayout>
        </Grid>
    </ContentPage>
    

    此代码将 Image.BackgroundColorStackLayout.Margin 属性设置为在应用程序级别 ResourceDictionary 中定义的值。

  9. 在正在运行的应用程序中,导航到 AboutPage

    XAML 热重载将更新应用程序的 UI,而无需重新生成应用程序。 具体而言,Image 的背景色在运行的应用程序中将发生变化。

后续步骤

在此快速入门中,读者学习了如何:

  • 使用 XAML 样式为 Xamarin.Forms Shell 应用程序设置样式。
  • 使用 XAML 热重载查看 UI 更改,无需重新生成应用程序。

若要详细了解如何使用 Xamarin.Forms Shell 进行应用程序开发的基础知识,请继续学习快速入门深入探讨。