如何引用另一个库中单独程序集中定义的WPF样式键

时间:2010-02-02 14:49:08

标签: wpf assemblies styles resourcedictionary mergeddictionaries

我有两个库和一个应用程序集程序项目布局,我想知道如何通过其中一个我在另一个库中定义的库中的键来引用样式。

我的解决方案布局:

  • WpfControls.dll - 保存通用的可重用控件,例如基于WPF的NumericUpDown控件以及其他基本控件和一些我希望可重用的样式。为了举例说明,我可以说我的样式键定义为 MyButtonStyle
  • SpecializedControls.dll - 保存专门用于我们应用程序的控件,例如WPF中的自定义复合控件和UserControls。这是我想引用WpfControls.dll程序集中定义的 MyButtonStyle 样式的地方。
  • Application.exe - 此程序集使用SpecializedControls.dll程序集中定义的控件。

我已经看到一些示例解释如何使用简单的单个控件库和应用程序组件来执行此操作,但在我的情况下,我有两个程序集和一个应用程序。所以换句话说在我的情况下,我的第二个控件库中没有App.xaml,我可以使用MergeDictionaries概念。我很确定我是否可以直接在每个控件XAML文件中放置一个MergedDictionaries引用来合并WpfControls.dll程序集中定义的所有Generic.xaml但我的猜测是这会导致样式被冗余地合并到各个地方在我的SpecializedControls程序集中,这似乎不是最好的解决方案。更糟糕的是,这些词典也可能合并到Application.exe中,这会在运行时开始膨胀我的应用程序吗?

任何人都可以用最少的编程和资源开销来澄清分享这些样式的建议或最佳方法。

更新:经过多一点测试后,即使在同一个程序集中,我也无法通过它的密钥引用Generic.xaml中定义的任何资源。关于我如何理解资源键的工作原理可能有些完全错误,因此我需要进行更多的研究以及研究ComponentResourceKey。如果有人有任何提示或建议请帮助。

2 个答案:

答案 0 :(得分:14)

WPF中的资源查找在层次结构中工作:向上逻辑树,然后是应用程序资源,主题资源,最后是系统资源。

主题资源通常只能隐式访问(即使在定义它们的程序集中)。这仅适用于样式,其中TargetType可用作隐式键。

要完成您要做的事情,有两种选择:

  • 使用 ComponentResourceKey 。这是一个特殊的资源键,允许引用其他程序集中的资源。例如,您可以在 WpfControls 主题词典中定义画笔:

    <LinearGradientBrush x:Key="{ComponentResourceKey TypeInTargetAssembly=local:MyClass, ResourceId=MyBrush}">
        <GradientStop Color="Red" />
        <GradientStop Color="Blue" Offset="1" />
    </LinearGradientBrush>
    

    然后您可以在 SpecializedControls 中引用它:

    <UserControl Background="{StaticResource {ComponentResourceKey TypeInTargetAssembly=wpfControls:MyClass, ResourceId=MyBrush}}" />
    
  • 使用 MergedDictionaries 将字典导入应用程序资源。您可以在 Application 程序集中执行此操作,并且在加载应用程序时,即使 SpecializedControls 中的控件也可以使用这些资源。在这种情况下,你会遇到设计时体验的问题,你可以通过在 SpecializedControls 中添加一个假的App.xam来解决这个问题,它也会包含对字典的引用。

希望这有帮助,

Aelij。

答案 1 :(得分:0)

接受的答案是正确的,我只是在解释如何使用 MergedDictionaries

App.xaml 中,

    <Application.Resources>
      <ResourceDictionary>
         <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/-YourDllName-;component/-DirectoryName-/FileName.xaml"/>
            <!-- Use Below syntax if your resource file is not inside a directory(in root) -->
            <ResourceDictionary Source="pack://application:,,,/-YourDllName-;component/FileName.xaml"/>
         </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
    </Application.Resources>