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

Lib*_*tal 14 c# wpf templates styles

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

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

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

Mar*_*arc 35

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

造型项目

对于每个控件,我都会创建一个样式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>
Run Code Online (Sandbox Code Playgroud)

在一个主要内容中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>
Run Code Online (Sandbox Code Playgroud)

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

<UserControl.Resources>        
    <ResourceDictionary>            
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Commons.Styling;component/IncaDesign.xaml" />
        </ResourceDictionary.MergedDictionaries>   
    </ResourceDictionary>        
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)

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

<Viewbox Height="16" Width="16" Margin="0,0,10,0">
    <ContentControl Content="{StaticResource FileIcon32}" />
</Viewbox>
Run Code Online (Sandbox Code Playgroud)

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

  • 最重要的是避免交叉引用和字典的非系统合并.这是真正导致麻烦的原因,因为您始终创建所有资源的副本,而不是ResourceDictionary本身.我认为这就是重点,你所链接的文章指的是这一点.我没有看到在复杂项目中避免使用ResourceDictionaries的方法......这正是样式项目的想法:避免在很多地方合并字典...... (3认同)