سؤال

حسنًا، لقد تطورت الأمور بشكل ملحوظ مع خدمة DSL الخاصة بي منذ أن طلبت ذلك هذا السؤال منذ بضعة أيام.

بمجرد أن أقوم بإعادة بناء الكود الخاص بي، سأقوم بنشر إجابتي الخاصة على ذلك، ولكن في الوقت الحالي، أواجه مشكلة أخرى.

أقوم بإنشاء مخططات فرعية ديناميكيًا من نموذج تم إنشاؤه بواسطة DSL، وحفظ تلك المخططات كصور ثم إنشاء مستند Word يتضمن تلك الصور المضمنة.حتى الان جيدة جدا.

ولكن عندما تحتوي الأشكال الخاصة بي على مقصورات (على سبيل المثال، العمليات على عقد الخدمة - هل يمكنك تخمين ما هي حتى الآن؟)، يتم عرض رأس المقصورة ولكن لا شيء من العناصر.

إذا قمت بفحص كائن الشكل الخاص بي، فإنه يحتوي على طفل متداخل واحد - ElementListCompartment والذي بدوره يحتوي على عدد من العناصر التي أتوقع عرضها.تم تعيين الخاصية ElementListCompartment.IsExpanded على true (ويحتوي رأس المقصورة على رمز "طي" صغير عليه) ولكن أين العناصر الخاصة بي؟

تمت إضافة الشكل إلى الرسم التخطيطي باستخدام

parentShape.FixupChildShapes(modelElement);

لذا، هل يمكن لأي شخص أن يرشدني في طريقي السعيد؟

هل كانت مفيدة؟

المحلول

لقد واجهت مؤخرًا مشكلة ذات صلة، وتمكنت من حلها، وإليك القصة.

كانت المهمة التي كنت أقوم بتنفيذها هي تحميل وعرض نموذج المجال والرسم التخطيطي المرتبط الذي تم إنشاؤه بواسطة حزمة DSL الخاصة بـ ActiveWriter.

إليك كيفية تنفيذ الوظيفة المطلوبة (جميع الطرق أدناه تنتمي إلى فئة 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، ورسم الرسم التخطيطي داخل نموذج النوافذ المخصص الخاص بي، ودعم التمرير في اللوحة القماشية، بل وسمح لي بسحب الأشكال هنا.ومع ذلك، كان هناك شيء واحد يزعجني - كانت المقصورات فارغة وكان لها اسم افتراضي، أي."حجرة".

لم يساعدني 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));
}

الكود أعلاه يعمل على النحو التالي:

  1. عند إضافة عنصر جديد إلى الرسم التخطيطي (على سبيل المثالأثناء إلغاء تسلسل الرسم التخطيطي) يتم تشغيل القاعدة "FixUpDiagram".

  2. القاعدة تدعو بعد ذلك Diagram.FixUpDiagram(parentElement, childElement), ، أين childElement لتقف على عنصر يتم إضافته و parentElement يرمز إلى أصله المنطقي (تم تحديده باستخدام المنطق الشرطي الصعب، لذلك لم أحاول إعادة إنتاجه بنفسي).

  3. أسفل استدعاءات أسلوب FixUpDiagram لتتبع المكدس EnsureCompartments طرق جميع الأشكال الصفية في الرسم التخطيطي.

  4. تقوم طريقة EnsureCompartments بإعادة رسم مقصورات الفئة وتحول رسم "مقصورة [-]" كعب الروتين إلى شكل "خصائص" كامل كما هو معروض في الصورة المرتبطة أعلاه.

ملاحظة.ستيف، لقد لاحظت أنك قمت بالاتصال بمركز الإصلاح ولكنه ما زال لا يعمل.حسنًا، أنا لست محترفًا في DSL SDK (بدأت استخدامه للتو منذ بضعة أيام)، لذلك لا يمكنني توضيح سبب احتمالية مواجهة مشكلات.

ربما تكون قد اتصلت بالإصلاح باستخدام وسيطات خاطئة.أو ربما يقوم Diagram.FixupDiagram(parent, newChild) بشيء مختلف عما يفعلهparent.FixupChildShapes(newChild).ولكن هذا هو البديل الذي يعمل فقط.نأمل أن يساعد هذا أيضا.

نصائح أخرى

ربما تكون إجابتي متأخرة بعض الشيء، ولكن هل تأكدت باستخدام DSL Explorer من أن مقصوراتك تحتوي على عناصر؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top