【问题标题】:Adding a Merged Dictionary to a Merged Dictionary将合并词典添加到合并词典
【发布时间】:2010-08-05 21:58:59
【问题描述】:

我似乎无法将合并字典添加到 XAML 中的合并字典集合中。

Theme.xaml

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/Mine;component/Themes/Palette.Blue.xaml"/>
    <ResourceDictionary Source="/Mine;component/Themes/Template.xaml"/>
</ResourceDictionary.MergedDictionaries>

应用资源

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Mine;component/Themes/Theme.xaml"/> 
            <!--
            <ResourceDictionary Source=="/Mine;component/Themes/Palette.Blue.xaml"/>
            <ResourceDictionary Source="/Mine;component/Themes/Template.xaml"/>
            -->
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

注意:如果我将两个 ResourceDictionaries 都放在 Appication.Resources MergedDictionary 中(注释掉 theme.xaml 并取消注释其他两个字典),它们都会正确加载。然而,我们资源的定义方式,这可能意味着会加载相当多的资源,而对于动态加载,我希望能够定义模板。

【问题讨论】:

  • 是theme.xaml的完整代码吗?因为我认为你只需要用 ResourceDictionary 标签开始和结束它就可以了
  • 不,它实际上已经在合并字典中了。它似乎没有继承。

标签: wpf silverlight xaml resourcedictionary


【解决方案1】:

这是一个优化bug,见this链接

关于每个对象的创建 XAML,如果存在默认样式 (即带有类型键的样式) 应该应用样式。尽你所能 想象一下有几种表现 进行优化(隐含) 查找尽可能轻的重量。一 其中一个是我们不向内看 资源字典,除非它们是 标记为“包含默认值 风格”。有一个错误:如果你的所有 默认样式嵌套在合并 字典深度三层(或 更深)顶级字典没有 被标记以便搜索跳过它。 解决方法是设置默认值 风格的东西,任何东西,在根 字典。

所以在根字典中添加一个虚拟样式可以解决这个问题。示例

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Mine;component/Themes/Theme.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <!-- Dummy Style, anything you won't use goes -->
        <Style TargetType="{x:Type Rectangle}" />
    </ResourceDictionary>
</Application.Resources>

【讨论】:

  • 我在 .NET 4 中遇到了这个确切的问题,这解决了它。
  • 出于某种原因,这对我不起作用。启动时,它会抛出一个异常(DependencyProperty.UnsetValue 对“Foreground”无效),这表明没有添加资源字典。我的设置与 .NET 4.5 上的上述代码相同。
  • 这在 VS2010 .net 4.0 中不起作用,这不会编译。错误Error 7 Property elements cannot be in the middle of an element's content. They must be before or after the content.
  • 有人知道这个错误是否在 .NET 4.5 或更高版本中得到修复? Microsoft Connect 已停用,因此我无法从提供的链接中得知。
【解决方案2】:

您的示例代码在 Palette.Blue.xaml 的 App.xaml 合并资源字典源中有一个双等号。我假设这是您在此处发布的示例的错字,但不是您的真正问题。

弄清楚如何在 XAML 中直接链接所有资源可能很棘手。最简单的方法是使用 Blend 中的资源面板。我创建了一个 Silverlight 应用,其资源文件的名称与您的示例类似,然后在 Blend 中打开该项目并很快将它们链接在一起。

App.xaml

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SilverlightApplication1.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Theme.xaml" />
                <!--
                <ResourceDictionary Source="Palette.Blue.xaml"/>
                <ResourceDictionary Source="Template.xaml"/>
                -->
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Theme.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Palette.Blue.xaml"/>
        <ResourceDictionary Source="Template.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Template.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="TextBox">
        <Setter Property="Margin" Value="10" />
        <Setter Property="Width" Value="250" />
    </Style>
    <Style x:Key="ReadOnlyTextBoxStyle" TargetType="TextBox">
        <Setter Property="IsReadOnly" Value="True" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="Margin" Value="10" />
        <Setter Property="Width" Value="250" />
    </Style>
</ResourceDictionary>

Palette.Blue.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="BlueSolidColorBrush" Color="SkyBlue" />
</ResourceDictionary>

MainPage.xaml

<UserControl x:Class="SilverlightApplication1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel x:Name="LayoutRoot" Background="Honeydew">
        <TextBox Text="Read Only Textbox"
                 Style="{StaticResource ReadOnlyTextBoxStyle}" />
        <TextBox Text="Blue Textbox"
                 Background="{StaticResource BlueSolidColorBrush}" />
        <TextBox Text="Read Only, Blue Textbox"
                 Style="{StaticResource ReadOnlyTextBoxStyle}"
                 Background="{StaticResource BlueSolidColorBrush}" />
    </StackPanel>
</UserControl>

当然,如果您要链接来自不同程序集的资源,它看起来会有所不同。实际上,在这种情况下,我建议考虑将您的字典合并到后面的代码中。

【讨论】:

  • 这显然是一个转录错误(不在实际文件中。)我知道如何单独添加每个资源(通过代码后面或创建一个新的 MergedDictionary)但问题似乎与将合并字典添加到 ResourceDictionary 作为单独合并字典的源或一部分。
  • 检查您的字典 xaml 文件的构建操作。您可能需要将其从默认页面更改为资源。
【解决方案3】:

如果这发生在您自己的一个控件上,我发现另一种解决方案是将 DefaultStyleKey 属性设置为 null:

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(null));

我不知道为什么会这样,但似乎可以!

【讨论】:

  • SO thread 解释了 OverrideMetadata 的工作原理
猜你喜欢
  • 1970-01-01
  • 2013-03-18
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
  • 2014-07-25
  • 2022-12-24
  • 1970-01-01
相关资源
最近更新 更多