【问题标题】: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 库项目(以添加 UserControlsWindowsResourcesDictionaries 等),您可以在第一个 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 很棒,对我帮助很大,但值得补充的是,如果您创建一个空文件并在其中添加资源标签,您还应该转到文件属性,设置 BuildActionResource复制到...不复制 并清除已设置的 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 转换为完整的类,如 herehere 中所述,然后在使用任何 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
                  相关资源
                  最近更新 更多