Esquemas de namespace personalizados XAML em Xamarin.Forms
Os tipos em uma biblioteca podem ser referenciados em XAML declarando um namespace XAML para a biblioteca, com a declaração de namespace especificando o nome do namespace CLR (Common Language Runtime) e um nome de assembly:
<ContentPage ...
xmlns:controls="clr-namespace:MyCompany.Controls;assembly=MyCompany.Controls">
...
</ContentPage>
No entanto, especificar um namespace CLR e um nome de assembly em uma xmlns
definição pode ser estranho e propenso a erros. Além disso, várias declarações de namespace XAML podem ser necessárias se a biblioteca contiver tipos em vários namespaces.
Uma abordagem alternativa é definir um esquema de namespace personalizado, como http://mycompany.com/schemas/controls
, que mapeia para um ou mais namespaces CLR. Isso permite que uma única declaração de namespace XAML faça referência a todos os tipos em um assembly, mesmo que eles estejam em namespaces diferentes. Ele também permite que uma única declaração de namespace XAML faça referência a tipos em vários assemblies.
Para obter mais informações sobre namespaces XAML, consulte Namespaces XAML no Xamarin.Forms.
Definindo um esquema de namespace personalizado
O aplicativo de exemplo contém uma biblioteca que expõe alguns controles simples, como CircleButton
:
using Xamarin.Forms;
namespace MyCompany.Controls
{
public class CircleButton : Button
{
...
}
}
Todos os controles na biblioteca residem no MyCompany.Controls
namespace. Esses controles podem ser expostos a um assembly de chamada por meio de um esquema de namespace personalizado.
Um esquema de namespace personalizado é definido com a XmlnsDefinitionAttribute
classe, que especifica o mapeamento entre um namespace XAML e um ou mais namespaces CLR. O XmlnsDefinitionAttribute
usa dois argumentos: o nome do namespace XAML e o nome do namespace CLR. O nome do XmlnsDefinitionAttribute.XmlNamespace
namespace XAML é armazenado na propriedade e o nome do namespace CLR é armazenado na XmlnsDefinitionAttribute.ClrNamespace
propriedade.
Observação
A XmlnsDefinitionAttribute
classe também tem uma propriedade chamada AssemblyName
, que pode ser opcionalmente definida como o nome do assembly. Isso só é necessário quando um namespace CLR referenciado de um XmlnsDefinitionAttribute
está em um assembly externo.
O XmlnsDefinitionAttribute
deve ser definido no nível do assembly no projeto que contém os namespaces CLR que serão mapeados no esquema de namespace personalizado. O exemplo a seguir mostra o arquivo AssemblyInfo.cs do aplicativo de exemplo:
using Xamarin.Forms;
using MyCompany.Controls;
[assembly: Preserve]
[assembly: XmlnsDefinition("http://mycompany.com/schemas/controls", "MyCompany.Controls")]
Esse código cria um esquema de namespace personalizado que mapeia a http://mycompany.com/schemas/controls
URL para o MyCompany.Controls
namespace CLR. Além disso, o Preserve
atributo é especificado no assembly, para garantir que o vinculador preserve todos os tipos no assembly.
Importante
O Preserve
atributo deve ser aplicado a classes no assembly que são mapeadas por meio do esquema de namespace personalizado ou aplicado a todo o assembly.
O esquema de namespace personalizado pode ser usado para resolução de tipo em arquivos XAML.
Consumindo um esquema de namespace personalizado
Para consumir tipos do esquema de namespace personalizado, o compilador XAML requer que haja uma referência de código do assembly que consome os tipos para o assembly que define os tipos. Isso pode ser feito adicionando uma classe que contém um Init
método ao assembly que define os tipos que serão consumidos por meio de XAML:
namespace MyCompany.Controls
{
public static class Controls
{
public static void Init()
{
}
}
}
Em seguida, o Init
método pode ser chamado do assembly que consome tipos do esquema de namespace personalizado:
using Xamarin.Forms;
using MyCompany.Controls;
namespace CustomNamespaceSchemaDemo
{
public partial class MainPage : ContentPage
{
public MainPage()
{
Controls.Init();
InitializeComponent();
}
}
}
Aviso
A falha em incluir essa referência de código resultará na incapacidade do compilador XAML de localizar o assembly que contém os tipos de esquema de namespace personalizados.
Para consumir o CircleButton
controle, um namespace XAML é declarado, com a declaração de namespace especificando a URL do esquema de namespace personalizado:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="http://mycompany.com/schemas/controls"
x:Class="CustomNamespaceSchemaDemo.MainPage">
<StackLayout Margin="20,35,20,20">
...
<controls:CircleButton Text="+"
BackgroundColor="Fuchsia"
BorderColor="Black"
CircleDiameter="100" />
<controls:CircleButton Text="-"
BackgroundColor="Teal"
BorderColor="Silver"
CircleDiameter="70" />
...
</StackLayout>
</ContentPage>
CircleButton
As instâncias podem ser adicionadas ao declarando-as ContentPage
com o prefixo de controls
namespace.
Para localizar os tipos de esquema de namespace personalizados, Xamarin.Forms pesquisaremos assemblies referenciados para XmlnsDefinitionAttribute
instâncias. Se o xmlns
atributo de um elemento em um arquivo XAML corresponder ao valor da XmlNamespace
propriedade em um XmlnsDefinitionAttribute
, Xamarin.Forms o tentará usar o valor da XmlnsDefinitionAttribute.ClrNamespace
propriedade para a resolução do tipo. Se a resolução de tipo falhar, Xamarin.Forms continuará a tentar a resolução de tipo com base em quaisquer instâncias correspondentes XmlnsDefinitionAttribute
adicionais.
O resultado é que duas CircleButton
instâncias são exibidas: