13

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

我的解决方案布局:

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

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

任何人都可以澄清以最少的程序和资源开销共享此类样式的推荐或最佳方法吗?

更新:经过更多测试后,即使在同一个程序集中,我似乎也无法通过它的键来引用 Generic.xaml 中定义的任何资源。我如何理解资源密钥的工作方式可能完全错误,因此我必须进行更多研究并研究 ComponentResourceKey。如果有人有任何提示或建议,请提供帮助。

4

2 回答 2

15

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

主题资源通常只能被隐式访问(即使在它们被定义的程序集中)。这仅与 Styles 相关,其中 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将字典导入应用程序资源。您可以在应用程序程序集中执行此操作,当应用程序加载时,即使是SpecializedControls中的控件也可以使用这些资源。在这种情况下,您将遇到设计时体验问题,您可以通过在SpecializedControls中放置一个假 App.xaml 来解决该问题,该 App.xaml还包含对字典的引用。

希望这可以帮助,

埃利杰。

于 2010-02-18T14:34:29.210 回答
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>
于 2019-02-06T11:47:02.507 回答