在UWP中嵌套使用MergedDictionaries的ResourceDictionary

3
我正在尝试拆分一个包含多个控件样式的ResourceDictionary,该字典文件已经达到了大约3000行,变得难以管理。因此我决定将其拆分成更小、更具体的ResourceDictionaries 并使用 MergedDictionaries 进行合并。
App.xaml中实现此操作。
<common:BootStrapper x:Class="Asteria.Ion.App"
                     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     xmlns:common="using:Template10.Common"
                     xmlns:styles="using:Asteria.Ion.Styles"
                     RequestedTheme="Dark">

    <common:BootStrapper.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles\Custom.xaml" />
                <ResourceDictionary Source="Styles\CustomControls.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </common:BootStrapper.Resources>
</common:BootStrapper>

CustomControls.xaml 包含对其他 ResourceDictionaries 的引用。

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="using:Template10.Controls"
    xmlns:behaviors="using:Template10.Behaviors"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:local="using:Asteria.Ion.Styles">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Shared.xaml" />
        <ResourceDictionary Source="Templates.xaml" />
        <ResourceDictionary Source="ComponentBlock.xaml" />
        <ResourceDictionary Source="FlowAgent.xaml" />
        <ResourceDictionary Source="Planning.xaml" />
        <ResourceDictionary Source="ProjectDialog.xaml" />
        <ResourceDictionary Source="Inspector.xaml" /-->
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

这将始终产生以下异常: 无法将类型“Windows.Foundation.String”分配给类型“Windows.Foundation.Uri”,因此无法将其分配给属性“Windows.UI.Xaml.ResourceDictionary.Source”。[行:12 位置:37] 我已经尝试过多次更改源URI,但它仍然会出现此错误。只有注释掉CustomControls.xaml中的所有ResourceDictionary元素才能帮助解决问题。但这样做会导致缺少样式的异常。
我尝试过的一些URI格式如下:
  • /Styles/Shared.xaml
  • Styles/Shared.xaml
  • Styles\Shared.xaml
  • .\Shared.xaml
  • ms-appx:///Styles/Shared.xaml
没有一个有效。如果您有任何建议,将不胜感激。

我并不打算引用外部程序集中的样式。 - Wesley Vrancken
我明白了。也许你应该尝试这个语法? - stefan.s
2个回答

4
最后,这与URI结构无关,而是与ThemeDictionariesMergedDictionaries的组合有关。
先前的工作方式:
在中:
<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Styles/Themes.xaml" />
    <ResourceDictionary Source="Styles/CustomControls.xaml" />
</ResourceDictionary.MergedDictionaries>

Themes.xaml 包含 ThemeDictionaries,而 CustomControls.xaml 包含许多样式的 <Styles>

CustomControls.xaml 拆分后,它不再包含任何样式,只有 MergedDictionaries。大致如下:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="ControlStyles/ProjectDialog.xaml" />
    <ResourceDictionary Source="ControlStyles/Inspector.xaml" />
</ResourceDictionary.MergedDictionaries>

Inspector.xaml 包含一个使用 {ThemeResource}Style,这似乎是出错的原因。最终的解决方案/变通方法是在 Inspector.xaml 中包含一个对 Themes.xaml 的引用的 MergedDictionaries

现在,如果有人能够解释这个解决方案背后的确切原因,我将不胜感激。


2

根据错误信息,XAML编译器无法翻译嵌套ResourceDictionaries的Source属性。最简单和最快的解决方法是在App.Xaml.cs中添加嵌套的ResourceDictionaries:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
   ...
    var applicationMergedDics = Application.Current.Resources.MergedDictionaries;
    applicationMergedDics[0].MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("ms-appx:///Styles/Shared.xaml") });
    applicationMergedDics[0].MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("ms-appx:///Styles/Templates.xaml") });
    ...
    rootFrame.Navigate(typeof(MainPage), e.Arguments);
}

注意:不要忘记在CustomControls.xaml中删除MergedDictionaries。这样错误就会消失。


这解决了我的问题,但又引发了另一个问题。如果使用start-process从PowerShell启动应用程序,则字典不会加载,样式也不会应用。不确定以这种方式运行是否意味着未触发OnLaunched事件,但如果有任何想法,那就太好了。目前只能通过在每个样式中包含对mergedDictionary的引用来解决我的问题-并不理想。谢谢。 - Blingers
1
通过PowerShell启动UWP将触发OnActivated生命周期方法,您可以将代码放在普通函数中并将其命名为Myfunc,然后在OnLaunchedOnActivated中都调用Myfunc - Elvis Xia - MSFT
这是我最终做的事情 - 完整答案在此处:https://stackoverflow.com/questions/59138929/uwp-mergeddictionary-style-that-references-other-style-throws-error - Blingers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接