Criar uma Linguagem Específica de Domínio baseada no Windows Forms
Você pode usar Windows Forms para exibir o estado de um modelo DSL (linguagem específica do domínio) em vez de usar um diagrama DSL. Este tópico explica como associar um Windows Form a uma DSL usando o SDK de Visualização e Modelagem do Visual Studio.
A seguinte imagem mostra uma interface do usuário do Windows Form e o gerenciador de modelos para uma instância DSL:
Criar uma DSL do Windows Forms
O modelo DSL Minimal WinForm Designer cria uma DSL mínima que você pode modificar para atender aos seus requisitos.
Crie uma DSL com base no modelo Minimal WinForm Designer.
Neste passo a passo, os seguintes nomes são considerados:
- Solução e nome DSL:
FarmApp
- Namespace:
Company.FarmApp
- Solução e nome DSL:
Experimente o exemplo inicial que o modelo fornece:
Transformar todos os modelos.
Compilar e executar a amostra (Ctrl+F5).
Na instância experimental do Visual Studio, abra o arquivo
Sample
no projeto de depuração.Observe que ele é exibido em um controle Windows Forms.
Você também pode ver os elementos do modelo exibidos no Explorer.
Adicione alguns elementos no formulário ou no Explorer e observe se eles aparecem na outra exibição.
Na instância principal do Visual Studio, observe os seguintes pontos sobre a solução DSL:
DslDefinition.dsl
não contém elementos de diagrama. Isso ocorre porque você não usará diagramas DSL para exibir modelos de instância dessa DSL. Em vez disso, você associará um Windows Form ao modelo e os elementos no formulário exibirão o modelo.Além dos projetos
Dsl
eDslPackage
, a solução contém um terceiro projeto chamadoUI.
UI que contém a definição de um controle do Windows Forms.DslPackage
depende deUI
eUI
depende deDsl
.No projeto
DslPackage
,UI\DocView.cs
contém o código que exibe o controle do Windows Forms definido no projetoUI
.O projeto
UI
contém um exemplo funcional de um controle de formulário associado à DSL. No entanto, ele não funcionará quando você tiver alterado a Definição de DSL. O projetoUI
contém:Uma classe do Windows Forms chamada
ModelViewControl
.Um arquivo chamado
DataBinding.cs
que contém uma definição parcial adicional deModelViewControl
. Para ver seu conteúdo, no Gerenciador de Soluções, abra o menu de atalho do arquivo e escolha Exibir Código.
Sobre o projeto da interface do usuário
Ao atualizar o arquivo de Definição de DSL para definir sua DSL, você precisará atualizar o controle no projeto UI
para exibir sua DSL. Ao contrário dos projetos Dsl
e DslPackage
, o projeto de amostra UI
não é gerado de DslDefinitionl.dsl
. Você poderá adicionar arquivos .tt para gerar o código se desejar, embora isso não seja abordado neste passo a passo.
Atualizar a definição de DSL
A imagem a seguir é a definição de DSL usada neste passo a passo.
Abra DslDefinition.dsl no designer DSL.
Excluir ExampleElement
Renomeie a classe de domínio ExampleModel como
Farm
.Forneça propriedades de domínio adicionais nomeadas
Size
do tipo Int32 eIsOrganic
do tipo booliano.Observação
Se você excluir a classe de domínio raiz e criar uma nova raiz, precisará redefinir a propriedade Editor Root Class. No Gerenciador DSL, selecione Editor. Na janela Propriedades, defina Classe Raiz como
Farm
.Use a ferramenta Classe de Domínio Nomeada para criar as seguintes classes de domínio:
Field
– dê a ela uma propriedade de domínio adicional chamadaSize
.Animal
– na janela Propriedades, defina Modificador de Herança como Abstrato.
Observação
A ferramenta Classe de Domínio Nomeada e as outras ferramentas mencionadas nesta seção são encontradas na janela de ferramentas da Caixa de Ferramentas. Você pode abrir ou ocultar essa janela com Exibir>Caixa de Ferramentas.
Use a ferramenta Classe de Domínio para criar as seguintes classes:
Sheep
Goat
Use a ferramenta Herança para fazer
Goat
eSheep
herdar deAnimal
.Use a ferramenta Inserção para inserir
Field
eAnimal
emFarm
.Talvez você queira organizar o diagrama. Para reduzir o número de elementos duplicados, use o comando Bring Subtree Here no menu de atalhos dos elementos folha.
Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções.
Compile o projeto DSL.
Observação
Nesta fase, os outros projetos não serão compilados sem erros. No entanto, queremos compilar o projeto DSL para que seu assembly esteja disponível para o Assistente da Fonte de Dados.
Atualizar o projeto da interface do usuário
Agora você pode criar um novo controle de usuário que exibirá as informações armazenadas no modelo DSL. A maneira mais fácil de conectar o controle de usuário ao modelo é por meio de associações de dados. O tipo de adaptador de associação de dados chamado ModelingBindingSource foi projetado especificamente para conectar DSLs a interfaces não VMSDK.
Definir seu modelo DSL como uma fonte de dados
No menu Dados, escolha Mostrar Fontes de Dados.
A janela Fontes de Dados é aberta.
Escolha Adicionar Nova Fonte de Dados. O Assistente de Configuração de Fonte de Dados é aberto.
Escolha Objeto, Avançar.
Expanda DSL, Company.FarmApp e selecione Farm, que é a classe raiz do modelo. Escolha Concluir.
No Gerenciador de Soluções, o projeto da interface do usuário agora contém Properties\DataSources\Farm.datasource
As propriedades e as relações da classe de modelo aparecem na janela Fontes de Dados.
Conectar seu modelo a um formulário
No projeto da interface do usuário, exclua todos os arquivos .cs existentes.
Adicione um novo arquivo Controle de Usuário chamado
FarmControl
ao projeto UI.Na janela Fontes de Dados, no menu suspenso do Farm, escolha Detalhes.
Deixe as configurações padrão para as outras propriedades.
Abra FarmControl.cs na exibição de design.
Arraste Farm da janela Fontes de Dados para FarmControl.
Um conjunto de controles é exibido, um para cada propriedade. As propriedades de relação não geram controles.
Exclua farmBindingNavigator. Isso também é gerado automaticamente no designer
FarmControl
, mas não é útil para esse aplicativo.Usando a caixa de ferramentas, crie duas instâncias de DataGridView e nomeie-as como
AnimalGridView
eFieldGridView
.Observação
Uma etapa alternativa é arrastar os itens Animais e Campos da janela Fontes de Dados para o controle. Essa ação cria automaticamente grades de dados e associações entre a exibição de grade e a fonte de dados. No entanto, essa associação não funciona corretamente para DSLs. Portanto, é melhor criar as grades de dados e as associações manualmente.
Se a Caixa de Ferramentas não contiver a ferramenta ModelingBindingSource, adicione-a. No menu de atalho da guia Dados, selecione Escolher Itens. Na caixa de diálogo Escolher Itens da Caixa de Ferramentas, selecione ModelingBindingSource na guia .NET Framework.
Usando a Caixa de Ferramentas, crie duas instâncias de ModelingBindingSource e nomeie-as como
AnimalBinding
eFieldBinding
.Defina a propriedade DataSource de cada ModelingBindingSource como farmBindingSource.
Defina a propriedade DataMember como Animais ou Campos.
Defina as propriedades DataSource de
AnimalGridView
comoAnimalBinding
e deFieldGridView
comoFieldBinding
.Ajuste o layout do controle Farm ao seu gosto.
O ModelingBindingSource é um adaptador que executa várias funções específicas para DSLs:
Ele encapsula atualizações em uma Transação de Repositório VMSDK.
Por exemplo, quando o usuário exclui uma linha da grade de exibição de dados, uma associação regular resultaria em uma exceção de transação.
Ela garante que, quando o usuário seleciona uma linha, a janela Propriedades exibe as propriedades do elemento de modelo correspondente em vez da linha da grade de dados.
Esquema de links entre fontes de dados e exibições.
Concluir as associações à DSL
Adicione o seguinte código em um arquivo de código separado no projeto de interface do usuário:
using System.ComponentModel; using Microsoft.VisualStudio.Modeling; using Microsoft.VisualStudio.Modeling.Design; namespace Company.FarmApp { partial class FarmControl { public IContainer Components { get { return components; } } /// <summary>Binds the WinForms data source to the DSL model. /// </summary> /// <param name="nodelRoot">The root element of the model.</param> public void DataBind(ModelElement modelRoot) { WinFormsDataBindingHelper.PreInitializeDataSources(this); this.farmBindingSource.DataSource = modelRoot; WinFormsDataBindingHelper.InitializeDataSources(this); } } }
No projeto DslPackage, edite DslPackage\DocView.tt para atualizar a seguinte definição de variável:
string viewControlTypeName = "FarmControl";
Testar a DSL
A solução DSL agora pode ser compilada e executada, embora talvez você queira adicionar outras melhorias posteriormente.
Compile e execute a solução.
Na instância experimental do Visual Studio, abra o arquivo de Amostra.
No FarmApp Explorer, abra o menu de atalho no nó raiz Farm e escolha Add New Goat.
Goat1
aparece no modo de exibição Animals.Aviso
Você deve usar o menu de atalho no nó Farm, não no nó Animals.
Selecione o nó raiz Farm e exiba suas propriedades.
No modo de exibição de formulário, altere o Name ou Size da fazenda.
Quando você navega para longe de cada campo no formulário, a propriedade correspondente é alterada na janela Propriedades.
Aprimorar o DSL
Fazer com que as propriedades atualizem imediatamente
Na exibição de design de FarmControl.cs, selecione um campo simples, como Name, Size ou IsOrganic.
Na janela Propriedades, expanda DataBindings e abra (Avançado).
Na caixa de diálogo Formatação e Associação Avançada, em Modo de Atualização da Fonte de Dados, escolha OnPropertyChanged.
Compile e execute a solução.
Verifique se, quando você altera o conteúdo do campo, a propriedade correspondente do modelo Farm é alterada imediatamente.
Fornecer botões Adicionar
Na exibição de design de FarmControl.cs, use a caixa de ferramentas para criar um botão no formulário.
Edite o nome e o texto do botão, por exemplo, para
New Sheep
.Abra o código por trás do botão (por exemplo, clicando duas vezes nele).
Edite da seguinte maneira:
private void NewSheepButton_Click(object sender, EventArgs e) { using (Transaction t = farm.Store.TransactionManager.BeginTransaction("Add sheep")) { elementOperations.MergeElementGroup(farm, new ElementGroup(new Sheep(farm.Partition))); t.Commit(); } } // The following code is shared with other add buttons: private ElementOperations operationsCache = null; private ElementOperations elementOperations { get { if (operationsCache == null) { operationsCache = new ElementOperations(farm.Store, farm.Partition); } return operationsCache; } } private Farm farm { get { return this.farmBindingSource.DataSource as Farm; } }
Você também precisará inserir a seguinte diretiva:
using Microsoft.VisualStudio.Modeling;
Adicione botões semelhantes para Cabras e Campos.
Compile e execute a solução.
Verifique se o novo botão adiciona um item. O novo item deve aparecer no FarmApp Explorer e na exibição de grade de dados apropriada.
Você deve ser capaz de editar o nome do elemento na exibição de grade de dados. Você também pode excluir.
Sobre o código para adicionar um elemento
Para os novos botões de elemento, o código alternativo a seguir é um pouco mais simples.
private void NewSheepButton_Click(object sender, EventArgs e)
{
using (Transaction t = farm.Store.TransactionManager.BeginTransaction("Add sheep"))
{
farm.Animals.Add(new Sheep(farm.Partition)); ;
t.Commit();
}
}
No entanto, esse código não define um nome padrão para o novo item. Ele não executa nenhuma mesclagem personalizada que você possa ter definido nas Diretivas de Mesclagem de Elementos da DSL e não executa nenhum código de mesclagem personalizado que possa ter sido definido.
Portanto, recomendamos que você use ElementOperations para criar elementos. Para obter mais informações, confira Personalizar a criação e a movimentação de elementos.