将 ResourceDictionary 添加到类库

发布于 2024-12-16 18:23:19 字数 1851 浏览 4 评论 0原文

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

I created a class library which is contained of WPF Windows and some user controls inherited from my c# classes that helps me to customize certain wpf controls.

Now I want to add ResourceDictionary, to help me share styles between my wpf classes. Is it possible?

Thx.


EDIT:
resource dictionary file located in MY.WpfPresentation.Main project (named 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>

using it:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

笑梦风尘 2024-12-23 18:23:19

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

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

create a resource dictionary like this one

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

and you can put it where you want

<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>
假面具 2024-12-23 18:23: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>
    <!-- ... -->    

To transform a classical library project to a WPF library project (in order to add UserControls, Windows, ResourcesDictionaries, etc.) you can add the following XML in the .csproj file in the first PropertyGroup Node :

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

Full example :

<?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>
    <!-- ... -->    
书间行客 2024-12-23 18:23:19

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

@punker76's answer is great and helped me a lot, but it's worth adding that if you create an empty file and add a resource tag into it you should also go to file properties, set BuildAction to Resource, Copy To... to Do not copy and clear CustomTool property if it's set.

染墨丶若流云 2024-12-23 18:23:19

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

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

In my opinion, the question is about adding a WPF Resource dictionary file to a Class Library project. The answer is that you can't do it for classic Class Library, but for WPF Application project, WPF Custom Control Library project or a WPF User Control Library. For these project types you can add a new Resource Dictionary (WPF), option which is available through adding new item to the project.

In my opinion the actual question title and question itself does not correspond to the accepted answer.

迷鸟归林 2024-12-23 18:23:19

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

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

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

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

If you can't find the Resource Dictionary (WPF) file type when trying to create the dictionary, do this:

Add the following line to your project file (.csproj), into the first <PropertyGroup> element:

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

Reload the project. Now you should have all the item types that can be found in a normal WPF project, including the Resource Dictionary (WPF).

晨与橙与城 2024-12-23 18:23:19

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

当您想要使用它时,可以根据需要使用 MergedDictionaries 将独立的 ResourceDictionary“合并”到该类型的资源中(即:Window用户控件)。

Yes. You can add a ResourceDictionary directly to your project.

When you want to use it, you can merge it into the XAML as needed by using MergedDictionaries to "merge" that standalone ResourceDictionary into the resources of the type (ie: the Window or UserControl).

七颜 2024-12-23 18:23:19

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

要添加到 nmariot 的答案:


提示 1

从 Visual Studio

右键单击​​项目 -> 访问 .csproj 文件单击“卸载项目”

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

提示 2

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

添加对 System.Xaml 的引用

Since i can't yet comment but i've used this answer twice now:

To add to nmariot's answer:


Tip 1

to reach the .csproj file from visual studio

right click project -> click 'unload project'

right click project [in unloaded state]-> click 'edit 'filename.csproj''

Tip 2

to avoid error warnings once resource dictionary has been added:

add reference to System.Xaml

街角迷惘 2024-12-23 18:23:19

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

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

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

它的优点是,如果您更改资源字典的位置,则不必更改所有路径(尽管如果您将 RD 引用为完整类,则不必这样做,如 此处)。

但是如果你直接使用Application.Run(myMainWindow),资源不会在编辑时解析,这很烦人,所以我通过启动一个派生的类来解决这个问题具有关联 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());
        }

I just came across the same problem in a project that was previously a Windows Application and then I turned into a Class Library (where I deleted the default App.xaml). I tried all the answers above and I managed to get my Visual Studio to let me create a Resource Dictionary from the Solution Explorer. In my case, my WPF UI was being launched from another so I made use of Application.Run(myMainWindow).

So far so good. But then I discovered that, as the resource dictionary was not being added through the App.xaml to the top of the resources hierarchy, I had to add a reference to the resourceDictionary in hundreds of .xaml files (or at least I couldn't make it work any other way using xaml). So I found a workaround for my case using code behind that may help someone.

The idea is just to convert the ResourceDictionary into a full class as explained in here or here and then force to add an instance of the RD to the top of the resources hierarchy in code behind before any xaml that uses these resources is created, emulating what App.xaml would have done. This way all the following WPF within the Application will inherit these styles and no further references are needed.

It has the advantage that if you change the location of your resourceDictionary, you don't have to change all paths (althougth you don't have to do it either if you refer to the RD as a full class as in here).

BUT if you use Application.Run(myMainWindow) directly, resources are not resolved on edition time, which is quite annoying, so I worked around it by launching a class derived from Application with an associated xaml and referencing the RD there as well (as the default App.xaml does). Note that both references to the RD are necessary, one for run time and the other one for edition time.

The App.xaml would look something like:

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

and

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

and the ResourceDictionary like:

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

and

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

And finally the GUI is launched with:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文