Namespaces XAML e mapeamento de namespace para WPF XAML
Este tópico explica ainda mais a presença e a finalidade dos dois mapeamentos de namespace XAML, como frequentemente encontrados na tag raiz de um arquivo XAML do WPF. Ele também descreve como criar mapeamentos semelhantes para usar elementos definidos em seu próprio código ou em assemblies distintos.
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 define um escopo exclusivo para o uso de marcações e também influencia como os elementos de marcação são potencialmente respaldados 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 entender como o WPF funciona com namespaces XAML, você geralmente pode pensar nos namespaces XAML em termos de um namespace padrão do XAML, o namespace da linguagem XAML e quaisquer outros namespaces XAML mapeados pela marcação XAML diretamente para namespaces de suporte específicos do CLR e assemblies referenciados.
As declarações de namespace WPF e XAML
Dentro das declarações de namespace na marca 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 prefixo x:
.
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
A relação entre essas declarações é que o mapeamento de prefixo x:
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 convenção de prefixo x:
para mapear o suporte a intrínsecos de linguagem XAML é seguida por modelos de projeto, código de exemplo e a documentação dos recursos de linguagem nesse SDK. O namespace XAML define muitos recursos comumente usados que são necessários até mesmo para aplicativos WPF básicos. Por exemplo, para unir qualquer code-behind a um arquivo XAML por meio de uma classe parcial, você deve nomear essa classe como o atributo x:Class
no elemento raiz do arquivo XAML relevante. Ou, qualquer elemento definido em uma página XAML que você deseja acessar como um recurso com chave deve ter o atributo x:Key
definido no elemento em questão. Para obter mais informações sobre esses e outros aspectos do XAML, consulte XAML no WPF ou Sintaxe do XAML em Detalhe.
Mapeamento para classes e assemblies personalizados
Você pode mapear namespaces XML para assemblies usando uma série de tokens em uma declaração de prefixo xmlns
, semelhante à forma como os namespaces XAML padrão WPF e XAML-intrínsecos 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=
A montagem que contém parte ou todo o namespace CLR 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 esse assembly precisa ser definido como uma referência de projeto no ficheiro 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 cadeia de caracteres, conforme definido por AssemblyName, em vez do nome de cadeia de caracteres simples.
Observe que o caractere que separa o token clr-namespace
de seu valor é dois pontos (:) enquanto o caractere que separa o token assembly
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) é denominada 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 integrar tudo isso, o seguinte é um XAML que inclui o mapeamento personalizado juntamente com os mapeamentos padrão e x: típicos na tag raiz, e então usa uma referência prefixada para instanciar ExampleClass
nesta 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 no mesmo assembly que o código do aplicativo que está referenciando as classes personalizadas. Ou, uma sintaxe equivalente para esse caso é especificar assembly=
, sem nenhuma 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.
Mapeando namespaces CLR para namespaces XML em um 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 do assembly no código-fonte que gera a montagem. 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 namespace http://schemas.microsoft.com/winfx/2006/xaml/presentation
.
O XmlnsDefinitionAttribute usa dois parâmetros: o nome do namespace XML/XAML e o nome do namespace CLR. Mais de um XmlnsDefinitionAttribute pode existir para que múltiplos namespaces CLR sejam mapeados para o mesmo namespace XML. Depois de mapeados, os membros desses namespaces também podem ser referenciados sem qualificação completa, caso desejado, fornecendo a instrução using
apropriada no arquivo de código subjacente da classe parcial. Para obter mais detalhes, consulte XmlnsDefinitionAttribute.
Namespaces de design 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 de design XAML é usado para perpetuar o estado de design durante a ida e volta da interface do usuário baseada em XAML no designer. Ele também é usado para recursos como d:IsDataSource
, que habilitam 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 em 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 funcionalidades de linguagem de compatibilidade de marcação (mc:).
Carregamento de WPF e de Assemblies
O contexto de esquema XAML para WPF integra-se ao modelo de aplicativo WPF, que, por sua vez, usa o conceito definido pela CLR de AppDomain. A sequência a seguir descreve como o contexto do esquema XAML interpreta como carregar assemblies ou localizar tipos em tempo de execução ou tempo de design, com base no uso do WPF de AppDomain e outros fatores.
Iterar pela AppDomain, procurando um assembly já carregado que corresponda a todos os aspectos do nome, começando pelo assembly carregado mais recentemente.
Se o nome for qualificado, chame Assembly.Load(String) no nome qualificado.
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.
Use o nome curto + token de chave pública para chamar Assembly.Load(String).
Se o nome não estiver 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 via XamlBuildTask) não usa os assemblies já carregados de AppDomain (Etapa 1). Além disso, o nome nunca deve ser desvinculado da 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
.NET Desktop feedback