Question

OK, mon DSL a bien progressé depuis que j'ai posé la question cette question il y a quelques jours.

Dès que mon code aura été refait, je posterai ma propre réponse à celle-ci, mais pour l'instant, j'ai un autre problème.

Je génère de manière dynamique des sous-diagrammes à partir d'un modèle créé par DSL, en enregistrant ces diagrammes sous forme d'images, puis en générant un document Word avec ces images incorporées. Jusqu'ici, tout va bien.

Mais là où mes formes ont des compartiments (par exemple, Opérations sur un contrat de service - pouvez-vous deviner ce que c'est encore?), l'en-tête du compartiment est affiché mais aucun des éléments .

Si j'examine l'objet de forme, il n'a qu'un seul enfant imbriqué, un ElementListCompartment qui, à son tour, contient un certain nombre d'éléments que je m'attends à afficher. La propriété ElementListCompartment.IsExpanded est définie sur true (et l'en-tête du compartiment comporte une petite icône 'Réduire'), mais où, oh, où sont mes éléments?

La forme a été ajoutée au diagramme à l'aide de

parentShape.FixupChildShapes(modelElement);

Alors, est-ce que quelqu'un peut me guider dans mon chemin joyeux?

Était-ce utile?

La solution

J'ai récemment rencontré un problème connexe et j'ai réussi à le faire fonctionner. Voici donc l'histoire.

La tâche que je mettais en œuvre consistait à charger et à afficher un modèle de domaine et un diagramme associé généré par le package DSL d'ActiveWriter.

Voici comment j'ai implémenté les fonctionnalités requises (toutes les méthodes ci-dessous appartiennent à la classe Form1 que j'ai créée pour jouer):

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

Ce travail a fonctionné avec précision: il a correctement chargé le diagramme à partir de fichiers créés avec Visual Studio, l'a dessiné dans mon formulaire Windows personnalisé, a pris en charge le défilement du canevas et m'a même permis de faire glisser des formes ici. Cependant, une chose me dérangeait: les compartiments étaient vides et portaient un nom par défaut, c’est-à-dire "Compartment".

Google n’a pas aidé du tout, alors j’ai dû creuser seul. Ce n’était pas très facile, mais avec l’aide de Reflector et après quelques heures, j’ai réussi à faire fonctionner ce scénario comme prévu!

Le problème était le suivant. À ma grande surprise, les bibliothèques DSL ne dessinent pas correctement certains éléments de diagramme immédiatement après leur ajout au diagramme. Parfois, seuls les talons de certaines formes sont dessinés (comme il est affiché dans la première image). Ainsi, nous avons parfois besoin de demander manuellement à la bibliothèque de redessiner les formes de diagramme.

Cette fonctionnalité peut être implémentée avec les "règles". qui sont en fait des gestionnaires d’événements déclenchés par certains événements du diagramme. Fondamentalement, nous devons attacher certains gestionnaires à un événement du diagramme ajouté par élément et assurer l'initialisation de la forme.

Heureusement, nous n'avons même pas besoin d'écrire de code puisque le concepteur DSL génère automatiquement les règles de correction et une méthode utilitaire qui attache ces règles au diagramme (voir EnableDiagramRules ci-dessous). Il suffit d’appeler cette méthode immédiatement après la création du magasin (avant de charger le modèle et le diagramme).

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

Le code ci-dessus fonctionne comme suit:

  1. Lors de l'ajout d'un nouvel élément au diagramme (lors de la désérialisation du diagramme, par exemple), la règle "FixUpDiagram" se déclenche.

  2. La règle appelle ensuite Diagram.FixUpDiagram (parentElement, childElement) , où childElement correspond à un élément ajouté et parentElement . représente son parent logique (déterminé à l'aide d'une logique conditionnelle délicate, je n'ai donc pas essayé de le reproduire moi-même).

  3. La trace Fix de la pile dans la méthode FixUpDiagram appelle les méthodes EnsureCompartments de toutes les formes de classe du diagramme.

  4. La méthode EnsureCompartments redessine les compartiments de la classe en retournant le talon "& [;] Compartiment "" graphique en pleine propriété " Propriétés " forme affichée dans l'image liée ci-dessus.

P.S. Steve, j'ai remarqué que vous avez appelé la réparation, mais cela n'a toujours pas fonctionné. Eh bien, je ne suis pas un pro du SDK DSL (je viens juste de l'utiliser depuis quelques jours), donc je ne peux pas expliquer pourquoi vous pourriez avoir des problèmes.

Peut-être avez-vous appelé la réparation avec des arguments erronés. Ou peut-être que Diagram.FixupDiagram (parent, newChild) agit différemment de ce que fait parent.FixupChildShapes (newChild). Cependant voici ma variante qui fonctionne. J'espère que cela aidera aussi.

Autres conseils

Peut-être que ma réponse est un peu trop tardive, mais avez-vous confirmé en utilisant l'explorateur DSL que vos compartiments ont des objets?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top