【问题标题】:Add ResourceDictionary to class library将 ResourceDictionary 添加到类库
【发布时间】:2011-12-31 16:44:40
【问题描述】:

我创建了一个类库,其中包含 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


    【解决方案1】:

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

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

    【讨论】:

    • 好吧,问题是当我尝试向项目添加新项目时,我没有看到 ResourceDictionary。
    • 如果您的解决方案是 wpf 解决方案 -> 在解决方案资源管理器中的项目名称处鼠标右键 -> 添加 -> 资源字典,或者您可以添加一个名为 YourName.xaml 的空文件并将 ResourceDictionary 标记放入它
    • 只有当我的项目是 WPF 应用程序时,我才能在 Add->... 上看到 ResourceDictionary。因此,我创建了新文件并将其命名为 Styles.xaml,但现在我收到异常:'Resources' 属性已设置在
    • 啊,你必须把你的datatemplate移到resourcedictionary标签里,看看你的第一篇文章
    • 很好的答案,但需要注意的是:不要在 pack:// uris 中的程序集名称中包含 .dll 扩展名。否则,您将花费大量时间试图了解它为什么不起作用
    【解决方案2】:

    要将经典库项目转换为 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>
        <!-- ... -->    
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        在我看来,问题在于将 WPF 资源字典文件添加到类库项目中。答案是经典的类库不能这样做,但是对于WPF应用程序项目、WPF自定义控件库项目或者WPF 用户控件库。对于这些项目类型,您可以添加一个新的资源字典 (WPF),该选项可通过向项目添加新项目来获得。

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

        【讨论】:

          【解决方案5】:

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

          将以下行添加到您的项目文件 (.csproj) 的第一个 &lt;PropertyGroup&gt; 元素中:

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

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

          【讨论】:

            【解决方案6】:

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

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

            【讨论】:

              【解决方案7】:

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

              补充 nmariot 的答案:


              提示 1

              从 Visual Studio 访问 .csproj 文件

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

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

              提示 2

              为了避免在添加资源字典后出现错误警告:

              添加对 System.Xaml 的引用

              【讨论】:

                【解决方案8】:

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

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

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

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

                但是如果您直接使用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());
                        }
                
                

                【讨论】:

                  猜你喜欢
                  • 2012-03-15
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-11-20
                  • 2012-03-30
                  • 1970-01-01
                  • 2017-11-24
                  相关资源
                  最近更新 更多