Wpf合并的资源字典无法从app.xaml中识别

J K*_*ing 21 .net wpf xaml resourcedictionary

我有一个WPF .net 4.5应用程序,我在合并资源字典时遇到问题.

我有与此问题本问题完全相同的问题,但接受的解决方案对我不起作用.

我在app.xaml中声明了一个资源字典,如下所示(为简洁起见,简化):

<Application.Resources>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Skin/ResourceLibrary.xaml" />              
            <ResourceDictionary Source="Skin/Brushes/ColorStyles.xaml" />               
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>               
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

问题: 应用程序可以在app.xaml中列出时"查看"ColorStyles dictonary,但是如果我将其移动/嵌套在ResourceLibrary.xaml中,则应用程序不会"看到"ColorStyles.xaml以及有关缺少静态资源的错误出现.

以下是我创建ResourceLibrary.xaml字典的方法(简化):

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ResourceDictionary.MergedDictionaries>

        <!--  BRUSHES AND COLORS  -->
        <ResourceDictionary Source="Brushes/ColorStyles.xaml" />

    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)

更改原因:我当前的资源字典组织很糟糕,我需要更改它(因为我不止一次创建对象).我希望在"Skin"文件夹中有一个资源字典,然后在子文件夹中组织剩余的样式字典,这些字典将全部合并到ResourceLibrary.xaml文件中,而后者将在app.xaml中调用.

我尝试过: 是的我尝试使用上面链接中的解决方案:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Skin/ResourceLibrary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <!-- Dummy Style, anything you won't use goes -->
        <Style TargetType="{x:Type Rectangle}" />
    </ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

但我在虚拟样式行上得到以下错误:

错误2属性元素不能位于元素内容的中间.它们必须在内容之前或之后.

由于lisp注释,将代码更改为以下内容消除了上述错误:

<Application.Resources>
    <ResourceDictionary>
        <!--Global View Model Locator-->
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />

        <!-- Dummy Style, anything you won't use goes -->
        <Style TargetType="{x:Type Rectangle}" />

        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Skin/ResourceLibrary.xaml"></ResourceDictionary>             
            <ResourceDictionary Source="Skin/Brushes/ColorStyles.xaml" />
            <ResourceDictionary Source="Skin/NamedStyles/AlertStyles.xaml" />

        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>               
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

但资源库仍未被调用.

我还尝试更改所有文件路径以打包URI,但这也没有解决问题.

我尝试将resourceLibrary.xaml和其他资源字典移动到不同的类库项目中(使用与上面相同的文件夹结构和文件).然后我使用了以下URI,但我仍然无法访问ResourceLibrary.xaml文件中声明的资源.

<ResourceDictionary Source="pack://application:,,,/FTC.Style;component/ResourceLibrary.xaml" />
Run Code Online (Sandbox Code Playgroud)

但同样,如果我使用上面的UIR格式将每个资源字典添加到App.Xaml文件中,则资源可用.

错误消失了,但我仍然无法使用资源作为ResourceLibrary.xaml文件中合并字典的一部分.我倾向于同意关于我是否应该使用这种方法的评论,但我想弄明白,因为这个问题的最常见解决方案(参见本文顶部的链接)不起作用,也许这个解决方案可以帮助别人.

问题: 为什么ResourceLibrary.xaml文件被忽略?

lis*_*isp 26

我对MergedDictionaries有一个大问题,我相信你的问题是一样的.我希望我的ResourceDictionaries能够正确组织,这对我来说意味着有单独的Buttons.xaml,TextBoxes.xaml,Colors.xaml等等.我将它们合并到Theme.xaml中,通常所有样式都处于单独的程序集中(这样我就可以轻松切换主题).我的ApplicationResources如下:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/DefaultTheme;component/Theme.xaml" />
    </ResourceDictionary.MergedDictionaries>
    <Style TargetType="{x:Type Ellipse}"/>
  </ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

并且在主应用程序组件中定义的.xamls中的每个StaticResource工作,默认样式的工作归功于虚拟样式. 什么不起作用的是Theme里面的.xamls之间的StaticResources.如果我使用Colors.xaml中的StaticResource在Buttons.xaml中定义一个Style,我会收到有关StaticResources和UnsetValue的错误.如果我将Colors.xaml添加到Application MergedDictionaries,它就可以工作.

解决方案0

放弃组织.将所有内容放在一个.xaml中.我相信,由于MergedDictionaries存在所有"问题",因此通常应该使用ResourceDictionaries(对我而言,这将是一场噩梦).

解决方案1

将主题内的所有cross-xaml StaticResource引用更改为DynamicResource.它的工作原理是价格,因为DynamicResources比StaticResources"更重".

解决方案2

在使用另一个.xaml中的StaticResources的每个Theme .xaml中,将另一个ResourceDictionary添加到MergedDictionaries.这意味着Buttons.xaml,TextBoxes.xaml和其他人在MergedDictionaries中会有Colors.xaml.它将导致Colors ResourceDictionary以多个副本存储在内存中.为避免这种情况,您可能需要查看SharedResourceDictionary.

解决方案3

通过不同的ResourceDictionaries设置,我提出了不同的嵌套理论:

如果在上面的.xaml或此ResourceDictionary的MergedDictionaries中找不到StaticResource,则会在其他顶级MergedDictionaries中搜索它.

我宁愿只向ApplicationResources添加一个.xaml,但我通常最终使用两个 .xaml .您不必在Theme中添加每个.xaml的ApplicationResources,例如 - Controls.xaml(使用任何类型的MergedDictionaries嵌套,但不允许在Controls.xaml的字典之间进行交叉引用)和Common.xaml其中包含所有常见的控件资源.在Common.xaml的情况下,也允许嵌套,但是没有交叉引用,不能使用Colors作为StaticResources的单独Colors.xaml和Brushes.xaml - 那么你必须将3 .xamls添加到Application MergedDictionaries.

现在我总是使用第三种解决方案,但我认为它并不完美,仍然想知道是否有更好的方法.我希望我正确地解释了你所描述的和我一样的问题.

  • @JKing 1 :(我正在使用VS2010)当我签入属性时,输出类型是"类库",但是通过AssemblyInfo.cs中存在的ThemeInfo属性来判断,当我创建这个项目时,我必须选择一些与wpf相关的选项.(当我以前寻找更好的解决方案时,我尝试了其他的东西:Generic.xaml应该是特殊的,但它没有解决我的问题,我必须尝试过属性和属性 - 无济于事) (2认同)
  • @JKing 2:我很少把DataTemplates放在我的主题中,但你的观点是肯定的.您始终要做的是将所有资源分成几层.在第一层中没有对其他.xamls的StaticResource引用,在第二层中只能引用第一层,依此类推.也许你最终会有三个或更多.当我说我使用第三种解决方案时,我想我过于简化,实际上我使用的是0,1和3.我的第一层主要是颜色和画笔,也许还有一些非常基本的样式,所有这一切都在一个. xaml(解决方案0).... (2认同)
  • @JKing2 ...当我不想弄乱我的组织或者不能轻易地分成层时,我偶尔会切换到DynamicResource(解决方案2).我不知道在Application.xaml中有很多链接是不鼓励的.我不知道任何指导方针.您的基本问题是:一个文件或MergedDictionaries.我猜你会把所有东西放在一个文件中(取决于你拥有多少资源),从而获得(略微或显着)更好的性能,但对我来说,单独的文件是必须的.... (2认同)
  • @JKing ...然后:在App或主题中合并?当您在App中合并所有内容时,您可以避免大多数问题,但我希望我的主题可以重复使用(通过不同的应用程序),因此当我向主题添加新的.xaml时,我不必更新每个应用程序.这就是为什么我想尽可能少的应用程序中的字典,这就是为什么我不认为第三个解决方案完美 - 因为我希望能够在应用程序中只添加一个字典以使一切工作. (2认同)