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

时间:2016-01-23 16:44:35

标签: c# xaml xamarin xamarin.forms

我编写了以下代码,但是XamlParseException抛出了bean。 ("找不到关键CustomColor&#34的StaticResource;)

MyPage.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>

4 个答案:

答案 0 :(得分:14)

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

<强> BlueTheme.xaml

3

<强>的App.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>

答案 1 :(得分:9)

2.1.7以下的Xamarin Forms XAML不支持合并字典

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

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

然而,从2.1.0-pre1(本周发布)开始,您现在可以进行模板化,这是另一种方法。杰森史密斯在博客上写道: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>

答案 2 :(得分:0)

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文件的路径(始终在同一程序集中)
  • MergeDictionaries:可以与资源所在的程序集无关地使用

Xamarin Forms Resource Dictionaries中的更多信息

答案 3 :(得分:0)

几个小时后的一些笔记:

  • MergedWith 已弃用。改用 Source
  • 尽管 the official tutorial 说了些什么,但似乎无法加载在单独的 ContentPage 中定义的资源字典。资源字典必须是它自己的 .xaml 文件。
  • 不管其他答案怎么说,Source 的值只是 .xaml 文件的名称,不是它的路径。
  • this comment 开始,包含共享资源的 .xaml 文件必须:
    • .. 有一个 ResourceDictionary 类型的根元素
    • ..有一个 .xaml.cs 支持文件(删除它会导致它静默失败)
    • ...从后备文件中的 ResourceDictionary 继承
    • ..与使用它的 .xaml 在同一个程序集中(显然可以使用 MergedDictionaries 在程序集中共享样式,但我无法让它工作)