wpf - 我可以通过使用样式/资源从我的所有用户控件中删除 xmlns 标签(也许还有资源)吗?
问题描述
我想摆脱每个或文件中的xmlns
标签。UserControl
Window
我可以通过某种方式使用样式或资源来做到这一点吗?
我的许多用户控件如下所示:
<UserControl x:Class="Mst2.View.Controls.Modules.TimerEntryControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:bcp="clr-namespace:ABitOfBinding"
xmlns:dc="clr-namespace:Mst2.Dictionaries"
xmlns:vm="clr-namespace:Mst2.ViewModel"
xmlns:vc="clr-namespace:Mst2.ValueConverters"
xmlns:c="clr-namespace:Mst2.View.Controls"
xmlns:mw="clr-namespace:Mst2.View.Windows"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<dc:Mst2Dictionaries x:Key="Dictionaries" />
<bcp:ByteBit2Bool x:Key="ByteBit2Bool" />
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<vc:TimerTimeAndRangeConverter x:Key="TimerTimeAndRangeConverter"/>
</UserControl.Resources>
<!-- user control contents here -->
</UserControl>
解决方案
如果您从特定命名空间实例化资源,则必须声明它。解析器如何知道您指的是哪种类型?但是,如果这些资源位于单独的程序集中,则可以创建自定义 XAML 命名空间并将所有 CLR 命名空间映射到它。如果资源和命名空间是在同一个程序集中定义的,这将不起作用。
XmlnsDefinition
使用所需的 XML 命名空间为每个 CLR 命名空间添加一个属性。
基于每个程序集指定 XAML 命名空间和 CLR 命名空间之间的映射,然后由 XAML 对象编写器或 XAML 架构上下文用于类型解析。
它
XmlnsDefinitionAttribute
采用两个参数:XML/XAML 命名空间名称和 CLR 命名空间名称。可以存在多个XmlnsDefinitionAttribute
将多个 CLR 命名空间映射到同一个 XML 命名空间的方法。
您需要在程序集级别插入属性,因此您必须拥有或能够修改它。
这个属性 ,
XmlnsDefinitionAttribute
放置在生成程序集的源代码中的程序集级别。
例如,对于您的Mst2
程序集,其中的属性AssemblyInfo.cs
可能如下所示。您可以自由选择 URI,它在这里除了作为标识符之外没有特殊含义。
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.Dictionaries")]
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.ViewModel")]
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.ValueConverters")]
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.View.Controls")]
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.View.Windows")]
此外,您可以定义XmlPrefix
一个提示设计者在将 XAML 命名空间添加到 XAML 文件时使用此前缀。
[assembly: XmlnsPrefix("http://schemas.Mst2.com/2021", "mst2")]
请注意,Visual Studio 等设计人员会尊重这一点,但其他人可能不会。
在 XAML 文件中写入元素和属性(序列化)或与具有 XAML 编辑功能的设计环境交互时,标识与 XAML 命名空间相关联的推荐前缀。
XAML 处理器或包含 XAML 的框架,或任何执行 XAML 序列化的进程,通常应遵循推荐的前缀。
当使用控件中的命名空间(在不同的程序集中)时,它看起来像这样。
<UserControl x:Class="Mst2.View.Controls.Modules.TimerEntryControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mst2="http://schemas.Mst2.com/2021"
xmlns:bcp="clr-namespace:ABitOfBinding"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<mst2:Mst2Dictionaries x:Key="Dictionaries" />
<mst2:ByteBit2Bool x:Key="ByteBit2Bool" />
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<mst2:TimerTimeAndRangeConverter x:Key="TimerTimeAndRangeConverter"/>
</UserControl.Resources>
<!-- user control contents here -->
</UserControl>
您可以做的另一件事是为共享资源创建资源字典,例如:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:bcp="clr-namespace:ABitOfBinding"
xmlns:dc="clr-namespace:Mst2.Dictionaries"
xmlns:vc="clr-namespace:Mst2.ValueConverters">
<dc:Mst2Dictionaries x:Key="Dictionaries" />
<bcp:ByteBit2Bool x:Key="ByteBit2Bool" />
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<vc:TimerTimeAndRangeConverter x:Key="TimerTimeAndRangeConverter"/>
</ResourceDictionary>
然后,您可以在任何需要它的地方包含它,而不必为每个资源指定命名空间或每次都重新声明资源。
<UserControl x:Class="Mst2.View.Controls.Modules.TimerEntryControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:bcp="clr-namespace:ABitOfBinding"
xmlns:vm="clr-namespace:Mst2.ViewModel"
xmlns:mw="clr-namespace:Mst2.View.Windows"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MySharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<!-- User control contents here -->
</UserControl>
如果这些是公共资源,您也可以简单地将它们添加到应用程序资源字典中,然后它们将在每个控件中可用,无需任何麻烦。
推荐阅读
- java - 具有 INNER JOIN 条件的 JPA 命名查询失败
- java - 如何在spring boot的application.yml中添加GCP(谷歌云存储)存储属性
- node.js - Docker 构建不使用来自 npm ci 的缓存
- c - Vim 指定语法文件(不是语法类型)?
- java - JNI:处理复杂的 C++ 类
- sql - PostgreSQL 子查询 - 计算滞后值的平均值
- ruby-on-rails - PSQL 数据库更新触发器更新过程有效。但是插入过程没有
- c# - 在 ubuntu 中构建 .NET Core 控制台应用程序 - 使用本机代码查找 c# nuget 的 windows dll 而不是 .so 文件
- css - 尝试在当前版本的 Safari 中包装多个表格时出现 Flex 错误?
- python - 如何从字符串和使用正则表达式在python中创建一个列表