从不同程序集加载合并的ResourceDictionary失败

12

我已将我的应用程序的所有ResourceDictionary放入一个单独的程序集中,并将它们合并成一个ResourceDictionary,我希望将其作为资源包含在我的应用程序中:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="InputStyles.xaml"/>
        <ResourceDictionary Source="DataGridStyles.xaml"/>
        <ResourceDictionary Source="ComboboxStyles.xaml"/>
        <ResourceDictionary Source="CheckboxStyles.xaml"/>
        <ResourceDictionary Source="TabControlStyles.xaml"/>
        <ResourceDictionary Source="ButtonStyles.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

声明资源:

<Window.Resources>
    <ResourceDictionary Source="pack://application:,,,/StyleAssembly;component/Styles.xaml"/>
</Window.Resources>

在VS的设计师中查看所有控件都显示了来自文件的样式,但是当我尝试启动应用程序时,出现以下错误:

"无法定位资源“inputstyles.xaml”."

对于所有文件,构建操作设置为“Page”,两个项目的构建都成功了。我做错了什么?


尝试在你的Source属性中加入"pack://application:,,,/StyleAssembly;component/.........."。 - punker76
请注意,根据https://dev59.com/7HPYa4cB1Zd3GeqPg0MU的说法,输出路径也是一个问题。 - nietras
4个回答

7
如果您愿意做一些工作,构建操作应该定义为资源或内容
您的资源必须被定义为项目的一部分,并采用资源构建操作。如果您在项目中包含一个资源.xaml文件,它被定义为资源,这样您就不需要将资源文件复制到输出目录中了,因为该资源已经被包括在编译后的应用程序中。您也可以使用内容构建操作,但是您必须将文件复制到输出目录,并在与可执行文件相同的路径关系下部署资源文件。

3

根据我的观察,将资源字典构建样式设置为Resource可能会在后面的过程中导致奇怪的错误(我突然开始收到运行时错误Cannot create X,其中X是在我的资源字典中引用的用户定义类型)。

我建议将构建样式保留在Page。从我所看到的情况来看,这样应该能正常工作。


我认为在WPF中,“Page”意味着XAML被编译成BAML。 - George Birbilis

2

有关 WPF 中的 Pack URIs 和 Merged Resource Dictionaries 的更多详细信息,请参见 此处此处

构建操作应为 Resource


1
请参考此解决方案,无论您是否了解外部Assembly结构(文件名等),都可以迭代外部Assembly以获取ResourceDictionary(s)UserControls。同时提供XMAL和C#解决方案。 更新 XAML方式:如果您知道Assembly中资源的URI,则可以直接加载它。在XAML中使用相同的语法转换
ResourceDictionary dictionary = new ResourceDictionary();
 dictionary.Source = new Uri("pack://application:,,,/WpfControlLibrary1;Component/RD1.xaml", UriKind.Absolute);
 foreach (var item in dictionary.Values)
 {
    //operations
 }

C#之道:如果你只知道程序集,而不知道其中的资源

public ResourceDictionary GetResourceDictionary(string assemblyName)
{
    Assembly asm = Assembly.LoadFrom(assemblyName);
    Stream stream = asm.GetManifestResourceStream(asm.GetName().Name + ".g.resources");            
    using (ResourceReader reader = new ResourceReader(stream))
    {
        foreach (DictionaryEntry entry in reader)
        {
            var readStream = entry.Value as Stream;
            Baml2006Reader bamlReader = new Baml2006Reader(readStream);
            var loadedObject = System.Windows.Markup.XamlReader.Load(bamlReader);
            if (loadedObject is ResourceDictionary)
            {
                return loadedObject as ResourceDictionary;
            }
        }
    }
    return null;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接