让你编写的控件库在 XAML 中有一个统一的漂亮的命名空间(xmlns)和命名空间前缀
原文 让你编写的控件库在 XAML 中有一个统一的漂亮的命名空间(xmlns)和命名空间前缀
在 WPF XAML 中使用自己定义的控件时,想必大家都能在 XAML 中编写出这个控件的命名空间了。然而——我写不出来,除非借助 ReSharper。
如果控件能够有一个漂亮的命名空间和命名空间前缀呢?——好吧,还是写不出来,不过,至少漂亮些。本文将指导你自定义在 XAML 中使用的命名空间。
达到什么样的效果?
<UserControl
x:Class="HuyaHearhira.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="http://walterlv.github.io/demo"
<Grid>
<w:DemoPage />
</Grid>
</UserControl>
注意到 DemoPage 所在的命名空间了吗?是 http://walterlv.github.io/demo 哦。而且,命名空间前缀是 w。这是不是比下面这种看得清爽多了呢?
<UserControl
x:Class="HuyaHearhira.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:newCsprojDemo="clr-namespace:Walterlv.NewCsprojDemo;assembly=Walterlv.NewCsprojDemo">
<Grid>
<newCsprojDemo:DemoPage />
</Grid>
</UserControl>
当然,好处不止是更清爽,还有更多,总结起来是这三个:
- 利于 API 的升级
例如你写了一个库提供了一些可以在 XAML 中使用的控件,但是后来随着功能的强大你把程序集拆分成了多个。这时,如果没有这样的命名空间定义,那就意味着使用你的库的大量开发者需要手工修改 XAML 中的命名空间前缀定义。而使用了这样的命名空间定义的方法后,开发者只需要重新编译一遍即可。 - 简化命名空间前缀
如果你的库有多个命名空间下都提供控件,那么可以使用命名空间定义将这些 C#/.NET 命名空间都映射到同一个 url 下,使得 XAML 中的命名空间声明可以更少。 - 更加清晰的命名空间声明 可以通过将命名空间前缀定义得更加清晰,更有效地利用每一个字符,而不是一些结构化的
clr-namespace和assembly。
这是怎么做到的呢?
在 System.Windows.Markup 命名空间下,有两个程序集级别的 Attribute,分别是 XmlnsDefinition 和 XmlnsPrefix。XmlnsDefinition 定义某个 C# 命名空间和一段命名空间字符串是等意的,XmlnsPrefix 定义此命名空间的默认前缀(只是默认而已)。
using System.Windows.Markup;
[assembly: XmlnsDefinition("http://walterlv.github.io/demo", "Walterlv.NewCsprojDemo")]
[assembly: XmlnsPrefix("http://walterlv.github.io/demo", "w")]
于是,利用这两个 Attribute 能够达到本文一开始的奇妙的效果。
如果你用工具(例如 ReSharper)自动生成命名空间前缀时,才会使用这样默认的命名空间前缀,否则,你随便填。
还有什么更高级的玩法吗?
也许你注意到 WPF 有一些一开始就帮你生成好的命名空间前缀,例如这些:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
</UserControl>
如果我们也把命名空间定义到这里会如何呢?
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "Walterlv.NewCsprojDemo")]
哇,我们竟然可以不用带前缀啦!
<UserControl
x:Class="HuyaHearhira.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<DemoPage />
</Grid>
</UserControl>
这在项目内为一些几乎侵染全部代码的标记扩展是很棒的一波语法糖。例如——自己实现的本地化标记扩展。
一些限制
值得注意的是,XAML 命名空间的定义只会在外部程序集生效。这是说,如果你在 A 程序集中定义了命名空间,那么只有引用了 A 程序集的 B 或者 C 才可以使用到新定义的命名空间;A 程序集自身是没有办法使用此命名空间的。
参考资料
- wpf - How to make XmlnsDefinition work on the local assembly? - Stack Overflow
- XmlnsDefinition doesn’t work in the same assembly
本文会经常更新,请阅读原文: https://walterlv.com/post/define-xmlns-of-for-xaml.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
让你编写的控件库在 XAML 中有一个统一的漂亮的命名空间(xmlns)和命名空间前缀的更多相关文章
- 《Dotnet9》系列-开源C# WPF控件库3《HandyControl》强力推荐
大家好,我是Dotnet9小编,一个从事dotnet开发8年+的程序员.我最近开始写dotnet分享文章,希望能让更多人看到dotnet的发展,了解更多dotnet技术,帮助dotnet程序员应用do ...
- 《Dotnet9》系列-开源C# Winform控件库1《HZHControls》强力推荐
大家好,我是Dotnet9小编,一个从事dotnet开发8年+的程序员.我最近在写dotnet分享文章,希望能让更多人看到dotnet的发展,了解更多dotnet技术,帮助dotnet程序员应用dot ...
- C#编写ActiveX控件
用C#编写ActiveX控件 http://www.cnblogs.com/homer/archive/2005/01/04/86473.html http://www.cnblogs.com/hom ...
- 用C#编写ActiveX控件
http://www.cnblogs.com/homer/archive/2005/01/04/86473.html http://www.cnblogs.com/homer/archive/2005 ...
- WindowsXamlHost:在 WPF 中使用 UWP 控件库中的控件
在 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit) 一文中,我们说到了在 WPF 中引入简单的 UWP 控件以及相关的注意事项 ...
- 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程
反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) 背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...
- 基于 jQuery 的专业 ASP.NET WebForms/MVC 控件库!
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
- Delphi 编写ActiveX控件(OCX控件)的知识和样例(有详细步骤)
一.ActiveX应用情况简介: ActiveX控件也就是一般所说的OCX控件,它是 ActiveX技术的一部分.ActiveX是微软公司推出的基于组件对象模型COM的技术,包括对Windows 32 ...
- 《Dotnet9》系列-开源C# Winform控件库强力推荐
时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...
随机推荐
- 9.11 Binder系统_分层
1.Binder系统过程分析,情景分析 server提供服务 (1)addService(服务名称,xxx)执行后会导致binder驱动在server的内核空间为服务创建一个binder_node结构 ...
- 9.9 Binder系统_Java实现_Android里java程序的编译启动
如果知道了进程号:通过ls /proc/进程号/task 可以看到所有线程 cat /proc/进程号/task/线程号/comm 可以达到线程名字(主线程是main,主线程号就是进程号) d ...
- Java 接口中定义抽象方法有什么意义
接口方法声明只能是public abstract的,所以不管你在声明的时候加不加abstract,都是可以的.Java 8开始,接口还引入了默认方法,也就是可以给接口的方法提供默认的实现,默认方法应当 ...
- 32、从零开始写CMOS摄像头驱动
使用的内核:linux-3.4.2 参考源码:第32课_新内核下的I2C驱动\i2c\1th_i2c_new_device第2课第1.1.7节文档和图片(从0写USB摄像头)\myuvc 设备地址:写 ...
- arm-linux-gcc: Command not found
老是提示arm-linux-gcc找不到,但是确实是装好了,其实是权限的问题,Ubuntu没有root权限,刚开始用碰到很多麻烦,查了好多资料,终于把arm-linux-gcc: Command no ...
- 【跟我一起学Unity3D】代码中分割图片而且载入帧序列动画
在Cocos2dx中.对大图的处理已经封装好了一套自己的API,可是在Unity3D中貌似没有类似的API(好吧,实际上是有的,并且功能更强大),或者说我没找到. 只是这也在情理之中,毕竟Unity3 ...
- js进阶 11-24 jquery如何实现选项卡的制作
js进阶 11-24 jquery如何实现选项卡的制作 一.总结 一句话总结:ul>li做选项卡的选项卡头,多个div做选项卡的内容,点到对应的li,就切换到对应的div,用index()获取l ...
- Range锁(也即范围锁)
浅析SQL Server在可序列化隔离级别下,防止幻读的范围锁的锁定问题 本文出处:http://www.cnblogs.com/wy123/p/7501261.html (保留出处并非什么原创作品权 ...
- Wampserver 2.5 多网站配置方法
写在开头:本文适用于wampserver2.5版本号,和wamp的老版本号配置有语法上的差别,笔者正是由于被老版本号的配置办法给整迷糊了所以才总结了一篇针对2.5版本号的配置方法,假设您还停留在1.x ...
- Facebook Hacker Cup 2015 Round 1--Winning at Sports(动态规划)
原题:pid=688426044611322&round=344496159068801">https://www.facebook.com/hackercup/problem ...