问题
我想在项目B中定义样式控件,但在项目A的页面上使用项目A中的样式。我决定通过使用包含MyCtrl.xaml中使用的键的样式字典定义合并字典来实现。
我认为在MainPage中使用的MyCtrl将在XAML树上找到正确的样式,如果它没有在自己的xaml(更广泛的范围)中找到它,但我得到了未找到名称/密钥的异常。我做错了什么,或者这个想法是不正确的,我应该找到另一个解决方案吗?
以下是结构:
我有两个项目:
项目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>
答案 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中。将所需的字典合并到控件的资源中。
这会增加您以前没有的依赖关系,而且它是循环的,所以尽量不要这样做。