代码之家  ›  专栏  ›  技术社区  ›  Kamil

通过在WPF中使用style/resources,我可以从所有用户控件中去掉xmlns标记(也许还有资源)吗?

  •  0
  • Kamil  · 技术社区  · 3 年前

    我想摆脱 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>
    
    0 回复  |  直到 3 年前
        1
  •  1
  •   thatguy    3 年前

    如果实例化来自特定名称空间的资源,则必须声明该名称空间。解析器如何知道您所指的是哪种类型?但是,如果这些资源位于 独立组件 ,可以创建自定义XAML命名空间并将所有CLR命名空间映射到该命名空间。如果在同一程序集中定义了资源和命名空间,则此操作不起作用。

    添加一个 XmlnsDefinition 属性与所需的XML命名空间。

    基于每个程序集指定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处理器或框架或执行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>
    

    如果这些是公共资源,您也可以简单地将它们添加到应用程序资源字典中,那么它们将在每个控件中可用,而无需任何其他操作。

    推荐文章