我在文件FrameRes.xaml
中创建了一个资源,如下所示:
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Japanese.Resources.FrameRes">
<Style x:Key="FrameBorder" TargetType="Frame">
<Setter Property="CornerRadius" Value="2" />
<Setter Property="HasShadow" Value="false" />
<Setter Property="Margin" Value="10,0" />
<Setter Property="BorderColor" Value="{DynamicResource LineColor}" />
<Setter Property="Padding" Value="0" />
<Setter Property="VerticalOptions" Value="Start" />
</Style>
</ResourceDictionary>
它包含在里面:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:converters="clr-namespace:Japanese"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Japanese.App">
<Application.Resources>
<ResourceDictionary Source="/Resources/FooterRes.xaml" />
<ResourceDictionary Source="/Resources/FrameRes.xaml" />
</Application.Resources>
</Application>
当我尝试像这样在C#中访问它时,它失败并说没有对FrameBorder的引用:
var fb2 = (Style)Application.Current.Resources["FrameBorder"];
当我尝试像这样在C#中访问它时,它将起作用:
Application.Current.Resources.TryGetValue("FrameBorder", out object frameBorder);
var fb = (Style)frameBorder;
有谁知道为什么第一种方法行不通。对我来说看起来一样。
最佳答案
设置方式是,在另一个ResourceDictionary
中包含一个ResourceDictionary
,但没有键/名称/引用。调用Application.Current.Resources["FrameBorder"];
时,您将访问字典的最上层并查找"FrameBorder"
,而不是其子级别。但是,调用TryGetValue
会遍历字典的所有级别。
通读Docs以了解如何从“词典”中访问值。
好的,所以我玩过ResourceDictionary
标记和文件,并且可以看到您要去哪里了。
根据Xamarin Forms Docs on ResourceDictionary
,您可以将ResourceDictionary
XAML独立文件添加到App.xaml
中,如下所示:
<App ...>
<App.Resources>
<!-- Add more resources here -->
<ResourceDictionary Source="MyResourceDictionary.xaml" />
<!-- Add more resources here -->
</App.Resources>
...
</App>
您可以根据自己的用途将
App
替换为ContentPage
或ContentView
。这是做什么的?
简而言之,这将创建一个新的
ResourceDictionary
对象,并且将其他ResourceDictionary
文件合并到其中。让我们再详细一点。让我们从
Application.Current.Resources
属性开始,该属性的类型为 ResourceDictionary
,实现了ICollection
,IDictionary
和IResourceDictionary
。给定它实现的接口(interface),您可以通过数字或字符串ID(例如App.Current.Resources[0]
或App.Current.Resources["LabelStyle"]
)获取值。这将访问字典的顶级顶级内容,因此仅访问在<[App/ContentPage/ContentView].Resources>
标记中创建的内容。您还拥有一个名为
MergedDictionaries
的属性,该属性实现ICollection
。这意味着您只能通过数字ID(例如MyMergedDictionary[0]
)访问列表项。当您添加
ResourceDictionary
文件时,例如:<ResourceDictionary Source="MyResourceDictionary.xaml" />
您实际上是将此文件与当前的
ResourceDictionary
合并。然后访问要调用的MyResourceDictionary
的内容(在C#中):App.Current.Resources.MergedDictionaries[0]["InternalKeyName"]
大概可以这样更好地解释:
<App ...>
<App.Resources>
<!-- Called using App.Current.Resources["PrimaryColor"] -->
<Color x:Key="PrimaryColor">#2196F3</Color>
<!-- Called using App.Current.Resources.MergedDictionaries[0]["InternalKeyName"] -->
<ResourceDictionary Source="MyResourceDictionary.xaml" />
</App.Resources>
...
</App>
你的情况
在您的情况下,您有两个词典合并到您的应用程序资源中:
FooterRes
和FrameRes
。为了更好的管理,我将创建一个
enum
,例如:public enum MergedResourcesEnum
{
Footer,
Frame
}
并在C#中调用资源时使用此枚举,如下所示:
Application
.Current
.Resources
.MergedDictionaries[(int)MergedResourcesEnum.Frame]["FrameBorder"];
关于xamarin - 为什么(Style)Application.Current.Resources ["FrameBorder"]不让我访问ResourceDirectory中的资源,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53457854/