Como criar controles de interface do usuário como pacotes do NuGet

No Visual Studio 2017 em diante, você pode aproveitar as funcionalidades adicionadas dos controles UWP e WPF entregues em pacotes NuGet. Este guia orientará você quanto a esses recursos no contexto dos controles UWP usando o exemplo ExtensionSDKasNuGetPackage. O mesmo se aplica aos controles WPF, salvo indicação em contrário.

Pré-requisitos

  1. Visual Studio 2017
  2. Noções básicas sobre como Criar pacotes UWP

Gerar Layout da Biblioteca

Observação

Isso só se aplica aos controles UWP.

Configurar a propriedade GenerateLibraryLayout garante que a saída de build do projeto é gerada em um layout que está pronto para ser empacotado, sem a necessidade de entradas de arquivos individuais no nuspec.

Nas propriedades do projeto, acesse a guia build e marque a caixa de seleção "Gerar Layout da Biblioteca". Isso modificará o arquivo de projeto e definirá o sinalizador GenerateLibraryLayout como verdadeiro para a plataforma e a configuração de build selecionadas no momento.

Como alternativa, edite o arquivo de projeto para adicionar <GenerateLibraryLayout>true</GenerateLibraryLayout> no primeiro grupo de propriedade incondicional. Isso aplicaria a propriedade independentemente da plataforma e da configuração de build.

Adicionar suporte para o painel da caixa de ferramentas/ativos a controles XAML

Para que um controle XAML apareça na caixa de ferramentas do designer XAML no Visual Studio e no painel de Ativos do Blend, crie um arquivo VisualStudioToolsManifest.xml na raiz da pasta tools do seu projeto de pacote. Esse arquivo não é necessário se você não precisar que o controle apareça na caixa de ferramentas ou no painel Ativos.

\build
\lib
\tools
    VisualStudioToolsManifest.xml

A estrutura do arquivo é a seguinte:

<FileList>
  <File Reference = "your_package_file">
    <ToolboxItems UIFramework="WPF" VSCategory="vs_category" BlendCategory="blend_category">
      <Item Type="type_full_name_1" />

      <!-- Any number of additional Items -->
      <Item Type="type_full_name_2" />
      <Item Type="type_full_name_3" />
    </ToolboxItems>
  </File>
</FileList>

onde:

  • your_package_file: o nome do arquivo do seu controle, como ManagedPackage.winmd (“ManagedPackage” é um nome arbitrário usado para este exemplo e não tem nenhum outro significado).
  • vs_category: o rótulo para o grupo no qual o controle deve aparecer na caixa de ferramentas do designer do Visual Studio. Um VSCategory é necessário para o controle apareça na caixa de ferramentas. ui_framework: O nome da Estrutura, como 'WPF', observe que o atributo é necessário em nós toolboxItems no Visual Studio 16.7 Versão Prévia 3 ou superior para que UIFramework o controle apareça na caixa de ferramentas.
  • blend_category: o rótulo para o grupo no qual o controle deve aparecer no painel Ativos do designer do Blend. Um BlendCategory é necessário para o controle apareça em Ativos.
  • type_full_name_n: o nome totalmente qualificado para cada controle, incluindo o namespace, como ManagedPackage.MyCustomControl. Observe que o formato de ponto é usado tanto para tipos gerenciados quanto para tipos nativos.

Em cenários mais avançados, também é possível incluir vários elementos <File> dentro de <FileList> quando um único pacote contém vários assemblies de controle. Também é possível ter vários nós <ToolboxItems> dentro de um único <File> se você quiser organizar os controles em categorias separadas.

No exemplo a seguir, o controle implementado em ManagedPackage.winmd aparecerá no Visual Studio e no Blend em um grupo denominado “Managed Package” e “MyCustomControl” será exibido nesse grupo. Todos esses nomes são arbitrários.

<FileList>
  <File Reference = "ManagedPackage.winmd">
    <ToolboxItems UIFramework="WPF" VSCategory="Managed Package" BlendCategory="Managed Package">
      <Item Type="ManagedPackage.MyCustomControl" />
    </ToolboxItems>
  </File>
</FileList>

An example control as it appear in Visual Studio

An example control as it appear in Blend

Observação

Você precisa especificar explicitamente cada controle deve ser exibido no painel de caixa de ferramentas/ativos. Verifique se você os especificou no formato Namespace.ControlName.

Adicionar ícones personalizados aos seus controles

Para exibir um ícone personalizado no painel de caixa de ferramentas/ativos, adicione uma imagem ao seu projeto ou ao projeto design.dll correspondente com o nome “Namespace.ControlName.extension” e defina a ação de build como “Recurso Inserido”. Você também deve garantir que o AssemblyInfo.cs associado especifique o atributo ProvideMetadata - [assembly: ProvideMetadata(typeof(RegisterMetadata))]. Veja este exemplo.

Os formatos compatíveis são .png, .jpg, .jpeg, .gif e .bmp. O formato recomendado é BMP24 em 16 x 16 pixels.

Tool box icon sample

A tela de fundo rosa é substituída em runtime. Os ícones são recoloridos quando o tema do Visual Studio é alterado e essa cor da tela de fundo é esperada. Para obter mais informações, veja Imagens e ícones para o Visual Studio.

No exemplo a seguir, o projeto contém um arquivo de imagem denominado “ManagedPackage.MyCustomControl.png”.

Setting a custom icon in a project

Observação

Para controles nativos, você deve colocar o ícone como um recurso do projeto design.dll.

Suporte a versões específicas de plataformas Windows

Pacotes UWP têm um TPV (TargetPlatformVersion) e TPMinV (TargetPlatformMinVersion) que definem os limites superior e inferior da versão do sistema operacional em que o aplicativo pode ser instalado. O TPV especifica ainda a versão do SDK na qual o aplicativo é compilado. Preste atenção a essas propriedades ao criar um pacote UWP: usar APIs fora dos limites das versões de plataforma definidas no aplicativo fará com que a compilação falhe ou o aplicativo falhe no runtime.

Por exemplo, digamos que você tenha definido o TPMinV para o pacote de controles para o Windows 10 Anniversary Edition (10.0; Build 14393), por isso pode ser útil garantir que o pacote seja consumido somente por projetos UWP que correspondam ao limite inferior. Para permitir que o pacote seja consumido por projetos UWP você precisa empacotar os controles com os seguintes nomes de pasta:

\lib\uap10.0.14393\*
\ref\uap10.0.14393\*

O NuGet verificará automaticamente o TPMinV do projeto consumidor e falhará na instalação se for inferior ao Windows 10 Anniversary Edition (10.0; build 14393)

No caso do WPF, digamos que você queira que seu pacote de controles WPF seja consumido por projetos utilizando o .NET Framework v4.6.1 ou superior. Para impor isso, você deve empacotar os controles com os seguintes nomes de pastas:

\lib\net461\*
\ref\net461\*

Adicionar suporte no tempo de design

Para configurar onde as propriedades do controle aparecem na Inspeção de propriedade, adicionar adornos personalizados, etc., coloque o arquivo design.dll dentro da pasta lib\uap10.0.14393\Design conforme apropriado para a plataforma de destino. Além disso, para garantir que o recurso Editar Editar > Modelo edite uma cópia funcione, você deve incluir os Generic.xaml dicionários de recursos e os dicionários de recursos que ele mesclar na pasta (novamente, usando o <your_assembly_name>\Themes nome do assembly real). (Esse arquivo não tem nenhum impacto no comportamento de runtime de um controle.) A estrutura de pastas seria, portanto, exibida da seguinte maneira:

\lib
  \uap10.0.14393
    \Design
      \MyControl.design.dll
    \your_assembly_name
      \Themes
        Generic.xaml

Para WPF, continuando com o exemplo em que você deseja que o pacote de controles WPF fosse consumido por projetos utilizando o .NET Framework v4.6.1 ou superior:

\lib
  \net461
    \Design
      \MyControl.design.dll
    \your_assembly_name
      \Themes
        Generic.xaml

Observação

Por padrão, as propriedades de controle aparecerão na categoria Diversos na Inspeção de propriedade.

Usar cadeias de caracteres e recursos

Você pode inserir recursos de cadeia de caracteres (.resw) no pacote, as quais podem ser usadas pelo controle ou o projeto UWP consumidor, defina a propriedade Ação de Build do arquivo .resw para PRIResource.

Para obter um exemplo, consulte MyCustomControl.cs no exemplo ExtensionSDKasNuGetPackage.

Observação

Isso só se aplica aos controles UWP.

Confira também