Xamarin.Forms: 如何从另一个文件加载 ResourceDictionary?
Xamarin.Forms: How can I load ResourceDictionary from another file?
我写了下面的代码,但是抛出了 XamlParseException。 ("StaticResource not found for key CustomColor")
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(构建操作 = 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>
低于 2.1.0
的 Xamarin Forms 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>
从 2.3.0 开始可以正式合并 xaml 中的资源字典
观察下面的例子
BlueTheme.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>
来自 Xamarin.Forms 3.0 MergedWith
已弃用,不应使用。
现在您可以使用 Source
或 MergeDictionaries
。
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>
需要考虑的一些事项:
- Source:只能在XAML中使用,值为xaml文件的路径(总是在同一个程序集中)
- MergeDictionaries:无论资源所在的程序集如何都可以使用
几个小时后的一些注意事项:
MergedWith
已弃用。请改用 Source
。
- 尽管 the official tutorial 怎么说,似乎无法加载在单独的
ContentPage
中定义的资源字典。资源字典需要是它自己的 .xaml
文件。
- 不管另一个答案怎么说,
Source
的值只是 .xaml 文件的名称, 而不是 文件的路径。
- 来自 this comment,包含您的共享资源的 .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>
我写了下面的代码,但是抛出了 XamlParseException。 ("StaticResource not found for key CustomColor")
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(构建操作 = 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>
低于 2.1.0
的 Xamarin Forms 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>
从 2.3.0 开始可以正式合并 xaml 中的资源字典 观察下面的例子
BlueTheme.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>
来自 Xamarin.Forms 3.0 MergedWith
已弃用,不应使用。
现在您可以使用 Source
或 MergeDictionaries
。
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>
需要考虑的一些事项:
- Source:只能在XAML中使用,值为xaml文件的路径(总是在同一个程序集中)
- MergeDictionaries:无论资源所在的程序集如何都可以使用
几个小时后的一些注意事项:
MergedWith
已弃用。请改用Source
。- 尽管 the official tutorial 怎么说,似乎无法加载在单独的
ContentPage
中定义的资源字典。资源字典需要是它自己的.xaml
文件。 - 不管另一个答案怎么说,
Source
的值只是 .xaml 文件的名称, 而不是 文件的路径。 - 来自 this comment,包含您的共享资源的 .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>