在开发 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 可以看到,当前设计器和代码都能工作

本文代码放在 githubgitee 欢迎下载执行

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 这三个字符,同时文件名和类名需要相同

以上代码放在 githubgitee 欢迎下载执行

WPF 给类库设置设计时使用的资源字典的更多相关文章

  1. WPF获取和设置应用程序范围的资源

    设置资源: Application.Current.Resources["ApplicationScopeResource"] = Brushes.White; 使用代码获取资源: ...

  2. 【WPF学习】第三十五章 资源字典

    如果希望在多个项目之间共享资源,可创建资源字典.资源字典只是XAML文档,除了存储希望使用的资源外,不做其他任何事情. 一.创建资源字典 下面是一个资源字典示例,它包含一个资源: <Resour ...

  3. [WPF 学习] 3.用户控件库使用资源字典的困惑

    项目需要(或者前后端分离的需要),前端我使用了用户控件库,由后端用代码加载和控制. 然而用户控件库没法指定资源字典,于是在用户控件的xaml文件里面手工添加了资源字典 <UserControl. ...

  4. wpf控件设计时支持(3)

    原文:wpf控件设计时支持(3) wpf设计时调试 编辑模型 装饰器 1.wpf设计时调试 为了更好的了解wpf设计时框架,那么调试则非常重要,通过以下配置可以调试控件的设计时代码 (1)将启动项目配 ...

  5. WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口

    原文:WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口 当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口.但是,如果直接判断是否是 W ...

  6. WPF 引用第三方库的控件在设计器加上设计时数据和属性

    本文告诉大家如何在 VisualStudio 2022 的 XAML 设计器中,在设计时给第三方控件加上设计用的属性和数据的方法 此功能要求使用不低于 VisualStudio 2019 的 16.8 ...

  7. wpf控件设计时支持(1)

    原文:wpf控件设计时支持(1) 这部分内容几乎是大家忽略的内容,我想还是来介绍一下. 本篇源码下载 1.属性元数据 在vs IDE中,在asp.net,winfrom等开发环境下,右侧的Proper ...

  8. wpf控件设计时支持(2)

    原文:wpf控件设计时支持(2) 这篇介绍在wpf设计时集合项属性添加项的定义和自定义控件右键菜单的方法 集合项属性设计时支持 1.为集合属性设计器识别具体项类型 wpf设计器允许定义集合项的类型,如 ...

  9. [No0000AE]在 Visual Studio 中调试 XAML 设计时异常

    在 Visual Studio 中进行 WPF, UWP, Silverlight 开发时,经常会遇到 XAML 设计器由于遭遇异常而无法正常显示设计器视图的情况.很多时候由于最终生成的项目在运行时并 ...

  10. 在 Visual Studio 中调试 XAML 设计时异常

    在 Visual Studio 中进行 WPF, UWP, Silverlight 开发时,经常会遇到 XAML 设计器由于遭遇异常而无法正常显示设计器视图的情况.很多时候由于最终生成的项目在运行时并 ...

随机推荐

  1. 记录--纯CSS实现骚气红丝带

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 在本文中,我们将探讨如何使用 CSS 以最少的代码创造出精美的 CSS 丝带形状,并最终实现下面这个效果: 下面我们使用html和css来 ...

  2. 性能测试系列:Jmeter使用记录

    jmeter配置环境变量vi /etc/profileexport PATH=$PATH:/tmp/jmeter/apache-jmeter-5.4.1/binsource /etc/profile ...

  3. java 控制台 输出进度条

    效果  代码 public static void main(String[] args) { int total = 100; for (int i = 0; i < total; i++) ...

  4. 在ubuntu安装QT

    在ubuntu安装 安装motrix motrix下载 下载对应版本的QT QT下载 授权run文件 sudo chmod +x xxx.run 运行run文件 ./ xxx.run 运行界面 安装完 ...

  5. linux系统centos7.9如何安装nginx

    1.官网下载nginx nginx官网:https://nginx.org/ 选择稳定版进行下载,也可以下载老版本,下载成功后上传到服务器. 2.使用wget下载 访问nginx官网,在下载页面鼠标右 ...

  6. KingbaseES V8R3 集群运维系列 -- 修改数据库服务端口

    ​ 案例说明: KingbaseES V8R3集群数据库服务端口(默认:54321)的配置在数据库及集群多个配置文件中都存在,修改端口需要更改所有的配置文件,本案例详细描述了数据库服务端口修改操作步骤 ...

  7. Python爬虫爬取京东某商品评论信息存入mysql数据库

    1 """ 2 https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_com ...

  8. 高抗干扰抗噪,段码LCD液晶低功耗驱动IC-VK2C23B,兼容市面上16C23

    VK2C23是一个点阵式存储映射的LCD驱动器,可支持最大224点(56SEGx4COM)或者最大416点(52SEGx8COM)的LCD屏. 单片机可通过I2C接口配置显示参数和读写显示数据,也可通 ...

  9. #搜索,计算几何#JZOJ 4016 圈地为王

    题目 在\(n\)行\(m\)列的网格中,你要圈一些地. 你从左上角出发,最后返回左上角,路径内部的区域视为被你圈住. 你不可以进入网格内部, 只能在边上行走. 你的路径不能在左上角以外自交, 但是边 ...

  10. 【FAQ】关于分析服务错误获取所选日期前一天事件数据的解决方法

    开发者通过华为分析服务下载所需的事件数据,这些数据可以导入到开发者自有的分析系统中,用于构建自定义报告或生成受众群体的个性化分析等,从而帮助制定切实有效的营销活动.数据导出支持按照用户属性和导出事件作 ...