将ResourceDictionary添加到类库

时间:2011-11-17 20:12:05

标签: c# wpf class-library resourcedictionary

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

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

THX。


编辑: 位于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>

8 个答案:

答案 0 :(得分:29)

创建像这样的资源字典

<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>

答案 1 :(得分:12)

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

答案 2 :(得分:10)

在我看来,问题是将WPF资源字典文件添加到类库项目中。答案是您不能为经典类库执行此操作,但对于 WPF应用程序项目, WPF自定义控件库项目或 WPF用户控件库。对于这些项目类型,您可以添加新的资源字典(WPF)选项,该选项可通过向项目添加新项目来实现。

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

答案 3 :(得分:10)

要将经典库项目转换为WPF库项目(为了添加UserControlsWindowsResourcesDictionaries等),您可以在.csproj中添加以下XML第一个PropertyGroup节点中的文件:

<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>
    <!-- ... -->    

答案 4 :(得分:1)

是。您可以直接将ResourceDictionary添加到项目中。

当您想要使用它时,您可以根据需要将其合并到XAML中,方法是使用MergedDictionaries来&#34;合并&#34;独立ResourceDictionary到该类型的资源(即:Window或UserControl)。

答案 5 :(得分:1)

由于我还不能评论,但我现在已经两次使用这个答案了:

添加到nmariot的答案:

提示1

从visual studio

获取.csproj文件

右击项目 - &gt;点击“卸载项目”

右键单击项目[处于卸载状态] - &gt;点击'edit'filename.csproj''

提示2

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

添加对System.Xaml的引用

答案 6 :(得分:0)

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

将以下行添加到项目文件(.csproj)中的第一个<PropertyGroup>元素中:

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

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

答案 7 :(得分:0)

我刚刚在一个以前是 Windows 应用程序的项目中遇到了同样的问题,然后我变成了一个类库(在那里我删除了默认的 App.xaml)。我尝试了上面的所有答案,并设法让我的 Visual Studio 允许我从解决方案资源管理器创建一个资源字典。就我而言,我的 WPF UI 是从另一个启动的,因此我使用了 var tree = parser.getCodec().readTree(parser); var name = (TextNode) tree.get("name"); return Person.create(Name.valueOf(name.asText()));

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

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

它的优点是,如果您更改 resourceDictionary 的位置,则不必更改所有路径(尽管如果您将 RD 称为完整类,如 { {3}})。

BUT 如果直接使用 Application.Run(myMainWindow),资源不会在编辑时解析,这很烦人,所以我通过启动一个从 Application 派生的类以及关联的 xaml 来解决这个问题并在那里引用 RD(就像默认的 App.xaml 一样)。 请注意,对 RD 的两个引用都是必需的,一个用于运行时间,另一个用于编辑时间。

App.xaml 看起来像:

Application.Run(myMainWindow)

   <!-- 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>

和 ResourceDictionary 像:

   //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);
        }
      }
    }

   <!-- 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>

最后启动 GUI:

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