【问题标题】:XAML Designer error: "IOException: Cannot locate resource" - How to provide a Pack URI that works with dynamic assembly name?XAML 设计器错误:“IOException:找不到资源”-如何提供与动态程序集名称一起使用的 Pack URI?
【发布时间】:2025-12-15 05:30:01
【问题描述】:

我们有一个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" />

这让设计师很高兴,但我们的程序集名称在暂存和生产中是不同的,所以如果我们不必指定程序集名称会很好。我的问题是:我们如何提供一个 ResourceDictionary Source URI 让设计者满意并且不需要指定程序集名称?

如果这是不可能的,我们可能会使用预处理器指令将 URI 设置为每个构建配置不同的静态值。

【问题讨论】:

    标签: c# wpf xaml resourcedictionary


    【解决方案1】:

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

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

    例子:

    <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 Source 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}"
    

    祝你好运!

    【讨论】:

    • 谢谢,这成功了!但是,我要补充一点,我需要创建一个继承自 ResourceDictionary 的代码隐藏类,并将 xaml 构建操作设置为 Page 以满足编译器的要求。
    最近更新 更多