Xamarin.Forms:如何从另一个文件加载 ResourceDictionary

本文关键字:另一个 文件 加载 ResourceDictionary Forms Xamarin | 更新日期: 2023-09-27 18:31:31

我写了以下代码,但XamlParseException已经抛出了bean。("找不到键自定义颜色的静态资源")

我的页面.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="XFApp11.MyPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="CustomResource.xaml" />
            </ResourceDictionary.MergedDictionaries> 
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <BoxView Color="{StaticResource CustomColor}" />
    </ContentPage.Content>
</ContentPage>

CustomResource.xaml (build action = EmbeddedResource)

<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <Color x:Key="CustomColor">#004B86</Color>
</ResourceDictionary>

Xamarin.Forms:如何从另一个文件加载 ResourceDictionary

从 2.3.0 开始可以正式合并 xaml 中的资源字典观察以下示例

蓝色主题.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="UI.Themes.BlueTheme">
    <Style TargetType="Label">
        <Setter Property="TextColor" Value="Blue" />
    </Style>
</ResourceDictionary>

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"
             xmlns:theme="clr-namespace:UI.Themes"
             x:Class="UI.App">
    <Application.Resources>
        <ResourceDictionary MergedWith="themes:BlueTheme" />
    </Application.Resources>
    <Label Text="Hello" />
</Application>

合并词典在 2.1.0 以下的 Xamarin 窗体 XAML 中不受支持

唯一的方法是将其放在另一个页面中,然后将其加载到代码隐藏中,并通过DynamicResource而不是StaticResource引用它。

我在这里解释更多:http://www.xamarinhelp.com/styling-uiux-day-11/

但是,从 2.1.0-pre1(本周发布)开始,您现在可以进行模板化,这是执行此操作的另一种方法。杰森·史密斯(Jason Smith)在博客上写道:http://xfcomplete.net/general/2016/01/20/control-templates/

更新:从 2.3.0 开始,您可以使用名为 MergedWith 的属性进行合并字典。

创建新的 XAML 文件

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="UIDemo.Style.NewStyle">
    <Style TargetType="Label">
        <Setter Property="TextColor" Value="Blue" />
    </Style>
</ResourceDictionary>

现在,在您的 ContentPage 中使用 ResourceDictionary 上的 MergedWith 属性。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:theme="clr-namespace:UIDemo.Style"
             x:Class="UIDemo.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary MergedWith="theme:NewStyle" />
    </ContentPage.Resources>
    <Grid>
        <Label Text="Hello" />
    </Grid>
</ContentPage>

来自 Xamarin.Forms 3.0 MergedWith已被弃用,不应使用。

现在您可以使用 SourceMergeDictionaries .

MyResource.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="UI.MyResource">
    <Style TargetType="Label">
        <Setter Property="TextColor" Value="Blue" />
    </Style>
</ResourceDictionary>

因此,如果MyResource.xaml位于同一程序集中,则可以直接使用:

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="UI.AnotherResource"
    Source="MyResource.xaml">
</ResourceDictionary>

否则(MyResource.xaml在另一个程序集上):

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:otherresources="clr-namespace:OtherAssembly.UI.Resources"
    x:Class="UI.AnotherResource">
    <ResourceDictionary.MergedDictionaries>
        <otherresources:MyResource />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

需要考虑的一些事项:

  • 源:它只能在 XAML 中使用,值是 xaml 文件的路径(始终在同一程序集中)
  • 合并词典:无论资源所在的程序集如何,都可以使用它

有关详细信息,请参阅 Xamarin 窗体资源字典

几个小时后的一些注意事项与此作斗争:

  • MergedWith已弃用。请改用Source
  • 尽管官方教程说了什么,但似乎无法加载在单独的ContentPage中定义的资源字典。资源字典需要是它自己的.xaml文件。
  • 尽管另一个答案说,Source的值只是 .xaml 文件的名称,而不是它的路径。
  • 在此注释中,包含共享资源的 .xaml 文件必须:
    • ..具有类型 ResourceDictionary 的根元素
    • ..有一个 .xaml.cs 备份文件(删除它会导致它静默失败)
    • ..从支持文件中的ResourceDictionary继承
    • ..与使用它的 .xaml 位于同一程序集中(显然可以使用 MergedDictionaries 在程序集之间共享样式,但我无法让它工作)

在也在这个主题上挣扎之后,我使用MergedDiciontaries找到了解决方案

<Application ... xmlns:resources="clr-namespace:AppName.Resources;assembly=AppName" xmlns:theme="clr-namespace:Company.Design;assembly=Company.Design">
    <Application.Resources>
        <ResourceDictionary >
            <ResourceDictionary.MergedDictionaries>
                <theme:Theme/> <!--ResourceDictionary from another assembly -->
                <resources:StylesAndTemplates/> <!--ResourceDictionary from the same assembly also StylesAndTemplates which uses colors / style from "Theme" ResourceDictionary -->
            </ResourceDictionary.MergedDictionaries>
        ...
        </ResourceDictionary>
        ...
    </Application.Resources>
    ...
</Application>