Xamarin Forms XAML:如何从另一个 XAML 文件(如资源字典)继承属性?

XamarinForms XAML: How can I inherit properties from another XAML file like ResourceDictionaries?

我经常使用资源词典,但是必须将它们从一个 Xaml 复制并粘贴到另一个以更新它们变得很乏味。我看到这样做的唯一方法是继承样式 class,但我不喜欢 C# 中声明属性的方式(我更喜欢 XAML 的更直观的树语法)。有没有办法让一个 XAML 从另一个继承?或者像 LoadXaml() 这样的方法,我可以在我创建的每个 Xamarin.Forms.ContentPage 上调用它来继承 StylePage?

这是我的风格 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="Demo.StylePage">
    <!-- Shared Properties -->
    <ContentPage.Resources>
        <ResourceDictionary>
            <!-- TitleBar Styles -->
            <Style x:Key="TitleBarStyle" TargetType="StackLayout">
                <Setter Property="BackgroundColor" Value="#5db3d6"/>
                <Setter Property="Padding" Value="15,6"/>
                <Setter Property="HeightRequest" Value="44"/>
            </Style>

            <Style x:Key="TitleBarHeaderStyle" TargetType="Label">
                <Setter Property="TextColor" Value="White"/>
                <Setter Property="VerticalOptions" Value="CenterAndExpand"/>
<!--                <Setter Property="FontSize" Value="18"/>-->
                <Setter Property="HorizontalOptions" Value="FillAndExpand"/>
            </Style>

            <Style x:Key="EmptyFrameStyle" TargetType="Frame">
                <Setter Property="HasShadow" Value="false"></Setter>
                <Setter Property="BackgroundColor" Value="Transparent"></Setter>
                <Setter Property="Padding" Value="0,0"></Setter>
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
</ContentPage>

我如何从另一个文件加载这个资源字典?谢谢你的时间,谢尔盖。

ContentPages 支持继承。您始终可以定义一个 BasePage,在那里实现您的资源,然后让每个新的 ContentPage 继承它。虽然我从来没有通过继承 xaml 来做到这一点,但我曾经在我的 BasePage 的代码隐藏中共享分析、日志记录等(如下所示)。

我建议尝试类似的方法并在您的 BasePage 中实例化您的资源字典。

BaseFormPage:

public class BasePage : ContentPage
    {
        public BasePage () : base () { }

        protected override void OnAppearing ()
        {
            base.OnAppearing ();

            AnalyticsApi.LogPageView ();
            AnalyticsApi.LogEvent(Title + " Page Loaded");

        }
    }

子表单页面:

<?xml version="1.0" encoding="UTF-8"?>
<local:BasePage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:local="clr-namespace:MyApp;assembly=MyApp"
             x:Class="MyApp.LoginPage"
             Title="{x:Static local:Strings.SignIn}"
             BackgroundColor="{x:Static local:Colors.ThemeQuaternary}">
    <StackLayout>
        ...
    </StackLayout>
</local:BasePage>

Xamarin.Forms 中,您可以在每个 VisualElement 上声明资源。然后,您可以使用 {StaticResource}{DynamicResource}.

访问这些资源

应用的解析规则大致如下:

  • 对于 {StaticResource}
    • 在同一 XAML 文件
    • 中查看此 VisualElement.Resources 或其任何父
    • 然后在Application.Current.Resources
    • 中查找
  • 对于 {DynamicResource}
    • 查看此 VisualElement.Resources 或其任何父级,甚至是未在同一 XAML 文件中定义的父级,直至 Application.Resources
    • 注意{DynamicResources}支持稍后添加资源,或更改父级

为了回答您的问题,您确实可以在 XAML 中的基础 class 中定义样式并使用 XAML 继承,或者将所有资源添加到您的应用程序 class.如果您的应用程序没有 XAML 文件,只需添加一个,然后从应用程序构造函数中调用 InitializeComponents()

您可以将 App.cs 替换为 XAML/cs 组合,如图 here

您 App.xaml 中定义的资源将可用于您应用中加载的每个视图。

确保您的 App.xaml 文件具有 "Embedded Resource" 的构建操作。或者,您可以将其添加为 UI 中的 ContentView with XAML,然后将 ContentView 替换为 Application

App.xaml

<Application
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="WorkingWithAppResources.App">
    <Application.Resources>
        <ResourceDictionary>
            <Style x:Key="labelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="Green" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

App.xaml.cs

public partial class App : Application
{
    public App ()
    {
        InitializeComponent ();
        MainPage = YourContentPage(); // change as required
    }
}