Windows フォームに基づくドメイン固有言語の作成
DSL の図を使用する代わりに Windows フォームを使用して、ドメイン固有言語 (DSL) モデルの状態を表示できます。このトピックでは、Visual Studio Visualization and Modeling SDK を使用して Windows フォームを DSL にバインドする手順を示します。
Windows フォーム UI とモデル エクスプローラーを表示する DSL インスタンス。
Windows フォーム DSL の作成
最小 WinForm デザイナー DSL テンプレートは、要件に合わせて変更できる最小 DSL を作成します。
最小限の WinForms DSL を作成するには
[最小 WinForm デザイナー] テンプレートから DSL を作成します。
このチュートリアルでは、次の名前を使用します。
ソリューションおよび DSL 名
FarmApp
名前空間
Company.FarmApp
テンプレートで提供される最初の例を使用してみます。
すべてのテンプレートを変換します。
サンプルをビルドし、実行します (CTRL+F5)。
Visual Studio の実験用インスタンスで、デバッグ プロジェクトで Sample ファイルを開きます。
Windowsフォーム コントロールに表示されることに注意してください。
また、エクスプローラーに表示されるモデルの要素を確認することもできます。
フォームまたはエクスプローラーにある要素を追加し、他のディスプレイに表示されることを確認します。
Visual Studio のメイン インスタンスでは、DSL ソリューションについて次の点に注意してください。
DslDefinition.dsl に図要素が含まれていません。これは、この DSL のインスタンス モデルの表示に DSL ダイアグラムを使用しないためです。代わりに、モデルに Windows フォームをバインドすると、フォームの要素にモデルが表示されます。
Dsl プロジェクトと DslPackage プロジェクトに加えて、ソリューションは、UI. という 3 番目のプロジェクトを含みます。UI プロジェクトには Windows フォーム コントロールの定義が含まれます。DslPackage は UIに依存し、UI は Dsl に依存します。
DslPackage プロジェクトで、UI\DocView.cs には UI プロジェクトで定義されている Windows フォーム コントロールを表示するコードが含まれています。
UI プロジェクトには、DSL にバインドされているフォーム コントロールの実際のサンプルが含まれています。ただし、DSL 定義を変更した場合、機能しません。UI プロジェクトには次が含まれます。
ModelViewControl という Windows フォーム クラス。
ModelViewControl の追加の部分定義を含む DataBinding.cs ファイル。その内容を確認するには、ソリューション エクスプローラーでファイルを対象とするショートカット メニューを開き、[コードの表示] を選択します。
UI プロジェクトについて
DSL 定義ファイルを更新して独自の DSL を定義する場合は、DSL を表示するために UI プロジェクト内のコントロールを更新する必要があります。Dsl プロジェクトと DslPackage プロジェクトとは異なり、サンプルの UI プロジェクトは DslDefinitionl.dsl からは生成されません。このチュートリアルでは説明していませんが、コードを生成するために .tt ファイルを追加することもできます。
DSL 定義の更新
次の DSL 定義はこのチュートリアルで使用されます。
DSL 定義を更新するには
DSL デザイナーで DslDefinition.dsl を開きます。
ExampleElement を削除します。
ExampleModel ドメイン クラスの名前を Farm に変更します。
Int32 型の Size および Boolean 型の IsOrganic という名前の追加のドメイン プロパティを指定します。
[!メモ]
ルート ドメイン クラスを削除し、新しいルートを作成すると、エディターのルート クラス プロパティをリセットする必要があります。DSL エクスプローラーで、[エディター] を選択します。次に、[プロパティ ウィンドウ] で、[ルート クラス] を [ファーム] に設定します。
次のドメイン クラスを作成するには、名前付きドメイン クラス ツールを使用します。
Field – Size という名前の追加のドメイン プロパティを設定します。
Animal – [プロパティ] ウィンドウで、[継承修飾子] を [抽象] に設定します。
ドメイン クラス ツールを使用して次のクラスを作成します。
羊
山羊
Animal から Goat と Sheep を継承するには、継承ツールを使用します。
Farm の下に Field と Animal を埋め込むには、埋め込みツールを使用します。
図を整理した方がよい場合があります。重複する要素の数を減らすには、リーフ要素のショートカット メニューの [Bring Subtree Here] (ここにサブツリーを移動) コマンドを使用します。
ソリューション エクスプローラーのツール バーの [すべてのテンプレートの変換]。
Dsl プロジェクトをビルドします。
[!メモ]
この段階で、他のプロジェクトはエラーなしで正常にビルドされません。ただし、データ ソース ウィザードでアセンブリが使用できるように Dsl プロジェクトをビルドします。
UI プロジェクトの更新
これで、DSL モデルに格納されている情報を表示する新しいユーザー コントロールを作成できます。モデルにユーザー コントロールを接続する最も簡単な方法は、データ バインディングを介する方法です。ModelingBindingSource という名前のデータ バインディング アダプター型は、DSL を非 VMSDK インターフェイスに接続するように特別に設計されています。
DSL モデルをデータ ソースとして定義するには
[データ] メニューの [データ ソースの表示] をクリックします。
[データ ソース] ウィンドウが開きます。
[新しいデータ ソースの追加] を選択します。データ ソース構成ウィザードが開きます。
[オブジェクト]、[次へ] をクリックします。
[Dsl]、[Company.FarmApp] を展開し、モデルのルート クラスである [ファーム] を選択します。[完了] をクリックします。
ソリューション エクスプローラーで確認すると、UI プロジェクトには Properties\DataSources\Farm.datasource が含まれています。
モデル クラスのプロパティとリレーションシップは、[データ ソース] ウィンドウに表示されます。
モデルをフォームに接続するには
UI プロジェクトでは、既存のすべての .cs ファイルを削除します。
FarmControl という名前の新しいユーザー コントロール ファイルを UI プロジェクトに追加します。
[データ ソース] ウィンドウの [ファーム] メニューで、[詳細] を選択します。
他のプロパティは既定の設定のままにします。
デザイン ビューで FarmControl.cs を開きます。
[ファーム] をデータ ソースから FarmControl にドラッグします。
一連のコントロールは、プロパティごとに 1 つが表示されます。リレーションシップ プロパティは、コントロールを生成しません。
farmBindingNavigator を削除します。これも FarmControl デザイナーで自動的に生成されますが、このアプリケーションでは使用しません。
ツールボックスを使用して、DataGridView のインスタンスを 2 個作成し、AnimalGridView および FieldGridView という名前を付けます。
[!メモ]
代替手順は、動物またはフィールド項目を、データ ソース ウィンドウからコントロールにドラッグします。この操作は自動的にグリッドのビューとデータ ソースの間でデータ グリッドとバインドを作成します。ただし、このバインディングは DSL で正しく機能しません。したがって、データ グリッドとバインドを手動で作成することをお勧めします。
ツールボックスに ModelingBindingSource ツールが表示されていない場合は追加します。[データ] タブのショートカット メニューの [アイテムの選択] をクリックします。[ツールボックス アイテムの選択] ダイアログで、[.NET Framework] タブから [ModelingBindingSource] をクリックします。
ツールボックスを使用して、ModelingBindingSource のインスタンスを 2 個作成し、AnimalBinding および FieldBinding という名前を付けます。
各 ModelingBindingSource の DataSource プロパティを farmBindingSource に設定します。
DataMember プロパティを Animals または Fields に設定します。
AnimalGridView と FieldGridView の DataSource プロパティをそれぞれ AnimalBinding と FieldBinding に設定します。
好みに合わせて、ファーム コントロールのレイアウトを調整します。
ModelingBindingSource は、DSL に固有のいくつかの関数を実行するアダプターです。
VMSDK ストアのトランザクションで更新をラップします。
たとえば、ユーザーがデータ ビュー グリッドから行を削除すると、通常のバインディングではトランザクションの例外が発生します。
ユーザーが行を選択すると、データ グリッド行ではなく、[プロパティ] ウィンドウに、対応するモデル要素のプロパティが表示されます。
データ ソースとビューの間のリンクのスキーマ。
DSL へのバインディングを完了するには
UI プロジェクトの別のコード ファイルに以下のコードを追加します。
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); } } }
DslPackage プロジェクトで、DslPackage\DocView.tt を編集し、次の変数定義を更新します。
string viewControlTypeName = "FarmControl";
DSL のテスト
今後の機能強化が必要な部分もありますが、DSL ソリューションをビルドして実行できるようになりました。
DSL をテストするには
ソリューションをビルドして実行します。
Visual Studio の実験用インスタンスで、Sample ファイルを開きます。
FarmApp エクスプローラーで、[ファーム] ルート ノードのショートカット メニューを開き、[新しい山羊の追加] を選択します。
"山羊 1" は "動物" ビューに表示されます。
注意 [動物] ノードでなく、[ファーム] ノードのショートカット メニューを使用する必要があります。
[ファーム] ルート ノードを選択して、プロパティを表示します。
フォーム ビューで、ファームの [名前] または [サイズ] を変更します。
フォームの各フィールドから移動すると、[プロパティ] ウィンドウ内の対応するプロパティが変更されます。
DSL の拡張
プロパティを直ちに更新するには
FarmControl.cs のデザイン ビューで、Name、Size、IsOrganic などの簡単なフィールドを選択します。
[プロパティ] ウィンドウで DataBindings を展開し、(Advanced) を開きます。
[フォーマットと詳細バインド] ダイアログ ボックスで、[データ ソース更新モード] の下で OnPropertyChanged を選択します。
ソリューションをビルドして実行します。
フィールドの内容を変更すると、ファーム モデルの対応するプロパティがすぐに変化することを確認します。
[追加] ボタンを提供するには
FarmControl.cs のデザイン ビューで、ツールボックスを使用してフォームのボタンを作成します。
ボタンの名前とテキストを、たとえば New Sheep と編集します。
(たとえば、ダブルクリックして) ボタンの分離コードを開きます。
次のように編集します。
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; } }
また、次のディレクティブを挿入する必要があります。
using Microsoft.VisualStudio.Modeling;
ヤギと野原の同様のボタンを追加します。
ソリューションをビルドして実行します。
新しいボタンが項目を追加することを確認します。新しい項目は FarmApp エクスプローラーと適切なデータ グリッド ビューの両方に表示されます。
データ グリッド ビューの要素の名前を編集できるようになります。また、そこから削除することもできます。
要素を追加するコードについて
新しい要素のボタンでは、次の代替コードは若干簡略化されます。
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();
}
}
ただし、このコードでは新しい項目の既定名は設定されません。DSL の要素マージ ディレクティブで定義している可能性があるカスタム マージを実行しません。および、定義されている可能性があるカスタム マージ コードも実行しません。
したがって、新しい要素を作成するには ElementOperations を使用することをお勧めします。詳細については、「要素作成処理および要素移動処理のカスタマイズ」を参照してください。
参照
概念
Visualization and Modeling SDK - ドメイン固有言語