我创建了一个包含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>
答案 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库项目(为了添加UserControls
,Windows
,ResourcesDictionaries
等),您可以在.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 转换为一个完整的类,如 here 或 here 中所述,然后在后面的代码中强制将 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();
}
}
}