【问题标题】:How to organize resources (styles, ...) in a complex WPF scenario?如何在复杂的 WPF 场景中组织资源(样式、...)?
【发布时间】:2013-02-21 08:53:37
【问题描述】:

如何组织 WPF 资源(包括样式、模板等),以便我可以跨 Windows、页面甚至项目使用它们。为了实现资源的最大可重用性和可维护的结构(例如每个模板一个文件),我必须采取哪些选项?

例如:我正在创建一个 WPF 应用程序,我想使用 TabControl,但我想对其进行重大更改。所以我可以在其中创建一个样式并将其应用于 TabControl 和 TabItem。没关系,但是我可以在哪里放置资源以保持 Window XAML 清晰并让其他 Windows 或项目也可以访问该样式?

我发现我可以将它添加到 App.xaml 中,但这只是一个项目的解决方案,并且只允许在该项目的项目之间共享。另外,我认为将这些模板与其他代码分开一点会更好,而不是将它们全部放在某个页面或 app.xaml 中?

【问题讨论】:

  • 您可以创建一个 ResourceDictionary 并将其添加到 ClassLibrary。您必须在 App.xaml 中引用它,并且可以在许多项目中使用该库

标签: c# wpf templates styles


【解决方案1】:

我通常创建一个单独的样式项目,我从我想要样式的项目中引用它。样式项目具有如下固定结构:

对于每个控件,我都会创建一个样式ResourceDictionary。例如对于我的按钮:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="PrimaryButtonStyle" TargetType="Button">
    </Style>

    <Style x:Key="ToolbarButton" TargetType="Button">
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Margin" Value="3"/>
        <Setter Property="Background" Value="Transparent"></Setter>
    </Style>
</ResourceDictionary>

在一个主要的ResourceDictionary 中,我合并了所有其他字典,在本例中是 IncaDesign.xaml 文件,您可以在上图中看到:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="clr-namespace:Commons.Controls;assembly=Commons">

    <ResourceDictionary.MergedDictionaries>

        <ResourceDictionary Source="Converter/Converter.xaml" />
        <ResourceDictionary Source="Styles/Button.xaml" />
        <ResourceDictionary Source="BitmapGraphics/Icons.xaml" />

    </ResourceDictionary.MergedDictionaries>

    <!-- Default Styles -->
    <Style TargetType="Button" BasedOn="{StaticResource PrimaryButtonStyle}"></Style>
</ResourceDictionary>

请注意我是如何定义默认样式的,它们会自动应用,除非您另外指定。在您想要设置样式的每个窗口或控件中,您只需要引用这个ResourceDictionary。注意源的定义,它是对程序集的引用(/Commons.Styling;component...

<UserControl.Resources>        
    <ResourceDictionary>            
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Commons.Styling;component/IncaDesign.xaml" />
        </ResourceDictionary.MergedDictionaries>   
    </ResourceDictionary>        
</UserControl.Resources>

现在将自动设置默认样式,如果您想显式访问资源,可以使用 StaticResource 来执行此操作。

<Viewbox Height="16" Width="16" Margin="0,0,10,0">
    <ContentControl Content="{StaticResource FileIcon32}" />
</Viewbox>

在我看来,这是一个非常好的解决方案,它适用于非常复杂的解决方案,包括模块化解决方案,例如使用 PRISM 构建的解决方案。

【讨论】:

  • 请记住,ResourceDictionary 实例资源繁重,如果可能,您最好避免使用它们。 See VI.
  • 最重要的是避免字典的交叉引用和不系统的合并。这才是真正引起麻烦的原因,因为您一直在创建所有资源的副本,而不是 ResourceDictionary 本身。我认为这就是重点,您链接的文章指的是。我没有看到在复杂项目中避免 ResourceDictionaries 的方法......这正是样式项目的想法:避免在许多地方合并字典......
  • 正是我想要的 :) 谢谢。我只是必须阅读更多关于这可能存在的问题。
  • 这是一个老问题/答案,但您的常见项目使用什么项目类型?
  • @Wbuck 它是一个类库。只需将所需的引用添加到 PresentationCore、PresentationFramework、System.Xaml、WindowsBase,它应该可以正常工作。
【解决方案2】:

ResourceDictionary 代表您正在寻找的内容。

Here is an explanation for how to use them within and across projects.

【讨论】:

  • 链接已损坏。有备份吗?
【解决方案3】:

您可以在您的解决方案或单独的解决方案中创建一个包含资源字典的项目。您的项目将是类库类型,然后可以轻松地从任何其他项目引用 .dll。这是一篇描述这一点的文章:Resource Dictionary Article

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 2019-01-29
    • 2014-01-27
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    相关资源
    最近更新 更多