Tworzenie języka specyficznego dla domeny opartego na formularzach systemu Windows

Formularze systemu Windows umożliwiają wyświetlanie stanu modelu języka specyficznego dla domeny (DSL), a nie diagramu DSL. W tym temacie przedstawiono proces tworzenia powiązania formularza systemu Windows z biblioteką DSL przy użyciu zestawu SDK wizualizacji i modelowania programu Visual Studio.

Na poniższej ilustracji przedstawiono interfejs użytkownika formularza systemu Windows i eksplorator modelu dla wystąpienia DSL:

DSL instance in Visual Studio

Tworzenie rozszerzenia DSL formularzy systemu Windows

Minimalny szablon WinForm Projektant DSL tworzy minimalny rozmiar DSL, który można zmodyfikować zgodnie z własnymi wymaganiami.

  1. Utwórz rozszerzenie DSL na podstawie szablonu minimalnego Projektant WinForm.

    W tym przewodniku przyjmuje się następujące nazwy:

    • Nazwa rozwiązania i rozszerzenia DSL: FarmApp
    • Przestrzeń nazw: Company.FarmApp
  2. Poeksperymentuj z początkowym przykładem, który udostępnia szablon:

    1. Przekształć wszystkie szablony.

    2. Skompiluj i uruchom przykład (Ctrl+F5).

    3. W eksperymentalnym wystąpieniu programu Visual Studio otwórz Sample plik w projekcie debugowania.

      Zwróć uwagę, że jest on wyświetlany w kontrolce Formularze systemu Windows.

      Możesz również zobaczyć elementy modelu wyświetlane w Eksploratorze.

      Dodaj niektóre elementy w formularzu lub Eksploratorze i zwróć uwagę, że są one wyświetlane na innym ekranie.

    W głównym wystąpieniu programu Visual Studio zwróć uwagę na następujące kwestie dotyczące rozwiązania DSL:

  • DslDefinition.dsl nie zawiera żadnych elementów diagramu. Dzieje się tak, ponieważ nie będziesz używać diagramów DSL do wyświetlania modeli wystąpień tego rozszerzenia DSL. Zamiast tego powiążesz formularz systemu Windows z modelem, a elementy w formularzu będą wyświetlać model.

  • Oprócz Dsl projektów i DslPackage rozwiązanie zawiera trzeci projekt o nazwie UI.Projekt interfejsu użytkownika zawiera definicję kontrolki Windows Forms. DslPackage zależy od UIelementu i UI zależy od Dslelementu .

  • W projekcie DslPackage zawiera kod, UI\DocView.cs który wyświetla kontrolkę Windows Forms zdefiniowaną w projekcie UI .

  • Projekt UI zawiera działającą próbkę kontrolki formularza powiązanej z dsl. Nie będzie jednak działać, gdy zmieniono definicję DSL. Projekt UI zawiera:

    • Klasa Windows Forms o nazwie ModelViewControl.

    • Plik o nazwie DataBinding.cs zawierający dodatkową częściową definicję ModelViewControl. Aby wyświetlić jego zawartość, w Eksplorator rozwiązań otwórz menu skrótów dla pliku i wybierz pozycję Wyświetl kod.

Informacje o projekcie interfejsu użytkownika

Podczas aktualizowania pliku definicji DSL w celu zdefiniowania własnego rozszerzenia DSL należy zaktualizować kontrolkę w projekcie UI , aby wyświetlić rozszerzenie DSL. Dsl W przeciwieństwie do projektów i DslPackage przykładowy UI projekt nie jest generowany na podstawie DslDefinitionl.dslelementu . Jeśli chcesz, możesz dodać pliki tt, aby wygenerować kod, chociaż nie zostało to omówione w tym przewodniku.

Aktualizowanie definicji DSL

Na poniższej ilustracji przedstawiono definicję DSL używaną w tym przewodniku.

DSL definition

  1. Otwórz plik DslDefinition.dsl w projektancie DSL.

  2. Usuń element ExampleElement

  3. Zmień nazwę klasy domeny ExampleModel na Farm.

    Nadaj mu dodatkowe właściwości domeny o nazwie Size typu Int32 i IsOrganic typu Wartość logiczna.

    Uwaga

    Jeśli usuniesz klasę domeny głównej, a następnie utworzysz nowy katalog główny, musisz zresetować właściwość Klasa główna edytora. W Eksploratorze DSL wybierz pozycję Edytor. Następnie w okno Właściwości ustaw wartość Klasa główna na Farm.

  4. Użyj narzędzia Nazwana klasa domeny, aby utworzyć następujące klasy domen:

    • Field - Nadaj tej dodatkowej właściwości domeny o nazwie Size.

    • Animal- W okno Właściwości ustaw modyfikator dziedziczenia na Abstrakcja.

    Uwaga

    Narzędzie Nazwana klasa domeny i inne narzędzia wymienione w tej sekcji znajdują się w oknie narzędzia Przybornik . Możesz otworzyć lub ukryć to okno za pomocą przybornika widoków>.

  5. Użyj narzędzia Klasa domeny, aby utworzyć następujące klasy:

    • Sheep

    • Goat

  6. Użyj narzędzia Dziedziczenie, aby tworzyć Goat i Sheep dziedziczyć z Animalprogramu .

  7. Użyj narzędzia Osadzanie, aby osadzić Field element i Animal w obszarze Farm.

  8. Możesz chcieć uporządkować diagram. Aby zmniejszyć liczbę zduplikowanych elementów, użyj polecenia Bring Subtree Here w menu skrótów elementów liścia.

  9. Przekształć wszystkie szablony na pasku narzędzi Eksplorator rozwiązań.

  10. Skompiluj projekt Dsl .

    Uwaga

    Na tym etapie inne projekty nie będą kompilować bez błędów. Chcemy jednak skompilować projekt Dsl, aby jego zestaw był dostępny dla Kreatora źródła danych.

Aktualizowanie projektu interfejsu użytkownika

Teraz możesz utworzyć nową kontrolkę użytkownika, która będzie wyświetlać informacje przechowywane w modelu DSL. Najprostszym sposobem połączenia kontrolki użytkownika z modelem jest powiązanie danych. Typ adaptera powiązania danych o nazwie ModelingBindingSource został specjalnie zaprojektowany w celu łączenia list DSL z interfejsami innych niż VMSDK.

Definiowanie modelu DSL jako źródła danych

  1. W menu Dane wybierz pozycję Pokaż źródła danych.

    Zostanie otwarte okno Źródła danych.

    Wybierz pozycję Dodaj nowe źródło danych. Zostanie otwarty Kreator konfiguracji źródła danych.

  2. Wybierz pozycję Obiekt, Dalej.

    Rozwiń węzeł Dsl, Company.FarmApp i wybierz pozycję Farma, która jest klasą główną modelu. Wybierz pozycję Zakończ.

    W Eksplorator rozwiązań projekt interfejsu użytkownika zawiera teraz właściwości\DataSources\Farm.datasource

    Właściwości i relacje klasy modelu są wyświetlane w oknie Źródła danych.

    Data sources window

Połączenie modelu do formularza

  1. W projekcie interfejsu użytkownika usuń wszystkie istniejące pliki cs.

  2. Dodaj nowy plik kontrolki użytkownika o nazwie FarmControl do projektu interfejsu użytkownika .

  3. W oknie Źródła danych w menu rozwijanym farmy wybierz pozycję Szczegóły.

    Pozostaw ustawienia domyślne dla innych właściwości.

  4. Otwórz plik FarmControl.cs w widoku projektu.

    Przeciągnij pozycję Farma z okna Źródła danych na FarmControl.

    Zostanie wyświetlony zestaw kontrolek, po jednym dla każdej właściwości. Właściwości relacji nie generują kontrolek.

  5. Usuń farmBindingNavigator. Ta funkcja jest również generowana automatycznie w FarmControl projektancie, ale nie jest przydatna w przypadku tej aplikacji.

  6. Za pomocą przybornika utwórz dwa wystąpienia elementu DataGridView i nadaj im AnimalGridView nazwę i FieldGridView.

    Uwaga

    Alternatywnym krokiem jest przeciągnięcie elementów Zwierzęta i Pola z okna Źródła danych do kontrolki. Ta akcja automatycznie tworzy siatki danych i powiązania między widokiem siatki a źródłem danych. Jednak to powiązanie nie działa poprawnie w przypadku list DSL. Dlatego lepiej jest ręcznie utworzyć siatki danych i powiązania.

  7. Jeśli przybornik nie zawiera narzędzia ModelingBindingSource , dodaj go. W menu skrótów karty Dane wybierz pozycję Wybierz elementy. W oknie dialogowym Wybieranie elementów przybornika wybierz pozycję ModelingBindingSource na karcie .NET Framework.

  8. Za pomocą przybornika utwórz dwa wystąpienia elementu ModelingBindingSource i nadaj im AnimalBinding nazwę i FieldBinding.

  9. Ustaw właściwość DataSource każdego elementu ModelingBindingSource na farmBindingSource.

    Ustaw właściwość DataMember na Zwierzęta lub Pola.

  10. Ustaw właściwości DataSource wartości AnimalGridView na AnimalBinding, i FieldGridView na FieldBinding.

  11. Dostosuj układ kontrolki Farma do swojego smaku.

    ModelingBindingSource to karta, która wykonuje kilka funkcji specyficznych dla praw podmiotów danych:

  • Opakowuje aktualizacje w transakcji magazynu VMSDK.

    Na przykład gdy użytkownik usunie wiersz z siatki widoku danych, regularne powiązanie spowoduje wyjątek transakcji.

  • Gwarantuje to, że gdy użytkownik wybierze wiersz, okno Właściwości wyświetli właściwości odpowiedniego elementu modelu zamiast wiersza siatki danych.

    Schema of the DSL binding

    Schemat łączy między źródłami danych i widokami.

Ukończ powiązania z platformą DSL

  1. Dodaj następujący kod w osobnym pliku kodu w projekcie interfejsu użytkownika :

    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);
        }
      }
    }
    
  2. W projekcie DslPackage zmodyfikuj plik DslPackage\DocView.tt, aby zaktualizować następującą definicję zmiennej:

    string viewControlTypeName = "FarmControl";
    

Testowanie rozszerzenia DSL

Rozwiązanie DSL może teraz kompilować i uruchamiać, chociaż warto dodać dalsze ulepszenia później.

  1. Skompiluj i uruchom rozwiązanie.

  2. W eksperymentalnym wystąpieniu programu Visual Studio otwórz plik Przykładowy .

  3. W Eksploratorze FarmApp otwórz menu skrótów w węźle głównym Farma, a następnie wybierz pozycję Dodaj nową kozę.

    Goat1 pojawi się w widoku Zwierzęta .

    Ostrzeżenie

    Musisz użyć menu skrótów w węźle Farma , a nie węzła Zwierzęta .

  4. Wybierz węzeł główny farmy i wyświetl jego właściwości.

    W widoku formularza zmień nazwę lub rozmiar farmy.

    Po przejściu z dala od każdego pola w formularzu odpowiednia właściwość zmienia się w okno Właściwości.

Ulepszanie rozszerzenia DSL

Natychmiastowe aktualizowanie właściwości

  1. W widoku projektu pliku FarmControl.cs wybierz proste pole, takie jak Nazwa, Rozmiar lub IsOrganic.

  2. W okno Właściwości rozwiń węzeł DataBindings i otwórz (zaawansowane).

    W oknie dialogowym Formatowanie i powiązanie zaawansowane w obszarze Tryb aktualizacji źródła danych wybierz pozycję OnPropertyChanged.

  3. Skompiluj i uruchom rozwiązanie.

    Sprawdź, czy po zmianie zawartości pola odpowiednia właściwość modelu farmy zmienia się natychmiast.

Podaj przyciski Dodaj

  1. W widoku projektu pliku FarmControl.cs użyj przybornika, aby utworzyć przycisk w formularzu.

    Edytuj nazwę i tekst przycisku, na przykład na New Sheep.

  2. Otwórz kod za przyciskiem (na przykład klikając go dwukrotnie).

    Edytuj go w następujący sposób:

    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; }
    }
    

    Należy również wstawić następującą dyrektywę:

    
    using Microsoft.VisualStudio.Modeling;
    
  3. Dodaj podobne przyciski dla koz i pól.

  4. Skompiluj i uruchom rozwiązanie.

  5. Sprawdź, czy nowy przycisk dodaje element. Nowy element powinien pojawić się zarówno w Eksploratorze FarmApp, jak i w odpowiednim widoku siatki danych.

    Należy mieć możliwość edytowania nazwy elementu w widoku siatki danych. Możesz również usunąć go z tego miejsca.

    Sample data grid view

Informacje o kodzie w celu dodania elementu

W przypadku przycisków nowego elementu poniższy kod alternatywny jest nieco prostszy.

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();
  }
}

Jednak ten kod nie ustawia domyślnej nazwy nowego elementu. Nie uruchamia ona żadnych dostosowanych scaleń, które mogły zostać zdefiniowane w dyrektywach scalania elementów DSL i nie uruchamia żadnego niestandardowego kodu scalania, który mógł zostać zdefiniowany.

Dlatego zalecamy utworzenie nowych elementów za pomocą ElementOperations polecenia . Aby uzyskać więcej informacji, zobacz Dostosowywanie tworzenia i przenoszenia elementów.