2008-09-19 4 views
0

며칠 전에 this question에 질문 한 이후로 DSL이 상당히 진행되었습니다.DSL 다이어그램에 컴 파트먼트 항목이 표시되지 않습니다.

내 코드를 리팩터링하는 즉시 해당 코드에 대한 내 답변을 게시하겠습니다.하지만 지금은 다른 문제가 있습니다.

DSL로 만든 모델에서 하위 다이어그램을 동적으로 생성하여 해당 다이어그램을 이미지로 저장 한 다음 해당 이미지가 포함 된 Word 문서를 생성합니다. 여태까지는 그런대로 잘됐다.

그러나 내 셰이프에는 구획이 있습니다 (예를 들어 서비스 계약에 대한 작업 - 그것이 무엇인지 알 수 있습니까?) 구획 헤더가 표시되지만 항목이 없습니다.

내 모양 개체를 검사하면 하나의 중첩 된 자식이 있습니다. 즉, ElementListCompartment에는 차례대로 여러 항목이 표시 될 것으로 예상됩니다. ElementListCompartment.IsExpanded 속성이 true로 설정되어 있고 (구획 머리글에 약간의 '붕괴'아이콘이 있음)하지만 내 항목은 어디에 있습니까?

모양

parentShape.FixupChildShapes(modelElement); 

그래서, 누군가가 내 메리가는 길에 저를 인도 할 수 사용하여 다이어그램에 추가되었습니다?

답변

2

저는 최근에 관련된 문제에 직면했으며 제대로 작동하도록 관리했습니다. 그래서 여기에 이야기가 있습니다.

ActiveWriter의 DSL 패키지로 생성 된 도메인 모델과 관련 다이어그램을로드하고 표시하는 작업이 구현되었습니다.

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

이 물건은 대부분 미세 일 : 여기

내가 필요한 기능 (아래의 모든 방법이 놀러 제작 한 Form1 클래스에 속하는)를 구현 한 방법은 올바르게 다이어그램을로드 Visual Studio로 만든 파일에서 내 사용자 지정 Windows 폼 내에서 다이어그램을 그렸고 캔버스를 스크롤 할 수 있도록 지원했으며 여기에 도형을 끌어 올 수도있었습니다. 그러나 한 가지로 저를 괴롭혔습니다. 구획이 비어 있고 기본 이름 (예 : "구획")을 가졌습니다.

Google은 전혀 도움이되지 않아 혼자서 조사해야했습니다. 매우 쉽지는 않았지만 Reflector의 도움을 받아 두 시간을 보낸 후에는 예상대로이 시나리오를 작동시킬 수있었습니다.

문제는 다음과 같습니다. 필자의 놀랍게도 DSL 라이브러리는 특정 다이어그램 요소를 다이어그램에 추가 한 직후 올바르게 그릴 수 없습니다. 때로는 특정 모양의 스텁 만 그려집니다 (첫 번째 그림에 표시됨). 따라서 때때로 라이브러리에 다이어그램 모양을 다시 그리도록 요청해야합니다.

이 기능은 실제로 특정 다이어그램 이벤트에 의해 트리거되는 이벤트 처리기라는 소위 "규칙"으로 구현 될 수 있습니다. 기본적으로 다이어그램의 요소 추가 이벤트에 특정 처리기를 연결하고 모양 초기화를 보장해야합니다.

DSL 디자이너가 픽스 업 규칙과 다이어그램에 이러한 규칙을 첨부하는 유틸리티 메서드를 자동 생성하므로 다행히도 코드를 작성하지 않아도됩니다 (아래의 EnableDiagramRules 참조).저장소를 만든 직후 (모델 및 다이어그램을로드하기 전에)이 메서드를 호출하면됩니다. 새로운 요소시

  1. 다이어그램에 추가되는 규칙 "FixUpDiagram은"트리거 얻는다 (예를 들면 도면의 직렬화시) 다음

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

    코드 위에서 작동한다. 논리적 부모 요소의 childElement 스탠드가 추가되는

  2. 규칙은 다음 Diagram.FixUpDiagram(parentElement, childElement)를 호출하고 parentElement 스탠드 (까다로운 조건 논리를 사용하여 결정, 그래서 나는 나 자신에 의해 그것을 재현하려고하지 않았다).

  3. 아래쪽 픽스 업 픽스 다이어그램 메서드는 다이어그램에서 모든 클래스 셰이프의 EnsureCompartments 메서드를 호출합니다.

  4. EnsureCompartments 메서드는 스텁 "[-] 구획"그래픽을 위의 그림에 표시된대로 본격적인 "속성"모양으로 바꾸는 클래스 구획을 다시 그립니다.

P. 스티브, 당신이 픽스 업에 전화를 걸었지만 여전히 작동하지 않는다는 것을 알았습니다. 글쎄, 나는 DSL SDK의 전문가가 아니기 때문에 (며칠 전에 사용하기 시작했다) 문제가 발생할 수있는 이유를 설명 할 수 없다.

어쩌면 잘못된 인수로 픽스 업을 호출했을 수도 있습니다. 또는 Diagram.FixupDiagram (parent, newChild)은 parent.FixupChildShapes (newChild)가하는 것과는 다른 방식으로 동작합니다. 그러나 여기에는 단지 작동하는 나의 변형이있다. 희망이 또한 도움이됩니다.

+0

크래킹 기여도, 유진! 나는 또 한번 살펴볼 것입니다. –

1

어쩌면 내 대답이 조금 늦었 겠지만 DSL Explorer를 사용하여 구획에 항목이 있는지 확인 했습니까?

관련 문제