Compartilhar via


Namespaces XAML e mapeamento de namespaces para WPF XAML

Este tópico aprofunda a presença e a finalidade dos dois mapeamentos de namespace XAML, comumente encontrados na tag raiz de um arquivo WPF XAML. Ele também descreve como produzir mapeamentos semelhantes para usar elementos definidos em seu próprio código e/ou em módulos separados.

O que é um Namespace XAML

Um namespace XAML é realmente uma extensão do conceito de um namespace XML. As técnicas de especificação de um namespace XAML dependem da sintaxe do namespace XML, da convenção de usar URIs como identificadores de namespace, usando prefixos para fornecer um meio de referenciar vários namespaces da mesma origem de marcação e assim por diante. O conceito principal adicionado à definição XAML do namespace XML é que um namespace XAML implica um escopo de exclusividade para os usos de marcações e também influencia potencialmente como essas entidades de marcação são apoiadas por namespaces CLR específicos e assemblies referenciados. Essa última consideração também é influenciada pelo conceito de um contexto de esquema XAML. Mas para fins de entender como o WPF funciona com namespaces XAML, você pode geralmente pensar em namespaces XAML em termos de um namespace XAML padrão, o namespace da linguagem XAML e quaisquer outros namespaces XAML que são mapeados pela marcação XAML diretamente para namespaces CLR de suporte específicos e assemblies referenciados.

As declarações de namespace WPF e XAML

Dentro das declarações de namespace na tag raiz de muitos arquivos XAML, você verá que normalmente há duas declarações de namespace XML. A primeira declaração mapeia o namespace XAML do cliente/framework do WPF como o padrão.

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

A segunda declaração mapeia um namespace XAML separado, mapeando-o (normalmente) para o x: prefixo.

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

A relação entre essas declarações é que o x: mapeamento de prefixo dá suporte aos intrínsecos que fazem parte da definição de linguagem XAML, e o WPF é uma implementação que usa XAML como linguagem e define um vocabulário de seus objetos para XAML. Como os usos do vocabulário do WPF serão muito mais comuns do que os usos de intrínsecos XAML, o vocabulário do WPF é mapeado como o padrão.

A x: convenção de prefixo para mapear o suporte a intrínsecos da linguagem XAML é seguida por modelos de projeto, código de exemplo e a documentação dos recursos de linguagem dentro desse SDK. O namespace XAML define muitos recursos comumente usados que são necessários até mesmo para aplicativos WPF básicos. Por exemplo, para vincular qualquer code-behind a um arquivo XAML por meio de uma classe parcial, você deve nomear essa classe como atributo x:Class no elemento raiz do arquivo XAML relevante. Ou, qualquer elemento conforme definido em uma página XAML que você deseja acessar como um recurso com chave deve ter o x:Key atributo definido no elemento em questão. Para obter mais informações sobre esses e outros aspectos do XAML, consulte XAML na sintaxe WPF ou XAML em detalhes.

Mapeamento para classes e assembléias personalizadas

Você pode mapear namespaces XML para assemblies usando uma série de tokens em uma declaração de prefixo xmlns, semelhante à maneira como os namespaces XAML intrínsecos padrão do WPF e XAML são mapeados para prefixos.

A sintaxe usa os seguintes tokens nomeados possíveis e os seguintes valores:

clr-namespace: O namespace CLR declarado dentro do assembly que contém os tipos públicos a serem expostos como elementos.

assembly= O assembly que contém parte ou todo o namespace CLR que foi referenciado. Esse valor normalmente é apenas o nome do assembly, não o caminho e não inclui a extensão (como .dll ou .exe). O caminho para essa montagem deve ser estabelecido como uma referência de projeto no arquivo de projeto que contém o XAML que você está tentando mapear. Para incorporar o controle de versão e a assinatura de nome forte, o valor assembly pode ser uma string definida por AssemblyName, em vez de um nome de string simples.

Observe que o caractere que separa o clr-namespace token de seu valor é dois pontos (:) enquanto o caractere que separa o assembly token de seu valor é um sinal de igualdade (=). O caractere a ser usado entre esses dois tokens é um ponto e vírgula. Além disso, não inclua nenhum espaço em branco em qualquer lugar na declaração.

Um exemplo de mapeamento personalizado básico

O código a seguir define um exemplo de classe personalizada:

namespace SDKSample {
    public class ExampleClass : ContentControl {
        public ExampleClass() {
        ...
        }
    }
}
Namespace SDKSample
    Public Class ExampleClass
        Inherits ContentControl
         ...
        Public Sub New()
        End Sub
    End Class
End Namespace

Essa classe personalizada é então compilada em uma biblioteca, que de acordo com as configurações do projeto (não mostradas) é nomeada SDKSampleLibrary.

Para fazer referência a essa classe personalizada, você também precisa incluí-la como uma referência para seu projeto atual, o que normalmente você faria usando a interface do usuário do Gerenciador de Soluções no Visual Studio.

Agora que você tem uma biblioteca que contém uma classe e uma referência a ela nas configurações do projeto, você pode adicionar o seguinte mapeamento de prefixo como parte do elemento raiz em XAML:

xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary"

Para juntar tudo isso, o seguinte é XAML que inclui o mapeamento personalizado junto com o padrão típico e x: mapeamentos na marca raiz e, em seguida, usa uma referência prefixada para instanciar ExampleClass nessa interface do usuário:

<Page x:Class="WPFApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary">
  ...
  <custom:ExampleClass/>
...
</Page>

Mapeamento para assemblies atuais

assembly pode ser omitido se o clr-namespace referenciado estiver sendo definido dentro do mesmo assembly que o código do aplicativo que está fazendo referência às classes personalizadas. Ou, uma sintaxe equivalente para esse caso é especificar assembly=, sem nenhum token de cadeia de caracteres seguindo o sinal de igual.

Classes personalizadas não podem ser usadas como o elemento raiz de uma página se definidas no mesmo assembly. Classes parciais não precisam ser mapeadas; somente classes que não são a classe parcial de uma página em seu aplicativo precisam ser mapeadas se você pretende referenciá-las como elementos em XAML.

Mapeamento de namespaces CLR para namespaces XML em uma assembly

O WPF define um atributo CLR que é consumido por processadores XAML para mapear vários namespaces CLR para um único namespace XAML. Esse atributo, XmlnsDefinitionAttribute, é colocado no nível de assembly do código-fonte que produz o assembly. O código-fonte do assembly do WPF usa esse atributo para mapear os vários namespaces comuns, como System.Windows e System.Windows.Controls, para o http://schemas.microsoft.com/winfx/2006/xaml/presentation namespace.

O XmlnsDefinitionAttribute aceita dois parâmetros: o nome do namespace XML/XAML e o nome do namespace CLR. Mais de um XmlnsDefinitionAttribute pode existir para mapear vários namespaces CLR para o mesmo namespace XML. Depois de mapeados, os membros desses namespaces também podem ser referenciados sem qualificação total, caso desejado, ao fornecer a declaração apropriada using na página code-behind de classe parcial. Para obter mais detalhes, confira XmlnsDefinitionAttribute.

Namespaces de designer e outros prefixos de modelos XAML

Se você estiver trabalhando com ambientes de desenvolvimento e/ou ferramentas de design para WPF XAML, poderá observar que há outros namespaces/prefixos XAML definidos dentro da marcação XAML.

O Designer do WPF para Visual Studio usa um namespace de designer que normalmente é mapeado para o prefixo d:. Modelos de projeto mais recentes para WPF podem pré-mapear esse namespace XAML para dar suporte ao intercâmbio do XAML entre o WPF Designer para Visual Studio e outros ambientes de design. Esse namespace XAML de design é usado para perpetuar o estado de design ao arredondar a interface do usuário baseada em XAML no designer. Ele também é usado para recursos como d:IsDataSource, que permitem fontes de dados de runtime em um designer.

Outro prefixo que você pode ver mapeado é mc:. mc: é para compatibilidade de marcação e aproveita um padrão de compatibilidade de marcação que não é necessariamente específico de XAML. Em certa medida, os recursos de compatibilidade de marcação podem ser usados para trocar XAML entre estruturas ou entre outros limites de implementação de suporte, trabalhar entre contextos de esquema XAML, fornecer compatibilidade para modos limitados nas ferramentas de design e assim por diante. Para obter mais informações sobre os conceitos de compatibilidade de marcação e como eles se relacionam com o WPF, consulte Recursos de linguagem de compatibilidade de marcação (mc:).

Carregamento de WPF e Assembly

O contexto de esquema XAML para WPF integra-se ao modelo de aplicativo WPF, que, por sua vez, usa o conceito definido por CLR de AppDomain. A sequência a seguir descreve como o contexto de esquema do XAML interpreta a maneira de carregar assemblies ou localizar tipos em tempo de execução ou tempo de design, com base no uso do WPF do AppDomain e em outros fatores.

  1. Iterar através do AppDomain, procurando uma montagem já carregada que corresponda a todos os aspectos do nome, começando pela montagem carregada mais recentemente.

  2. Se o nome for qualificado, chame Assembly.Load(String) no nome qualificado.

  3. Se o nome curto + token de chave pública de um nome qualificado corresponder ao assembly do qual a marcação foi carregada, retorne esse assembly.

  4. Use o nome curto + token de chave pública para chamar Assembly.Load(String).

  5. Se o nome não for qualificado, chame Assembly.LoadWithPartialName.

O XAML flexível não usa a Etapa 3; não há nenhum assembly carregado.

O XAML compilado para WPF (gerado com XamlBuildTask) não usa os assemblies já carregados de AppDomain (Passo 1). Além disso, o nome nunca deve ser usado sem qualificação na saída do XamlBuildTask, portanto, a Etapa 5 não se aplica.

O BAML compilado (gerado por meio do PresentationBuildTask) usa todas as etapas, embora o BAML também não deva conter nomes de assembly não qualificados.

Consulte também