WPF 给类库设置设计时使用的资源字典
在开发 WPF 类库时,由于类库里面没有存在 App.xaml.cs 文件,而在对单个 XAML 进行开发时,设计器将会因为找不到资源文件的存在,而拿不到资源。本文告诉大家简单的方法,给设计器设置仅在设计时引用的资源
在 WPF 的 XAML 中,如果对每个 XAML 控件都引用相同的资源,此时设计时将可以愉快的跑起来,然而在运行时将会重复创建资源影响性能。在开发 WPF 应用时,在入口项目里面,因为入口处有 App.xaml 文件,在这个文件里面加上了各个项目的引用,此时设计器就能知道当前项目引用的 XAML 资源字典,因此设计器就能工作
但是在开发类库的时候,类库不知道最终的入口项目是哪个,因此也就不知道当前程序在运行的时候,将会找不到引用
最佳的方法是和 Blend 一样,在设计时让设计器引用上某些资源,这样设计器就能工作
实现方法是在类库里面添加特殊的文件,这个特殊的文件有文件夹和命名的要求,这是在 VisualStudio 的设计器里面写常量固定的路径
在项目里面新建 Properties 文件夹,在 Properties 文件夹里面新建 DesignTimeResources.xaml 资源字典文件,大概如下

这个文件的命名规则是有约定的,不推荐自己修改。在 csproj 上添加如下代码
<ItemGroup>
<Page Update="Properties\DesignTimeResources.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>
</ItemGroup>
上面代码核心就是 ContainsDesignTimeResources 这个属性。理论上可以给任意的 xaml 文件设置这个属性,但是 XAML 设计器在很多 VS 版本上只读取此路径的文件
在 DesignTimeResources.xaml 资源字典添加对其他资源字典的引用,即可实现让类库的设计器找到资源,而在运行时是不会加载资源到内存
例如我新建了类库项目 JeenalerenenearWerjilakaw 项目。我在 JeenalerenenearWerjilakaw 项目里面添加了资源字典 ColorBrushResourcesDictionary.xaml 资源字典,在里面存放颜色画刷,代码如下
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:JeenalerenenearWerjilakaw">
<SolidColorBrush x:Key="Brush.ColorBrush.ThemeColorBrush">#FF565656</SolidColorBrush>
</ResourceDictionary>
而我期望在 JeenalerenenearWerjilakaw 项目的自定义控件 UserControl1.xaml 上使用这个 Brush.ColorBrush.ThemeColorBrush 资源,如下面代码
<Grid>
<Border Background="{StaticResource Brush.ColorBrush.ThemeColorBrush}" Margin="10,10,10,10"></Border>
</Grid>
此时的设计器和代码都不能工作,将会在设计器提示找不到资源

接下来新建 Properties\DesignTimeResources.xaml 资源字典文件,在这个资源字典文件里面添加如下代码
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../ColorBrushResourcesDictionary.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
在 JeenalerenenearWerjilakaw 的 csproj 添加如下代码
<ItemGroup>
<Page Update="Properties\DesignTimeResources.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>
</ItemGroup>
当前的 csproj 的所有代码看起来如下
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Page Update="Properties\DesignTimeResources.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>
</ItemGroup>
</Project>
以上代码是用在 SDK 风格的 csproj 文件上,如果当前项目文件非 sdk 风格,请参阅 从以前的项目格式迁移到 VS2017 新项目格式
接下来保存代码,然后关闭 VisualStudio 清理缓存文件,打开 VisualStudio 可以看到,当前设计器和代码都能工作

WPF Design Time Support (Part 2) · jbe2277/waf Wiki
然而在有 Resharper 的 VisualStudio 上,这个配置在 Resharper 2020 的一些版本是不认识的,此时将会让 Resharper 找不到资源引用,而没有自动跳转和补全的功能。好在 Resharper 对于项目格式的支持不够好,咱可以使用黑科技来解决此问题。在 Resharper 的 2021 版本也修了这个问题,因此在新版本的 Resharper 是不需要加以下代码
在 Resharper 中,将会根据 ApplicationDefinition 定义去读取应用资源文件,但是在读取时将会忽略 Condition 内容。于是咱就可以尝试创建一个叫 App_MakeReshaperHappy.xaml 的文件,用来让 Resharper 开森。在 csproj 中添加如下代码,用来引用应用资源,但实际上又不会用上此资源
<ApplicationDefinition Include="App_MakeReshaperHappy.xaml" Condition="false">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
上面代码中,使用了 Condition 为 false 让构建时实际忽略了此文件,否则将会在构建时报告不能在 WPF 类库中定义 ApplicationDefinition 元素。为什么不能叫 App.xaml 文件?原因是在 SDK 风格的 csproj 中,默认将会加上 EnableDefaultApplicationDefinition 自动加上默认的 ApplicationDefinition 元素。只要有文件叫 App.xaml 的,那么将会自动识别为 ApplicationDefinition 元素,此元素将会让 WPF 构建时报告不能在类库中定义。而如果设置 EnableDefaultApplicationDefinition 为 false 那 Resharper 又会不认此文件,经过了 lsj 工具人的摸索,发现使用上文方法是最稳的
在 App_MakeReshaperHappy.xaml 文件里面存放以下代码,用来让 Resharper 智能感知能在设计时找到资源
<Application x:Class="App_MakeReshaperHappy" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--这个文件只是为了让Reshaper的智能感知开心-->
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--以下替换为你自己的路径,我推荐引用的是设计时资源文件-->
<ResourceDictionary Source="Properties/DesignTimeResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
以上代码必须要自己定义类型,然后继承 Application 同时有 x:Class 内容才可以。这个文件的文件名和类名要求一定包含 App 这三个字符,同时文件名和类名需要相同
WPF 给类库设置设计时使用的资源字典的更多相关文章
- WPF获取和设置应用程序范围的资源
设置资源: Application.Current.Resources["ApplicationScopeResource"] = Brushes.White; 使用代码获取资源: ...
- 【WPF学习】第三十五章 资源字典
如果希望在多个项目之间共享资源,可创建资源字典.资源字典只是XAML文档,除了存储希望使用的资源外,不做其他任何事情. 一.创建资源字典 下面是一个资源字典示例,它包含一个资源: <Resour ...
- [WPF 学习] 3.用户控件库使用资源字典的困惑
项目需要(或者前后端分离的需要),前端我使用了用户控件库,由后端用代码加载和控制. 然而用户控件库没法指定资源字典,于是在用户控件的xaml文件里面手工添加了资源字典 <UserControl. ...
- wpf控件设计时支持(3)
原文:wpf控件设计时支持(3) wpf设计时调试 编辑模型 装饰器 1.wpf设计时调试 为了更好的了解wpf设计时框架,那么调试则非常重要,通过以下配置可以调试控件的设计时代码 (1)将启动项目配 ...
- WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口
原文:WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口 当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口.但是,如果直接判断是否是 W ...
- WPF 引用第三方库的控件在设计器加上设计时数据和属性
本文告诉大家如何在 VisualStudio 2022 的 XAML 设计器中,在设计时给第三方控件加上设计用的属性和数据的方法 此功能要求使用不低于 VisualStudio 2019 的 16.8 ...
- wpf控件设计时支持(1)
原文:wpf控件设计时支持(1) 这部分内容几乎是大家忽略的内容,我想还是来介绍一下. 本篇源码下载 1.属性元数据 在vs IDE中,在asp.net,winfrom等开发环境下,右侧的Proper ...
- wpf控件设计时支持(2)
原文:wpf控件设计时支持(2) 这篇介绍在wpf设计时集合项属性添加项的定义和自定义控件右键菜单的方法 集合项属性设计时支持 1.为集合属性设计器识别具体项类型 wpf设计器允许定义集合项的类型,如 ...
- [No0000AE]在 Visual Studio 中调试 XAML 设计时异常
在 Visual Studio 中进行 WPF, UWP, Silverlight 开发时,经常会遇到 XAML 设计器由于遭遇异常而无法正常显示设计器视图的情况.很多时候由于最终生成的项目在运行时并 ...
- 在 Visual Studio 中调试 XAML 设计时异常
在 Visual Studio 中进行 WPF, UWP, Silverlight 开发时,经常会遇到 XAML 设计器由于遭遇异常而无法正常显示设计器视图的情况.很多时候由于最终生成的项目在运行时并 ...
随机推荐
- 记录--求你了,别再说不会JSONP了
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 JSONP是一种很远古用来解决跨域问题的技术,当然现在实际工作当中很少用到该技术了,但是很多同学在找工作面试过程中还是经常被问到,本文将带 ...
- 虚拟DOM的理解与总结
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 1. 对虚拟DOM的理解? 从本质上来说,Virtual Dom是一个JavaScript对象,通过对象的方式来表示DOM结构.将页面的状 ...
- 记录--短视频滑动播放在 H5 下的实现
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 短视频已经无数不在了,但是主体还是使用 app 来承载的.本文讲述 H5 如何实现 app 的视频滑动体验. 无声胜有声,一图顶百辩,且看 ...
- FFmpeg开发笔记(六)如何访问Github下载FFmpeg源码
学习FFmpeg的时候,经常要到GitHub下载各种开源代码,比如FFmpeg的源码页面位于https://github.com/FFmpeg/FFmpeg.然而国内访问GitHub很不稳定,经常打 ...
- Docker Commands Diagram
- 工具推荐-sourcetree
工具推荐-sourcetree 简介 简单好用的win系统下的git可视化软件 支持ssh免密登录 一键暂存和上传到开源仓库 开源免费 安装 下载sourcetree sourcetree下载 下载g ...
- CSP:Object as Point同会议论文,相似思想用于人脸和行人检测 | CVPR 2019
CSP将目标定义为中心点和尺寸,通过网络直接预测目标的中心和寸尺,相对于传统的RCNN类型检测算法轻量化了不少.整体思想与Object as Points撞车了,真是英雄所见略同 来源:晓飞的算法 ...
- java反序列化-CC1
CC1 目录 CC1 1.Transformer接口 2.Transformer的实现类 ConstantTransformer ChainedTransformer InvokerTransform ...
- Scala 函数至简原则
(1)return 可以省略,Scala 会使用函数体的最后一行代码作为返回值(2)如果函数体只有一行代码,可以省略花括号(3)返回值类型如果能够推断出来,那么可以省略(:和返回值类型一起省略)(4) ...
- HandlerInterceptorAdapter和HandlerInterceptor的区别
其实归根揭底一个是抽象类,一个是接口,HandlerInterceptor是接口,它提供了所有方法,让开发人员必须实现所有方法, 而HandlerInterceptorAdapter是一个抽象类,它提 ...