将ResourceDictionary添加到类库中

问题描述 投票:0回答:8

我创建了一个类库,其中包含 WPF Windows 和一些从我的 C# 类继承的用户控件,这些控件可以帮助我自定义某些 WPF 控件。

现在我想添加 ResourceDictionary,以帮助我在 wpf 类之间共享样式。可以吗?

谢谢。


编辑: 资源字典文件位于 MY.WpfPresentation.Main 项目(名为 Styles.xaml):

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
                xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys"
                xmlns:MYNetMisc="clr-namespace:MY.Net.Misc;assembly=MY.Net"
                >
    <Style x:Key="customRowStyle" BasedOn="{StaticResource {dxgt:GridRowThemeKey ResourceKey=RowStyle}}" TargetType="{x:Type dxg:GridRowContent}">
        <Setter Property="Foreground" Value="{Binding Path=DataContext.balance, Converter={MYNetMisc:BalanceToColor OnlyNegative=false}}" />
    </Style>
</ResourceDictionary>

使用方法:

<MYNetPresentation:frmDockBase.Resources>       
    <ResourceDictionary x:Key="style">
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MY.WpfPresentation.Main;component/Styles.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
    <DataTemplate x:Key="TabTemplate">
        <dxlc:LayoutControl Padding="0" ScrollBars="None" Background="Transparent">
            <Image Source="/Images/Icons/table-32x32.png" Width="12" Height="12" />
            <TextBlock Text="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Center" />
        </dxlc:LayoutControl>
    </DataTemplate>

</MYNetPresentation:frmDockBase.Resources>
c# wpf class-library resourcedictionary
8个回答
35
投票

创建一个像这样的资源字典

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <!-- Common base theme -->
      <ResourceDictionary Source="pack://application:,,,/Another.AssemblyName;component/YourResDictionaryFolder/OtherStyles.xaml" />
      <ResourceDictionary Source="pack://application:,,,/Another.AssemblyName;component/YourResDictionaryFolder/AnotherStyles.xaml" />
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>

  <!-- store here your styles -->

</ResourceDictionary>

你可以把它放在你想要的地方

<Window x:Class="DragMoveForms.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window2"
        Height="300"
        Width="300">

  <Window.Resources>
    <ResourceDictionary Source="pack://application:,,,/Your.Base.AssemblyName;component/YourResDictionaryFolder/Dictionary1.xaml" />
  </Window.Resources>

  <Grid>

  </Grid>
</Window>

19
投票

要将经典库项目转换为 WPF 库项目(为了添加

UserControls
Windows
ResourcesDictionaries
等),您可以在第一个 PropertyGroup 节点的 .csproj 文件中添加以下 XML:

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

完整示例:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
    <PropertyGroup>
      <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
      <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
      <ProjectGuid>{50E8AAEA-5CED-46BE-AC9A-B7EEF9F5D4C9}</ProjectGuid>
      <OutputType>Library</OutputType>
      <AppDesignerFolder>Properties</AppDesignerFolder>
      <RootNamespace>WpfApplication2</RootNamespace>
      <AssemblyName>WpfApplication2</AssemblyName>
      <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
      <FileAlignment>512</FileAlignment>
      <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
      <WarningLevel>4</WarningLevel>
      <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
      <TargetFrameworkProfile />
    </PropertyGroup>
    <!-- ... -->    

17
投票

@punker76 的 answer 很棒,对我帮助很大,但值得补充的是,如果您创建一个空文件并向其中添加资源标签,您还应该转到文件属性,将 BuildAction 设置为 Resource复制到...请勿复制 并清除 CustomTool 属性(如果已设置)。


14
投票

在我看来,问题是关于将 WPF 资源字典文件添加到类库项目中。答案是,您无法对经典的 Class Library 执行此操作,但对于 WPF Application 项目、WPF Custom Control Library 项目或 WPF User Control Library 则无法执行此操作。对于这些项目类型,您可以添加新的资源字典 (WPF),该选项可通过向项目添加新项目来使用。

在我看来,实际的问题标题和问题本身与接受的答案不符。


5
投票

如果您在尝试创建字典时找不到资源字典 (WPF) 文件类型,请执行以下操作:

将以下行添加到项目文件 (.csproj) 的第一个

<PropertyGroup>
元素中:

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

重新加载项目。现在您应该拥有普通 WPF 项目中可以找到的所有项目类型,包括 资源字典 (WPF)


2
投票

是的。 您可以将

ResourceDictionary
直接添加到您的项目中。

当您想要使用它时,您可以根据需要将其合并到 XAML 中,方法是使用 MergedDictionaries 将独立的

ResourceDictionary
“合并”到该类型的资源中(即:
Window
UserControl
)。


1
投票

因为我还不能发表评论,但我现在已经使用了这个答案两次:

添加 nmariot 的答案:


提示1

从 Visual Studio 访问 .csproj 文件

右键单击项目 -> 单击“卸载项目”

右键单击项目[处于卸载状态]->单击“编辑'filename.csproj'”

提示2

添加资源字典后避免错误警告:

添加对 System.Xaml 的引用


0
投票

我刚刚在一个以前是Windows应用程序的项目中遇到了同样的问题,然后我变成了一个类库(我删除了默认的App.xaml)。我尝试了上面的所有答案,并设法让我的 Visual Studio 让我从解决方案资源管理器创建资源字典。就我而言,我的 WPF UI 是从另一个 UI 启动的,因此我使用了

Application.Run(myMainWindow)

到目前为止一切顺利。但后来我发现,由于资源字典没有通过 App.xaml 添加到资源层次结构的顶部,因此我必须在数百个 .xaml 文件中添加对资源字典的引用(或者至少我不能使用 xaml 使其以任何其他方式工作)。因此,我找到了一种使用背后代码来解决我的案例的解决方法,这可能会对某人有所帮助。

这个想法只是将 ResourceDictionary 转换为完整的类,如 herehere 中所述,然后在使用这些资源的任何 xaml 之前的代码后面强制将 RD 实例添加到资源层次结构的顶部创建后,模拟 App.xaml 会执行的操作。这样应用程序中的所有以下 WPF 都将继承这些样式,并且不需要进一步引用。

它的优点是,如果您更改resourceDictionary的位置,则不必更改所有路径(尽管如果您将RD称为完整类,则也不必这样做,如here中所示) ).

但是如果直接使用

Application.Run(myMainWindow)
,资源不会在编辑时解析,这非常烦人,所以我通过启动一个从 Application 派生的类以及关联的 xaml 并引用那里的 RD 来解决这个问题(如默认的 App.xaml 会执行此操作)。 请注意,对 RD 的引用都是必要的,一个用于运行时,另一个用于编辑时间。

App.xaml 看起来像:

   <!-- App.xaml emulation-->
     <Application x:Class="myNamespace.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-myNamespace">    
        <Application.Resources>       
            <ResourceDictionary >
                <ResourceDictionary.MergedDictionaries>
                   <ResourceDictionary Source="MyStyles.xaml"/>
                </ResourceDictionary.MergedDictionaries>
             </ResourceDictionary>
        </Application.Resources>
    </Application>

   //App.xaml.cs
   using System.Windows;
   namespace myNamespace
   {
      public partial class App : Application
      {
        protected override void OnStartup(StartupEventArgs e) 
        {
            //Custom startup code here           
            base.OnStartup(e);
        }
      }
    }

和 ResourceDictionary 类似:

   <!-- MyStyles.xaml -->
     <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:myNamespace"
                    x:Class="myNamespace.MyStyles"
                    x:ClassModifier="public">

        <!-- All my styles in here -->

     </ResourceDictionary>

   //MyStyles.xaml.cs
   using System.Windows;
   namespace myNamespace
   {
     public partial class MyStyles: ResourceDictionary
     {
        public MyStyles()
        {
            InitializeComponent();
        }
     }
   }

最后启动 GUI:

        public static void LaunchMainWindow()
        {                 
            App app = new App();

            //This sets the ResourceDict at the top of the hierarchy
            app.Resources.MergedDictionaries.Add(new MyStyles());
           
            app.Run(new myMainWindow());
        }

© www.soinside.com 2019 - 2024. All rights reserved.