如何在复杂的 WPF 场景中组织资源(样式、...)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15249492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 07:55:13  来源:igfitidea点击:

How to organize resources (styles, ...) in a complex WPF scenario?

c#wpftemplatesstyles

提问by Libor Zapletal

How can WPF resources - including styles, templates, etc. - be organized, so that I can use them across Windows, Pages or even Projects. What options do I have to achieve maximum re-usability of my resources and a maintainable structure (for example one file per Template)?

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

For example: I am creating a WPF application and I want to use a TabControl, but I want to make major changes to it. So I could create a style in and apply it to the TabControl and TabItem. That's ok, but where can I place my resources to keep my Window XAML clear and have the style accessible from other Windows or projects as well?

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

I found that I can add it to App.xaml but that is only a solution for one project and allows sharing just between items of this project. Also, I think it would be better to have these templates a little separate from other code, than placing it all in some page or app.xaml?

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

回答by Marc

I usually create a seperate styling project, which I reference from the projects, which I want to style. The styling project has a fixed structure like this:

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

Styling project

造型项目

For every control, I create a styling ResourceDictionary. For example for my buttons:

对于每个控件,我创建了一个样式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>

In one main ResourceDictionary, I merge all the other dictionaries, in this case in the file IncaDesign.xaml, which you can see in the picture above:

在一个 main 中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>

Notice how I defined the default styles, which are applied automatically, unless you specify otherwise. In every window or control, that you want to style, you only need to reference this one ResourceDictionary. Note the definition of the source, which is a reference to the assembly (/Commons.Styling;component...)

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

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

Default styles will be set automatically now, and if you want to access a resource explicitly, you can do this, using StaticResource.

现在将自动设置默认样式,如果您想显式访问资源,可以使用StaticResource.

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

This is very nice solution in my opinion, which works for very complex solutions, including modular solutions, for example built with PRISM.

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

回答by Nathan Hillyer

A ResourceDictionaryis for what you are looking.

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

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

这里解释了如何在项目内和跨项目使用它们

回答by Michael Sanderson

You can create a project that contains Resource Dictionaries, either in your solution or in a separate one. Your project will be a Class Library type and can then easily be .dll referenced from any other project. Here is an article describing this: Resource Dictionary Article

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