我创建了一个类库,其中包含 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>
创建一个像这样的资源字典
<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>
要将经典库项目转换为 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>
<!-- ... -->
@punker76 的 answer 很棒,对我帮助很大,但值得补充的是,如果您创建一个空文件并向其中添加资源标签,您还应该转到文件属性,将 BuildAction 设置为 Resource,复制到... 到请勿复制 并清除 CustomTool 属性(如果已设置)。
在我看来,问题是关于将 WPF 资源字典文件添加到类库项目中。答案是,您无法对经典的 Class Library 执行此操作,但对于 WPF Application 项目、WPF Custom Control Library 项目或 WPF User Control Library 则无法执行此操作。对于这些项目类型,您可以添加新的资源字典 (WPF),该选项可通过向项目添加新项目来使用。
在我看来,实际的问题标题和问题本身与接受的答案不符。
如果您在尝试创建字典时找不到资源字典 (WPF) 文件类型,请执行以下操作:
将以下行添加到项目文件 (.csproj) 的第一个
<PropertyGroup>
元素中:
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
重新加载项目。现在您应该拥有普通 WPF 项目中可以找到的所有项目类型,包括 资源字典 (WPF)。
是的。 您可以将
ResourceDictionary
直接添加到您的项目中。
当您想要使用它时,您可以根据需要将其合并到 XAML 中,方法是使用 MergedDictionaries 将独立的
ResourceDictionary
“合并”到该类型的资源中(即:Window
或 UserControl
)。
因为我还不能发表评论,但我现在已经使用了这个答案两次:
添加 nmariot 的答案:
提示1
从 Visual Studio 访问 .csproj 文件
右键单击项目 -> 单击“卸载项目”
右键单击项目[处于卸载状态]->单击“编辑'filename.csproj'”
提示2
添加资源字典后避免错误警告:
添加对 System.Xaml 的引用
我刚刚在一个以前是Windows应用程序的项目中遇到了同样的问题,然后我变成了一个类库(我删除了默认的App.xaml)。我尝试了上面的所有答案,并设法让我的 Visual Studio 让我从解决方案资源管理器创建资源字典。就我而言,我的 WPF UI 是从另一个 UI 启动的,因此我使用了
Application.Run(myMainWindow)
。
到目前为止一切顺利。但后来我发现,由于资源字典没有通过 App.xaml 添加到资源层次结构的顶部,因此我必须在数百个 .xaml 文件中添加对资源字典的引用(或者至少我不能使用 xaml 使其以任何其他方式工作)。因此,我找到了一种使用背后代码来解决我的案例的解决方法,这可能会对某人有所帮助。
这个想法只是将 ResourceDictionary 转换为完整的类,如 here 或 here 中所述,然后在使用这些资源的任何 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());
}