我在文件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替换为ContentPageContentView

这是做什么的?

简而言之,这将创建一个新的ResourceDictionary对象,并且其他ResourceDictionary文件合并到其中。让我们再详细一点。

让我们从Application.Current.Resources属性开始,该属性的类型为 ResourceDictionary ,实现了ICollectionIDictionaryIResourceDictionary。给定它实现的接口(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>

你的情况

在您的情况下,您有两个词典合并到您的应用程序资源中:FooterResFrameRes

为了更好的管理,我将创建一个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/

10-13 03:15