Este artigo foi traduzido por máquina.

XAML e C++

Apresentando o C++/CX e XAML

Andy rico

Baixar o código de exemplo

Código primeiro é grande para a concepção de um algoritmo de ordenação rápido, mas não é necessariamente a melhor maneira de fazer uma boa aparência da interface do usuário, e a tecnologia de interface do usuário fornecida pela Microsoft para desenvolvedores de C++ tem refletido esta preferência. A última atualização significativa para tecnologia Microsoft UI para C++, lançado em 2008, foi um novo conjunto de controles MFC fornecido com estilo Ribbon controles. Antes disso foi Windows Forms, uma tecnologia de interface do usuário baseada em .NET Framework Microsoft lançado com o Visual Studio .NET em fevereiro de 2002. Embora poderoso, ambos destas tecnologias foram focados principalmente no código subjacente que criou os elementos da interface do usuário e exigiu acoplamento forte de dados e a interface do usuário.

Nos últimos anos, os desenvolvedores de c# e Visual Basic têm desfrutado de melhoramentos significativos para sua tecnologia de interface do usuário na forma de estruturas de interface do usuário baseada em XAML (Windows Presentation Foundation ou WPF e Silverlight). Estes quadros trouxeram aos desenvolvedores novas opções em design da interface do usuário, dando-lhes a liberdade de seus algoritmos de código sem se preocupar como a interface do usuário seria apresentado e a liberdade para criar sua interface do usuário sem se preocupar com o código por trás dele. Por último, com Windows 8, desenvolvedores de C++ podem tirar proveito de um quadro de interface de usuário moderno, baseada em XAML para criar aplicativos para Windows 8.

Por que XAML?

XAML é uma linguagem de marcação baseada em XML que permite que você definir a aparência do seu aplicativo sem a necessidade de compreender como a interface do usuário é criado no código. O tempo de execução do Windows (WinRT) analisa esta informação em tempo de execução, constrói as classes de controle apropriado e cria a árvore de interface do usuário. Seu código pode manipular esses objetos e, quando criado corretamente, a aparência da interface do usuário pode ser alterada significativamente sem tocar o code-behind em tudo. Isso facilita uma divisão do trabalho entre um desenvolvedor que trabalha com o código por trás das cenas e um designer de interface do usuário que incide sobre a aparência do aplicativo propriamente dito.

Visual Studio 2012 também é totalmente integrado com a mistura, um poder­ferramenta de designer ful especificamente otimizada para trabalhar com XAML e HTML. Mistura fornece mais controle WYSIWYG (incluindo animação design) e expõe mais propriedades em objetos XAML que designer integrado do Visual Studio.

Por que C + + CX?

Os desenvolvedores têm uma gama de tecnologias para escolher quando escrever uma app Store do Windows: HTML e JavaScript, c# ou Visual Basic com XAML e C++. Em C++, você pode criar aplicativos com C + + CX e XAML ou DirectX, ou uma combinação de ambos. Além disso, você pode criar um aplicativo que é um híbrido dessas tecnologias, tais como a escrita de um componente em C + + CX é usado de uma app Store Windows construído com JavaScript/HTML.

Há um número de razões para você escolher o C++ para escrever um aplicativo Windows Store. Primeiro, o C + + CX vinculação de execução do Windows é 100% nativa e referência contabilizada. Isto significa que há muito pouca sobrecarga. Em segundo lugar, o C++ tem a capacidade de utilizar as bibliotecas existentes (como Boost). Finalmente, C++ suporta nativas superfícies Direct3D e Direct2D dentro apps da loja do Windows, que permite a criação de jogos e outros aplicativos com grande desempenho. Ter baixa sobrecarga e alto desempenho não significa apenas que seu aplicativo é executado mais rápido; também pode ser mais magro, usando menos instruções para realizar as mesmas tarefas, que reduz o consumo de energia e dá aos usuários a melhor vida da bateria.

Olá mundo do C + + CX e XAML

Visual Studio 2012 fornece uma série de modelos que demonstram os recursos avançados de armazenamento Windows apps. O modelo de grade é uma aplicação característica-embalada com vários modos de exibição, suporte para transições de retrato e paisagem, avançadas de vinculação de dados e suspender e retomar a recursos. No entanto, não é muito adequado para demonstrar os conceitos básicos. Em vez disso, crie um novo aplicativo de C++ Windows Store usando o modelo em branco App (XAML).

Uma vez que o aplicativo é criado, encontrar MainPage. XAML no Solution Explorer e abra-o. Ele é aberto para edição no designer XAML integrado, que é dividido em dois painéis: o desenho mostra um processamento de interface do usuário e o modo de exibição XAML mostra o código. Atualizar ou painel atualiza o outro. Isso lhe dá a liberdade para arrastar controles para facilitar a edição ou para controlar com precisão o layout, editando o código.

Abrir a caixa de ferramentas, expanda controles comuns de XAML e arraste um controle TextBlock para a superfície de design. Abra a janela de propriedades, e você encontrará opções para denominar esta instância do controle TextBlock. No campo nome, nomeie o TextBlock "myText." Isso se correlaciona com o atributo X:Name em XAML. Este atributo permite que você se refere ao TextBlock por nome, em outro lugar no arquivo XAML e no codebehind. E, porque este é o único controle na página, você pode também torná-lo muito grande: Expanda a categoria de texto e alterar o tamanho da fonte para 72px. O resultado final deve ser semelhante Figura 1. Você vai notar que, como fazer essas alterações no Inspetor de propriedades, a marcação XAML também é atualizada.


Figura 1 controle de TextBlock e XAML relacionado

Em seguida, arraste um controle de botão da caixa de ferramentas e colocá-lo para a esquerda do TextBlock. Na janela Propriedades, exibir os eventos disponíveis para o Button controle clicando no ícone de raio à direita do campo nome e, em seguida, clique duas vezes no campo para o evento Click. Visual Studio automaticamente gera um retorno adequado e alterna o modo de exibição para o code-behind para este evento. Na exibição da fonte XAML, a tag gerada deve ser algo como o seguinte:

<Button Click="Button_Click_1" />

Você pode realizar a mesma coisa no código, adicionando o clique = atributo para a marca XAML e, em seguida, fornecendo um nome ou permitindo autocomplete selecionar um para você. De qualquer maneira, você pode clique o evento e escolha navegar ao manipulador de eventos para navegar para o code-behind.

Agora adicione o seguinte código para o retorno de chamada:

this->myText->Text =
    "Hello World from XAML!";

Compilar e executar o aplicativo para verificar que, quando você clica no botão, o retorno de chamada modifica o texto de TextBlock (Figura 2).


Figura 2 atualizado TextBlock

Muita coisa vai nos bastidores aqui, assim que eu quero passar algum tempo Desconstruindo a magia que faz isso acontecer.

O que é o C + + CX?

C + + CX é a extensão de linguagem que fornece interoperabilidade entre C++ nativo e o tempo de execução do Windows. É uma ligação totalmente nativa que permite que você definir, instanciar e usar objetos em tempo de execução enquanto ainda fornece acesso à funcionalidade de C++ nativo e sintaxe com o qual você está familiarizado. Figura 3 lista os conceitos básicos. (Apesar de C + + CX é semelhante em muitas formas para o C + + Common Language Infrastructure, ou CLI, sintaxe, é uma língua separada e totalmente nativo extensão.)

Figura 3 C + + CX conceitos

Conceito Description
classe de interface Uma declaração abstrata dos métodos que suporte chamadas em um objeto que implementa a interface.
classe ref C + + palavra-chave CX que é usado para declarar uma classe de referência-contados em tempo de execução Windows que é usado para implementar interfaces.
^ Chamado um "chapéu" ou "pega", este é um ponteiro inteligente para uso com ref classes e interfaces; ele automaticamente incrementa e decrementa referência contagens apropriadamente.
ref novo Expressão que "ativa" (construções) um WinRT classe.
namespace padrão Contém definições de tipo fundamental (uint32, float64) que mapeiam para tipos WinRT.
Plataforma namespace Contém definições de tipo que fornecem o modelo básico de interoperabilidade com o Windows Runtime (Object ^, String ^).
Propriedade Um pseudo-field em uma classe; Ele é composto de uma função de getter e uma função de setter opcional e se comporta como um campo. (Por exemplo, um objeto TextBlock tem uma propriedade de texto.)

Parcial Classes e XAML código geração no Solution Explorer, navegue até MainPage.xaml.h, que contém uma definição parcial da classe MainPage XAML:

public ref class MainPage sealed
{
public:
  MainPage();
protected:
  virtual void OnNavigatedTo(
    Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
  void Button_Click_1(
    Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
};

Esta é a parte da definição que você pode editar e modificar (por exemplo, se você quiser adicionar alguns membros de dados para a classe MainPage). Observe que a declaração do manipulador de eventos Button_Click_1 foi inserida para esta definição da classe pelo Visual Studio quando você clicou duas vezes o evento Click anteriormente.

Botão direito do mouse no nome da classe MainPage e escolha ir para definição. Você deverá ver dois resultados: a definição de MainPage.xaml.h e uma definição parcial em MainPage.g.h. A segunda definição é gerada durante uma compilação quando o compilador XAML analisa MainPage. XAML e gera MainPage.g.h. MainPage.xaml.cpp inclui MainPage.xaml.h, que por sua vez inclui este arquivo gerado. Essas definições de classe são combinadas para produzir a classe final. Esta técnica permite que os usuários e o gerador de código para inserir informações na definição de classe.

Navegue até a definição parcial do MainPage encontrado em MainPage.g.h:

partial ref class MainPage : public ::Windows::UI::Xaml::Controls::Page,
  public ::Windows::UI::Xaml::Markup::IComponentConnector
{
public:
  void InitializeComponent();
  virtual void Connect(int connectionId, ::Platform::Object^ target);
private:
  bool _contentLoaded;
  private: ::Windows::UI::Xaml::Controls::TextBlock^ myText;
};

Você pode ver que este gerou o arquivo, o nome: x = "myText" atributo no TextBlock fez com que o compilador XAML gerar um membro de classe chamado myText. Aqui você também pode observar que MainPage herda da classe base Windows XAML Page e implementa a interface IComponentConnector. (IComponent­conector e seu associado método Connect são o que conectar o evento Click para o retorno de chamada Button_Click_1.)

Vinculação de dados em C + + CX ligação de dados é um conceito poderoso que permite que você facilmente fio o código e dados para a interface do usuário. Ele também permite que padrões de design de alto nível como o Model-View-ViewModel (MVVM) que fornecem excelente abstração entre dados, código e a interface do usuário.

Em C + + CX, você pode habilitar uma classe para ser ligados a dados em um número de maneiras:

  • Atribuir a classe com o atributo vinculável
  • Implementar a interface ICustomPropertyProvider
  • Implementar o IMap < String ^, objeto ^ > interface

Vou me concentrar no atributo vinculável, mas eu mencionei outras interfaces, porque em algumas situações, eles são mais adequados. Em particular, o atributo vinculável gera informações adequadas de vinculação de dados apenas se está marcada a classe vinculados a dados pública. Sempre que quiser uma classe privada ser acoplável, você precisará implementar uma das interfaces listadas.

Em seu aplicativo, adicione uma nova classe clicando o projeto e escolha Add, classe para abrir o Assistente para adicionar classe. Não há nenhuma opção para C + + classe CX (que é o que você precisa), então, adicionar uma classe nativa, nomeando-o pessoa. Visual Studio deve gerar uma classe Person.h e Person.cpp e adicioná-los ao seu projeto.

A classe pessoa precisa várias modificações (demonstrado no Figura 4):

Figura 4-Definição da classe pessoa

// person.h
#pragma once
namespace App12 {
  [Windows::UI::Xaml::Data::Bindable]
  public ref class Person sealed
  {
  public:
    Person(void);
    property Platform::String^ Name;
    property Platform::String^ Phone;
  };
}
// person.cpp
#include "pch.h"
#include "person.h"
using namespace App12;
Person::Person(void)
{
  Name = "Maria Anders";
  Phone = "030-0074321";
}
  • A definição de classe é alterada de classe para classe ref.
  • A classe ref é marcada como público e selado. "Público" é necessário para o compilador XAML encontrar essa classe e gerar informações de ligação de dados. Além disso, C + + CX não oferece suporte classes sem lacre públicas sem uma classe base, então a classe deve ser selada.
  • O destruidor ~Person(void) é removido porque nenhum destruidor é necessário para esta classe.
  • A classe é movida para o namespace usado pelo aplicativo (no exemplo mostrado no Figura 4, o namespace é "App12", mas isso irá variar com base no nome que você deu seu projeto). Para o Bindable atributo para o trabalho (e para satisfazer as regras de metadados do WinRT), a classe deve estar em um namespace.
  • A classe é atribuída com [Windows::UI::Xaml::Data::Bin­dável]. Esse atributo indica para o compilador XAML que deve gerar informações de ligação de dados para a classe.
  • Duas propriedades do tipo Platform::String ^: Nome e telefone são adicionados. (Propriedades só podem ser ligados a dados.)

Agora, na MainPage. XAML, adicione um segundo TextBlock abaixo da primeira e denominá-lo da mesma forma. No XAML, altere o atributo de texto dos dois TextBlocks texto = "{Binding nome}" e texto = "{telefone Binding}", respectivamente. Isto diz a interface do usuário para encontrar as propriedades nome e telefone no objeto vinculado a dados e aplicá-los para o campo de texto da classe. O XAML deve ser semelhante a Figura 5. (Quando os atributos de texto são alterados para ser vinculado a dados, eles não têm conteúdo quando eles são mostrados no designer; Isso é esperado.)


Ligação de dados Figura 5 em XAML

Em seguida, no MainPage.xaml.h, incluem Person.h e adicione um datamember privada do tipo pessoa ^ à classe MainPage. O nome m_Person. Finalmente, em MainPage.xaml.cpp, no método OnNavigatedTo, adicione o seguinte código:

m_Person = ref new Person;
this->DataContext = m_Person;

O tempo de execução XAML invoca o método de OnNavigatedTo antes desta página é exibida na tela, então é um lugar apropriado para configurar este datacontext. Este código irá criar uma nova instância da classe pessoa e vinculá-lo a seu objeto MainPage. Executar o aplicativo novamente, e você verá que foram aplicadas as propriedades nome e telefone para os atributos de texto de TextBlock.

A infra-estrutura de ligação de dados também fornece para os objetos de dados-limite a ser notificado se alterar o conteúdo da propriedade. Altere o método de Button_Click_1 para o seguinte código:

this->m_Person->Name = "Anders, Maria";

Se você executa o aplicativo novamente e clicar no botão, você verá que não altere o conteúdo do TextBlock. Para estes conteúdos a ser atualizado, a classe pessoa precisa implementar o INotify­interface de PropertyChanged.

INotifyPropertyChanged tem um item: um evento chamado PropertyChanged, do tipo PropertyChangedEventHandler ^. A propriedade Name também precisa ser alterado de uma propriedade trivial para uma propriedade totalmente definida (incluindo um armazenamento de backup fornecido pelo usuário) para oferecer suporte a disparar esse evento quando a propriedade é modificada. Além disso, adicionei uma função de conveniência chamada NotifyPropertyChanged que aciona esse evento quando ele é chamado. Esta é uma refatoração comum, porque várias propriedades muitas vezes exigem notificação. A implementação é mostrada em Figura 6. (Este exemplo só fornece para a propriedade nome a ser obrigatória. Uma mudança semelhante que precisam ser feitas para a propriedade do telefone.)

Figura 6 pessoa classe com declaração obrigatória Name Propriedade

// person.h
#pragma once
namespace App12 {
  namespace WUXD = Windows::UI::Xaml::Data;
  [WUXD::Bindable]
  public ref class Person sealed : WUXD::INotifyPropertyChanged
  {
  public:
    Person(void);
    property Platform::String^ Name {
      Platform::String^ get();
      void set(Platform::String^ value);
    }
    property Platform::String^ Phone;
    virtual event WUXD::PropertyChangedEventHandler^ PropertyChanged;
  private:
    void NotifyPropertyChanged(Platform::String^ prop);
    Platform::String^ m_Name;
  };
}
// person.cpp
#include "pch.h"
#include "person.h"
using namespace App12;
using namespace Platform;
using namespace WUXD;
Person::Person(void)
{
  Name = "Maria Anders";
  Phone = "030-0074321";
}
String^ Person::Name::get(){ return m_Name; }
void Person::Name::set(String^ value) {
  if(m_Name != value) {
    m_Name = value;
    NotifyPropertyChanged("Name");
  }
}
void Person::NotifyPropertyChanged(String^ prop) {
  PropertyChangedEventArgs^ args = 
    ref new PropertyChangedEventArgs(prop);
  PropertyChanged(this, args);
}

Executar o aplicativo novamente com as INotifyPropertyChanged modificações feitas deve resultar em mudança de nome, quando o botão é clicado.

ItemsControls e coleções em C + + CX e XAML

XAML fornece rica interface do usuário controles, incluindo controles que podem dados vincular a uma coleção de objetos. Estes são coletivamente referidos como ItemsControls. Vou me concentrar em um em especial, chamado de ListView.

Abra MainPage. XAML e apagar o conteúdo do objeto raiz Grid, substituindo-o por apenas uma classe ListView. Nome que myListView de classe, conforme mostrado aqui:

<!-- ListView inside MainPage -->
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">*
  <ListView x:Name="myListView" />
</Grid>

Coleções em C + + CX o tempo de execução do Windows não fornece classes de coleção; apenas fornece interfaces para as coleções. Cada projeção (JavaScript, c# / Visual Basic e C + + CX) é responsável por fornecer suas próprias classes de coleção. Em C + + CX, essas implementações são encontradas no cabeçalho do collection.h (que já está incluído no pch.h do modelo de aplicativo em branco). Há duas classes de coleção principais definidas no namespace Platform::Collections: Platform::Collections::vector <T> para a representação de listas de dados e Platform::Collections::Map < T, U > para representar os dicionários. ItemsControls geralmente esperar um iterável lista de objetos, assim Vector <T> justifica-se nesse cenário.

Em MainPage.xaml.cpp, altere o método OnNavigatedTo para "ref novo" um vetor < pessoa ^ > e preenchê-lo com várias classes de pessoa. Em seguida, atribuí-lo para a propriedade ItemsSource de myListView:

void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
  (void) e; // Unused parameter
  auto vec =
    ref new Platform::Collections::Vector<Person^>;
  vec->Append(ref
    new Person("Maria Anders","030-0074321"));
  vec->Append(ref new Person("Ana Trujillo","(5) 555-4729"));
  // etc.
...
myListView->ItemsSource = vec;
}

Denominando o ListView finalmente, precisamos dizer a ListView como estilo de cada elemento individual. O ListView, em seguida, iterar sobre sua ItemsSource e, para cada elemento na coleção, gerar a interface do usuário apropriado e vincular seu DataContext para esse elemento. Para o estilo de ListView, você deve definir seu ItemTemplate, como mostrado na Figura 7. Observe que as propriedades do texto dentro do modelo tem as ligações de dados apropriadas para um objeto Person.

Figura 7 dentro de ListView MainPage com estilo ItemTemplate

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
  <ListView x:Name="myListView">
    <ListView.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Vertical">
          <TextBlock Text="{Binding Name}" FontSize="20" />
          <TextBlock Text="{Binding Phone}" FontSize="12" />
        </StackPanel>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</Grid>

Quando você compilar e executa este aplicativo, ele deve se parecer com Figura 8.


Figura 8 o ListView acabado

Saiba mais

Referências em XAML para o Windows 8 e C + + CX são um pouco escassos no momento. Para saber mais sobre o XAML, eu recomendo procura referências que falam sobre o XAML no Silverlight, como muitos dos mesmos conceitos se aplicam e muitos controles são nomeados da mesma forma, ou o mesmo e ter a mesma funcionalidade. O code-behind para essas referências será c#, então é necessária alguma tradução ou interpretação. Esta é principalmente uma operação mecânica, mas onde você topar com funcionalidade que é representada pelo .NET Base Class Library, você precisa olhar para as bibliotecas de tempo de execução C, Standard Template Library ou outras bibliotecas C++ (ou o tempo de execução do Windows) para realizar estas tarefas. Felizmente, todas essas bibliotecas de jogar bem com C + + CX.

Outros grandes recursos são os modelos disponíveis em Visual Studio 2012 para criar apps da loja do Windows, em particular a grade App e App de Split. Esses modelos demonstram muitos recursos avançados de um aplicativo bem-feito e decifrar seus segredos pode levar a maior compreensão das estruturas subjacentes.

Finalmente, eu recomendo que você olhar para o projeto "Hilo," uma aplicação em grande escala, escrita usando XAML e C++. O código e a documentação para esta aplicação podem ser encontradas em hilo.codeplex.com. Este projeto foi desenvolvido pela Microsoft patterns & práticas de equipe e demonstra C++ padrão, moderno; portabilidade de bibliotecas C++ existentes para que eles podem ser usados em aplicações de armazenamento do Windows; e muitas práticas recomendadas quando usando C + + CX.

Espero que tenha lhe dado um vislumbre de que você pode fazer com C + + CX com XAML, mas esta é apenas a superfície. Como com qualquer nova tecnologia, você pode esperar para passar muitas madrugadas navegando documentação e fóruns e com o nariz enterrado em livros técnicos. Mas o poder e a capacidade de C + + CX e XAML valem a pena aprender mais sobre. Eles permitem escrever aplicativos ricos, rápidos em muito menos tempo.

Andy Rich é engenheiro de desenvolvimento de software da Microsoft e passou os últimos nove anos, o compilador C++ front-end de teste. Mais recentemente, ele foi um dos principais testadores de C + + extensões de linguagem CX e trabalhou em estreita colaboração com a equipe XAML no teste o cenário combinado de XAML/C++.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Tim Heuer, Marian Luparu e Mara Travassos