【问题标题】:Loading merged ResourceDictionary from different assembly fails从不同程序集加载合并的 ResourceDictionary 失败
【发布时间】:2011-12-12 14:16:28
【问题描述】:

我已将应用程序的所有 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'。”

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

【问题讨论】:

  • 尝试将“pack://application:,,,/StyleAssembly;component/..........” 也放到你的 Source 属性中
  • 请注意,根据stackoverflow.com/questions/17083370/… 输出路径也是一个问题。

标签: c# .net wpf xaml


【解决方案1】:

build action should be defined as Resource or Content 如果你愿意做一些腿部工作。

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

【讨论】:

    【解决方案2】:

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

    我建议将构建样式保留在 Page。从我所见,这应该可以正常工作。

    【讨论】:

    • 我认为“页面”意味着(在 WPF 上)XAML 被编译为 BAML
    【解决方案3】:

    有关Pack URIs in WPF和Merged Resource Dictionaries的更多详细信息

    构建操作应该是Resource。

    【讨论】:

      【解决方案4】:

      请参阅this solution 了解这两种情况当您知道外部 Assembly 结构(文件名等)和当你不知道而只想 为ResourceDictionary(s) 迭代外部Assembly 或 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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-26
        • 2019-04-27
        • 2016-11-06
        • 1970-01-01
        • 2018-06-28
        • 2014-09-17
        • 2011-03-03
        • 1970-01-01
        相关资源
        最近更新 更多