我可以使用 style/resource 从我的所有用户控件中删除 xmlns 标记(也许还有资源)吗?

Can I get rid of xmlns tags (and maybe also resources) from my all user controls by using style/resource?

我想从每个 UserControlWindow 文件中删除 xmlns 标签。

我可以通过某种方式使用样式或资源来实现吗?

我的许多用户控件看起来像这样:

<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 命名空间映射到它。如果资源和命名空间是在同一个程序集中定义的,这将不起作用。

为每个具有所需 XML 命名空间的 CLR 命名空间添加一个 XmlnsDefinition 属性。

Specifies a mapping on a per-assembly basis between a XAML namespace and a CLR namespace, which is then used for type resolution by a XAML object writer or XAML schema context.

The XmlnsDefinitionAttribute takes two parameters: the XML/XAML namespace name, and the CLR namespace name. More than one XmlnsDefinitionAttribute can exist to map multiple CLR namespaces to the same XML namespace.

您需要在程序集级别插入属性,因此您必须拥有或能够修改它。

This attribute, XmlnsDefinitionAttribute, is placed at the assembly level in the source code that produces the assembly.

例如,对于您的 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 这样的设计师会尊重这一点,但其他人可能不会。

Identifies a recommended prefix to associate with a XAML namespace for XAML usage, when writing elements and attributes in a XAML file (serialization) or when interacting with a design environment that has XAML editing features.

XAML processors or frameworks that incorporate XAML, or any process that performs XAML serialization, should generally honor the recommended prefix.

在您的控件中(在不同的程序集中)使用命名空间时,它看起来像这样。

<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>

如果这些是公共资源,您也可以简单地将它们添加到应用程序资源字典中,然后它们将在每个控件中可用,无需任何进一步的麻烦。