在ResourceDictionary中找不到外部控件的资源

时间:2017-11-17 10:41:54

标签: xaml uwp resourcedictionary

问题

我想在项目B中定义样式控件,但在项目A的页面上使用项目A中的样式。我决定通过使用包含MyCtrl.xaml中使用的键的样式字典定义合并字典来实现。

我认为在MainPage中使用的MyCtrl将在XAML树上找到正确的样式,如果它没有在自己的xaml(更广泛的范围)中找到它,但我得到了未找到名称/密钥的异常。我做错了什么,或者这个想法是不正确的,我应该找到另一个解决方案吗?

以下是结构:

我有两个项目:

  • 项目A - 包含MainPage页面和所有样式/资源的主应用程序。
  • 项目B - 包含用户控件

项目A参考项目B.

(项目A)MainPage.xaml

<Page
   xmlns:ext="using:ProjB.Ctrls">
  <Page.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
         <ResourceDictionary Source="ms-appx:///SomeDir/MyCtrlStyles.xaml" />
         <ResourceDictionary Source="ms-appx:///SomeDir/MainPageStyles.xaml" />
      </ResourceDictionary.MergedDictionaries>
  </Page.Resources>
  …
  <ext: MyCtrl x:Id="myCtrlA" />
  …
</Page>

(项目A)MainPageStyles.xaml

<ResourceDictionary>
  <Style x:Key="StyleAAA" />
</ResourceDictionary>

(项目A)MainPageStyles.xaml

<ResourceDictionary>
  <Style x:Key="StyleBBB" BasedOn="{StaticResource BodyTextBlockStyle}" TargetType="TextBlock">
    <Setter Property="Margin" Value="24 13 12 0" />
  </Style>
</ResourceDictionary>

(项目B)MyCtrl.xaml

<UserControl>
  <TextBlock x:Name="txtA" Style="{StaticResource StyleBBB}" Text="Text A" />
</ UserControl>

2 个答案:

答案 0 :(得分:0)

源路径的正确语法应为:

  

ms-appx:/// [Assembly] / [Path] / [Resource File]

因此,您应该将程序集名称添加到引用的程序集中,如下所示:

<Page
   xmlns:ext="using:ProjB.Ctrls">
  <Page.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
         <ResourceDictionary Source="ms-appx:///MyCtrl/SomeDir/MyCtrlStyles.xaml" />
         <ResourceDictionary Source="ms-appx:///SomeDir/MainPageStyles.xaml" />
      </ResourceDictionary.MergedDictionaries>
  </Page.Resources>
  …
  <ext: MyCtrl x:Id="myCtrlA" />
  …
</Page>

答案 1 :(得分:0)

<ext: MyCtrl x:Id="myCtrlA" />

只是自定义控件的一个实例,在不同的项目中,不知道您尝试使用的样式。

由于必须先加载自定义控件的xaml才能实例化它,因此它会尝试在那时找到资源StyleBBB。无法找到资源,因为资源不在任何可用的字典中,或者是app.xaml合并的字典。

一些选项,按照我建议尝试的顺序。

选项1

您应该尝试使用DynamicResource。

这将允许绑定在控件放入页面时重新评估,因此它可以在运行时正确查找它。

DynamicResource对性能的要求要高得多,所以如果这是一个控制,你计划一直创建数千个实例,这可能是一个太大的权衡。

选项2

将合并的词典放入app.xaml文件中。

当在其他地方找不到资源时,可以将此应用程序范围的资源字典视为后备查找。

缺点是它适用于您应用程序中的所有内容,并且它仅适用于任何给定密钥的一个资源,因此您不能像通常那样在子控件中覆盖它。

选项3

将项目A的引用添加到项目B中。将所需的字典合并到控件的资源中。

这会增加您以前没有的依赖关系,而且它是循环的,所以尽量不要这样做。