Pregunta

Bien, las cosas han progresado significativamente con mi DSL desde que pregunté esta pregunta hace unos días.

Tan pronto como haya refactorizado mi código, publicaré mi propia respuesta, pero por ahora tengo otro problema.

Estoy generando dinámicamente subdiagramas a partir de un modelo creado por DSL, guardando esos diagramas como imágenes y luego generando un documento de Word con esas imágenes incrustadas.Hasta ahora, todo bien.

Pero cuando mis formas tienen compartimentos (por ejemplo, Operaciones en un contrato de servicio, ¿puedes adivinar todavía qué es?), se muestra el encabezado del compartimento, pero ninguno de los artículos.

Si examino mi objeto de forma, tiene un único elemento secundario anidado: un ElementListCompartment que, a su vez, tiene una cantidad de elementos que espero que se muestren.La propiedad ElementListCompartment.IsExpanded está configurada en verdadero (y el encabezado del compartimento tiene un pequeño ícono de "colapso") pero ¿dónde, dónde, están mis artículos?

La forma se agregó al diagrama usando

parentShape.FixupChildShapes(modelElement);

Entonces, ¿alguien puede guiarme en mi alegre camino?

¿Fue útil?

Solución

Recientemente me enfrenté a un problema relacionado y logré hacerlo funcionar, así que aquí está la historia.

La tarea que estaba implementando era cargar y mostrar un modelo de dominio y un diagrama asociado generado por el paquete DSL de ActiveWriter.

Así es como implementé la funcionalidad requerida (todos los métodos siguientes pertenecen a la clase Form1 que creé para jugar):

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

Esto funcionó en su mayoría bien:cargó correctamente el diagrama a partir de archivos creados con Visual Studio, dibujó el diagrama dentro de mi formulario personalizado de Windows, admitió el desplazamiento del lienzo e incluso me permitió arrastrar formas aquí.Sin embargo, una cosa me molestaba: los compartimentos estaban vacíos y tenían un nombre predeterminado, es decir."Compartimiento".

Google no me ayudó en absoluto, así que tuve que buscarlo yo solo.No fue muy fácil, pero con la ayuda de Reflector y después de pasar un par de horas, ¡logré que este escenario funcionara como se esperaba!

El problema fue el siguiente.Para mi sorpresa, las bibliotecas DSL no dibujan correctamente ciertos elementos del diagrama inmediatamente después de agregarlos al diagrama.A veces, sólo se dibujan trozos de determinadas formas (como se muestra en la primera imagen).Por lo tanto, a veces necesitamos pedirle manualmente a la biblioteca que vuelva a dibujar las formas del diagrama.

Esta funcionalidad se puede implementar con las llamadas "reglas" que, de hecho, son controladores de eventos que se activan mediante ciertos eventos del diagrama.Básicamente, lo que tenemos que hacer es adjuntar cierto controlador a un evento de elemento agregado del diagrama y garantizar la inicialización de la forma.

Afortunadamente, ni siquiera tenemos que escribir ningún código, ya que el diseñador DSL genera automáticamente reglas de reparación y un método de utilidad que adjunta esas reglas al diagrama (consulte EnableDiagramRules a continuación).Todo lo que tenemos que hacer es llamar a este método justo después de que se haya creado la tienda (antes de cargar el modelo y el diagrama).

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

El código anterior funciona de la siguiente manera:

  1. Al agregar un nuevo elemento al diagrama (p. ej.durante la deserialización del diagrama) se activa la regla "FixUpDiagram".

  2. La regla entonces llama Diagram.FixUpDiagram(parentElement, childElement), dónde childElement representa un elemento que se agrega y parentElement representa su padre lógico (determinado mediante una complicada lógica condicional, por lo que no intenté reproducirlo yo mismo).

  3. Abajo del seguimiento de la pila llamadas al método FixUpDiagram EnsureCompartments métodos de todas las formas de clase en el diagrama.

  4. El método GuaranteeCompartments vuelve a dibujar los compartimentos de la clase, convirtiendo el gráfico "[-] Compartimento" en una forma completa de "Propiedades", como se muestra en la imagen vinculada arriba.

PDSteve, noté que llamaste a la reparación pero aún así no funcionó.Bueno, no soy un profesional en DSL SDK (recién comencé a usarlo hace un par de días), así que no puedo explicar por qué podrías tener problemas.

Quizás haya llamado a la solución con argumentos incorrectos.O tal vez Diagram.FixupDiagram(parent, newChild) hace algo diferente de lo que hace parent.FixupChildShapes(newChild).Sin embargo, aquí está mi variante que simplemente funciona.Espero que esto también ayude.

Otros consejos

Tal vez mi respuesta sea un poco tarde, pero ¿confirmaste usando DSL Explorer que tus compartimentos tienen artículos?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top