XAML设计器错误:“ IOException:无法找到资源”-如何提供与动态程序集名称一起使用的Pack URI?

问题描述

我们有一个ResourceDictionary被引用如下

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,/Theming/AppTheme.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

这在运行时效果很好。但是,Visual Studio中的设计器在引用此UserControl的视图中给出了错误

IOException:无法找到资源“ theming / apptheme.xaml”。

其他SO答案建议通过指定程序集名称来引用ResourceDictionary:

<ResourceDictionary Source="pack://application:,/MyDomain.MyApp.Wpf;component/Theming/AppTheme.xaml" />

这使Designer感到满意,但是我们的程序集名称在阶段和生产中是不同的,因此如果我们不必指定程序集名称,那就很好了。我的问题是:我们如何提供ResourceDictionary源URI,使设计者满意并且不需要指定程序集名称

如果这不可能,我们可以使用预处理器指令使URI成为一个静态值,该静态值对于每个构建配置都是不同的。

解决方法

您可以使用XAML定义应用程序的UI或资源。 资源通常是您希望多次使用的某些对象的定义。要在以后引用XAML资源,请为资源指定一个键,该键的作用类似于其名称。 您可以在整个应用程序中或从其中的任何XAML页面引用资源。 您可以使用Windows运行时XAML中的ResourceDictionary元素定义资源。 然后,您可以使用StaticResource标记扩展或ThemeResource标记扩展来引用资源。

资源不必是字符串。 它们可以是任何可共享的对象,例如样式,模板,笔刷和颜色。但是,控件,形状和其他FrameworkElement是不可共享的,因此不能将它们声明为可重用资源。

示例:

<Page.Resources>
    <x:String x:Key="key1">Hey</x:String>
    <x:String x:Key="key2">Nice</x:String>
</Page.Resources>

您可以通过在相应位置找到按键来使用这些资源,即:

<Label Text="{StaticResource key1}" FontSize="Large" VerticalAlignment="Center"/>

好吧,为了使您的项目更有条理,您需要将ResourceDictionary创建为一个单独的文件并按如下方式进行调用(ContentPage部分取决于页面):

<ContentPage.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Styles.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</ContentPage.Resources>

//在此示例中,“样式”位于页面所在的同一文件夹中,您可以使动态资源从所有区域访问它,或以适当的方式创建路径,例如:

xmlns:themes = "clr-namespace:AppName.Themes;assembly=AppName"

我们如何提供ResourceDictionary源URI,使设计者感到满意并且不需要指定程序集名称? 你会创造一个动态的。 像这样:

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
    x:Class="App.Themes.Theme"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Color x:Key="PrimaryColor">#ffffff</Color>
<Color x:Key="PrimaryDarkColor">#0f0f0f</Color>
</ResourceDictionary>

,然后在app.xaml中执行此操作(如果主题位于主项目的文件夹中):

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:themes = "clr-namespace:YourProjectName.Themes;assembly=YourProjectName"
             x:Class="YourProjectName.App">

    <Application.Resources>

    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <themes:Theme />
        </ResourceDictionary.MergedDictionaries >
    </ResourceDictionary>

</Application.Resources>

然后您可以在任何地方做这样的事情:

    BackgroundColor="{DynamicResource PrimaryColor}"

祝你好运!