Wpf 未从ResourceDictionary解析资源

Wpf 未从ResourceDictionary解析资源,wpf,xaml,resourcedictionary,Wpf,Xaml,Resourcedictionary,我在解析ResourceDictionary中的资源时遇到问题 我决定将我相当大的ResourceDictionary重构成单独的字典文件,并组织成子文件夹 我在参考资料下有一个ResourceLibrary.xaml: <ResourceDictionary x:Class="MyProject.Resources.ResourceLibrary" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/pr

我在解析ResourceDictionary中的资源时遇到问题

我决定将我相当大的ResourceDictionary重构成单独的字典文件,并组织成子文件夹

我在参考资料下有一个ResourceLibrary.xaml:

<ResourceDictionary x:Class="MyProject.Resources.ResourceLibrary"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <ResourceDictionary.MergedDictionaries>
     <!-- Colours -->
     <ResourceDictionary Source="Colors/ConnectedCellColor.xaml" />
     <!-- Brushes -->
     <ResourceDictionary Source="Brushes/ConnectorCellBrush.xaml" />
     <!-- Control Templates -->
     <ResourceDictionary Source="ControlTemplates/ConnectorCellTemplate.xaml" />
     <!-- Base Styles -->
     <ResourceDictionary Source="BaseStyles/ConnectorBaseStyle.xaml" />
   </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
(我在某处发现了一个巧妙的把戏)

我实际上可以运行我的程序,当创建该视图时,在尝试设置样式时会引发异常:

系统无效卡斯特例外
无法将类型为“MS.Internal.NamedObject”的对象强制转换为类型为System.Windows.FrameworkTemplate的对象

我发现的与此相关的唯一信息与资源的顺序有关,但从我在ResourceLibrary中的顺序来看,它应该是有效的

抛出异常时,我可以检查Application.Current.Resources.MergedDictionaries, 请参阅参考资料

我尝试了各种方法在ResourceLibrary中指定源代码

<ResourceDictionary Source="/MyProject;component/Resources/BaseStyles/ConnectorBaseStyle.xaml" />

等等,对找到它们没有影响。这些资源仅由插件代码使用

唯一有效的方法是将所有静态资源更改为动态资源

这对我来说没有意义,如果这是一个订单问题,那么当它们都在同一个文件中时,为什么静态工作

我的一些样式使用BasedOn,它们与DynamicSource不兼容


你能帮我理解为什么会发生这种情况,以及如何让它工作吗?

这是一个排序问题,但与合并的顺序无关,而是与加载的顺序有关。下面是加载ResourceLibrary字典时发生的基本情况:

  • ConnectedCellColor实例化
  • ConnectedCellColor加载到ResourceLibrary
  • ConnectorCellBrush实例化
  • ConnectorCellBrush加载到ResourceLibrary
  • ConnectorCellTemplate实例化
  • ConnectorCellTemplate加载到ResourceLibrary
  • ConnectorBaseStyle实例化
  • ConnectorBaseStyle加载到ResourceLibrary中
  • 这里的问题是,在使用单个文件之前,您只有一个实例化步骤,而现在您已经将其分解为多个步骤,每个步骤都独立发生。当实例化ConnectorBaseStyle时,ConnectorCellTemplate已加载,但此时ConnectorBaseStyle不知道ResourceLibrary的内容。使用
    DynamicResource
    这不是问题,因为这些引用可以在步骤8中解决,但是
    StaticResource
    需要在步骤7中立即解决


    最简单的修复方法是尽可能使用
    动态
    。对于需要
    Static
    (如
    BasedOn
    )的位置,您需要保证资源在实例化过程中可用,或者也可以将ConnectorCellTemplate合并到ConnectorBaseStyle中,或者将所需的所有内容合并到App.xaml中,App.xaml对所有内容都可用。当您获取更多文件并合并到多个位置时,这可能会使事情变得复杂和难以管理,但至少资源系统足够智能,能够识别重复项,因此在上述情况下,即使在两个位置合并ConnectorCellTemplate,您仍然只能获得一个ConnectorCellTemplate实例。

    我不确定是否理解这一点充分地据我所知,ResourceLibrary是在我的应用程序初始化后加载的,因为我可以在调试器中看到资源。一旦视图被创建,在我看来,如果BaseStyle在应用程序的资源中,它应该解决。。。
    <ResourceDictionary>
       <Style x:Key="ConnectorBaseStyle" TargetType="UserControl">
          <Setter Property="Template" Value="{StaticResource ConnectorCellTemplate}" />
       </Style>
    </ResourceDictionary>
    
      public void OnImportsSatisfied()
      {
         foreach (ResourceDictionary resourceDictionary in ResourceDictionaries)
         {
            Application.Resources.MergedDictionaries.Add(resourceDictionary);
         }
      }
    
    <ResourceDictionary Source="/MyProject;component/Resources/BaseStyles/ConnectorBaseStyle.xaml" />