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


我已将所有应用程序的ResourceDictionaries放入一个单独的程序集中,并将它们合并为一个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'。”

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


6298
2017-12-12 14:16


起源

尝试将“pack:// application:,,, / StyleAssembly; component / ..........”添加到您的Source属性中 - punker76
请注意,按照 stackoverflow.com/questions/17083370/... 输出路径也是一个问题。 - nietras


答案:


构建操作应定义为资源或内容 如果你愿意做一些腿部工作。

您的资源必须作为资源定义为项目的一部分   建立行动。如果在项目中包含资源.xaml文件   资源,您不需要将资源文件复制到输出   目录,资源已经包含在编译中   应用。您也可以使用内容构建操作,但必须这样做   将文件复制到输出目录并部署资源   文件与可执行文件的路径关系相同。


7
2017-12-12 14:22





从我的观察。将资源dictonary构建样式设置为 Resource 可能会导致更奇怪的错误(我突然开始遇到运行时错误 Cannot create X 其中X是我的资源字典中引用的用户定义类型。

我建议保留构建样式 Page。从我所见,这应该工作得很好。


3
2018-04-24 05:49



我认为“Page”意味着(在WPF上)XAML被编译为BAML - George Birbilis


更多细节 在WPF中打包URI & 合并资源字典

应该建立行动 资源


2
2017-12-12 14:24





看到 这个解决方案 对于这两种情况 当你知道的时候 外在的    Assembly 结构(文件名等)和 当你不知道的时候 而且只是想   迭代外部 Assembly 对于 ResourceDictionary(s) 要么    UserControls

Both XMAL and C# solution.

更新

XAML方式: If you know the URI of the resource in an Assembly, then load it directly. Transform same syntax in 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#方式: If you only know the Assambly and don't know the Resources in it

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;
}

1
2018-04-23 21:25