DSL図に表示されないコンパートメント項目
-
01-07-2019 - |
質問
OK、私が質問して以来、DSL に関してはかなり進歩しました。 この質問 数日前。
コードをリファクタリングしたらすぐに、そのコードに対する自分の答えを投稿するつもりですが、今のところ、別の問題が発生しています。
DSL で作成したモデルからサブ図を動的に生成し、それらの図を画像として保存し、それらの画像が埋め込まれた Word 文書を生成しています。ここまでは順調ですね。
ただし、私の図形にコンパートメントがある場合 (たとえば、サービス コントラクトの操作 - これが何であるかわかりますか?)、コンパートメント ヘッダーは表示されますが、 どの項目もありません.
シェイプ オブジェクトを調べると、ネストされた子が 1 つあり、ElementListCompartment には、表示されると予想される多数の項目が含まれています。ElementListCompartment.IsExpanded プロパティは true に設定されています (コンパートメント ヘッダーには小さな「折りたたみ」アイコンがあります)。しかし、項目はどこにあるのでしょうか?
形状は次を使用して図に追加されました
parentShape.FixupChildShapes(modelElement);
それで、誰か私を楽しい道に導いてくれる?
解決
私は最近、関連する問題に直面しましたが、それをなんとか機能させることができたので、ここにその話をします。
私が実装していたタスクは、ActiveWriter の DSL パッケージによって生成されたドメイン モデルと関連する図をロードして表示することでした。
必要な機能を実装した方法は次のとおりです (以下のすべてのメソッドは、遊ぶために作成した Form1 クラスに属しています)。
private Store LoadStore()
{
var store = new Store();
store.LoadDomainModels(typeof(CoreDesignSurfaceDomainModel), typeof(ActiveWriterDomainModel));
return store;
}
private void LoadDiagram(Store store)
{
using (var tx = store.TransactionManager.BeginTransaction("tx", true))
{
var validator = new ValidationController();
var deserializer = ActiveWriterSerializationHelper.Instance;
deserializer.LoadModelAndDiagram(store,
@"..\..\ActiveWriter1.actiw", @"..\..\ActiveWriter1.actiw.diagram", null, validator);
tx.Commit();
}
}
private DiagramView CreateDiagramView()
{
var store = LoadStore();
LoadDiagram(store);
using (var tx = store.TransactionManager.BeginTransaction("tx2", true))
{
var dir = store.DefaultPartition.ElementDirectory;
var diag = dir.FindElements<ActiveRecordMapping>().SingleOrDefault();
var view = new DiagramView(){Diagram = diag};
diag.Associate(view);
tx.Commit();
view.Dock = DockStyle.Fill;
return view;
}
}
protected override void OnLoad(EventArgs e)
{
var view = CreateDiagramView();
this.Controls.Add(view);
}
これはほとんどうまくいきました:Visual Studio で作成したファイルから図を正しくロードし、カスタム Windows フォーム内に図を描画し、キャンバスのスクロールをサポートし、ここに図形をドラッグすることもできました。ただし、1 つ気になる点がありました。コンパートメントは空で、デフォルトの名前が付けられていました。"区画"。
Google はまったく役に立たなかったので、自分で調べなければなりませんでした。それほど簡単ではありませんでしたが、Reflector の助けを借りて、数時間を費やした後、このシナリオを期待どおりに機能させることができました。
問題は次のようなものでした。驚いたことに、DSL ライブラリは、特定の図要素を図に追加した直後に正しく描画しません。場合によっては、特定の形状のスタブのみが描画されることがあります (最初の図に表示されているように)。したがって、場合によっては、図の形状を再描画するようにライブラリに手動で要求する必要があります。
この機能は、実際には特定のダイアグラム イベントによってトリガーされるイベント ハンドラーである、いわゆる「ルール」を使用して実装できます。基本的にしなければならないことは、図の要素追加イベントに特定のハンドラーをアタッチし、形状の初期化を確実にすることです。
幸いなことに、DSL デザイナーは修正ルールと、それらのルールを図に添付するユーティリティ メソッドの両方を自動生成するため、コードを記述する必要さえありません (以下の EnableDiagramRules を参照)。ストアが作成された直後 (モデルと図をロードする前) にこのメソッドを呼び出すだけです。
private Store LoadStore()
{
var store = new Store();
store.LoadDomainModels(typeof(CoreDesignSurfaceDomainModel), typeof(ActiveWriterDomainModel));
ActiveWriterDomainModel.EnableDiagramRules(store);
return store;
}
/// <summary>
/// Enables rules in this domain model related to diagram fixup for the given store.
/// If diagram data will be loaded into the store, this method should be called first to ensure
/// that the diagram behaves properly.
/// </summary>
public static void EnableDiagramRules(DslModeling::Store store)
{
if(store == null) throw new global::System.ArgumentNullException("store");
DslModeling::RuleManager ruleManager = store.RuleManager;
ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.FixUpDiagram));
ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.ConnectorRolePlayerChanged));
ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemAddRule));
ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemDeleteRule));
ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemRolePlayerChangeRule));
ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemRolePlayerPositionChangeRule));
ruleManager.EnableRule(typeof(global::Altinoren.ActiveWriter.CompartmentItemChangeRule));
}
上記のコードは次のように動作します。
新しい要素が図に追加されると (例:ダイアグラムの逆シリアル化中に) ルール「FixUpDiagram」がトリガーされます。
次に、ルールは呼び出します
Diagram.FixUpDiagram(parentElement, childElement)
, 、 どこchildElement
は追加される要素を表し、parentElement
は論理的な親を表します (扱いにくい条件付きロジックを使用して決定されるため、自分で再現しようとはしませんでした)。スタック トレースの FixUpDiagram メソッド呼び出しを下へ
EnsureCompartments
図内のすべてのクラス シェイプのメソッド。EnsureCompartments メソッドはクラスのコンパートメントを再描画し、上にリンクされている図に示すように、スタブ「[-] コンパートメント」グラフィックを本格的な「プロパティ」形状に変換します。
追伸スティーブ、あなたが修正を呼び出したことに気付きましたが、それでも機能しませんでした。そうですね、私は DSL SDK のプロではないので (数日前に使い始めたばかりです)、なぜ問題が発生するのか説明できません。
おそらく、間違った引数を指定して fixup を呼び出した可能性があります。あるいは、Diagram.FixupDiagram(parent, newChild) は、parent.FixupChildShapes(newChild) が行うこととは異なる動作をする可能性があります。ただし、これが正常に機能する私のバリアントです。これも役立つことを願っています。
他のヒント
私の答えは少し遅すぎるかもしれませんが、DSL Explorerを使用してコンパートメントにアイテムがあることを確認しましたか?