2017-07-03 118 views
0

首先,對不起我的英語。在圖形屏幕上居中放置一個DSL形狀

我正在開發一個DSL。在主窗口中,我有兩個面板:形狀列表和圖表本身。點擊列表中的項目時,我想要,將其形狀居中在屏幕(圖表面板)上。

我不想形狀移動到圖的中心。我想滾動圖表來居中形狀。

另一種方式來解釋:當驗證錯誤發生(在底部錯誤列表窗口),並在錯誤點擊時,它集中在屏幕上無效形狀,對不對?這就是我想要的。

起點:

private void symbolsListBox_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    var listBox = sender as ListBox; 
    var symbol = listBox.SelectedItem as Symbol; 
    var compartment = PresentationViewsSubject.GetPresentation(symbol) 
     .FirstOrDefault() as SymbolCompartmentShape; 
    var diagram = docView.CurrentDiagram; 

    //Next step, center the shape 
    //How? God please help me!!! 
} 

形象的例子始終是更好!所以...

這裏是一個例子形象I WANT

[1]

這裏,預期結果的示例圖像

[2]

+0

['DSL'?](https://www.google.com/search?q=dsl&ie=utf-8&oe=utf-8&client=firefox-b) – TaW

+0

DSL圖形,就像Visual Studio中的類圖項目 –

+0

VS社區版afaik沒有這樣的事情。我仍然不知道DSL代表什麼。另外:你的目標是什麼:Winforms,WPF,ASP ..? __Always__正確標記您的問題! – TaW

回答

0

你可以做什麼找到圖中的形狀並選擇它。如有必要,圖表會自動顯示。

下面是我使用的代碼。請注意,這從ModelElement(不是形狀)開始。

valueListAssociation.LocateInDiagram(); 

現在擴展方法:

public static bool LocateInDiagram(this ModelElement element) 
{ 
    // Validation 

    SmartGuard.NotNull(() => element, element); 

    // Get the diagram view 

    DiagramView diagramView = element.GetActiveDiagramView(); 
    if (diagramView != null) 
    { 
     // Select it 

     return diagramView.SelectModelElement(element); 
    } 

    // Default result 

    return false; 
} 

public static DiagramView GetActiveDiagramView(this ModelElement element) 
{ 
    // Validation 

    SmartGuard.NotNull(() => element, element); 

    // Get the shape that corresponds to this model element 

    ShapeElement shapeElement = element.GetShapeElement(); 
    if (shapeElement != null) 
    { 
     // Result 

     return shapeElement.GetActiveDiagramView(); 
    } 

    // Default result 

    return null; 
} 

public static ShapeElement GetShapeElement(this ModelElement element) 
{ 
    // Validation 

    SmartGuard.NotNull(() => element, element); 

    // Get the first shape 
    // If the model element is in a compartment the result will be null 

    ShapeElement shape = element.GetFirstShapeElement(); 
    if (shape == null) 
    { 
     // If the element is in a compartment, try to get the parent model element to select that 

     ModelElement parentElement = element.GetCompartmentElementFirstParentElement(); 
     if (parentElement != null) 
     { 
      shape = parentElement.GetFirstShapeElement(); 
     } 
    } 

    // Result 

    return shape; 
} 

private static ShapeElement GetFirstShapeElement(this ModelElement element) 
{ 
    // Presentation elements 

    LinkedElementCollection<PresentationElement> presentations = PresentationViewsSubject.GetPresentation(element); 
    foreach (PresentationElement presentation in presentations) 
    { 
     ShapeElement shapeElement = presentation as ShapeElement; 
     if (shapeElement != null) 
     { 
      return shapeElement; 
     } 
    } 

    // Default result 

    return null; 
} 

private static ModelElement GetCompartmentElementFirstParentElement(this ModelElement modelElement) 
{ 
    // Get the domain class associated with model element. 

    DomainClassInfo domainClass = modelElement.GetDomainClass(); 
    if (domainClass != null) 
    { 
     // A element is only considered to be in a compartment if it participates in only 1 embedding relationship 
     // This might be wrong for some models 

     if (domainClass.AllEmbeddedByDomainRoles.Count == 1) 
     { 
      DomainRoleInfo roleInfo = domainClass.AllEmbeddedByDomainRoles[0]; 
      if (roleInfo != null) 
      { 
       // Get a collection of all the links to this model element 
       // Since this is in a compartment there should be at least one 
       // There can be only one. 

       ReadOnlyCollection<ElementLink> links = roleInfo.GetElementLinks(modelElement); 
       if (links.Count == 1) 
       { 
        // Get the model element participating in the link that isn't the current one 
        // That will be the parent 
        // Probably there is a better way to achieve the same result 

        foreach (ModelElement linkedElement in links[0].LinkedElements) 
        { 
         if (!modelElement.Equals(linkedElement)) 
         { 
          return linkedElement; 
         } 
        } 
       } 
      } 
     } 
    } 

    // Default result 

    return null; 
} 

public static DiagramView GetActiveDiagramView(this ShapeElement shape) 
{ 
    // Validation 

    SmartGuard.NotNull(() => shape, shape); 

    // Result 

    if (shape.Diagram != null) 
    { 
     return shape.Diagram.ActiveDiagramView; 
    } 

    // Default result 

    return null; 
} 

public static bool SelectModelElement(this DiagramView diagramView, ModelElement modelElement, bool ensureVisible) 
{ 
    // Validation 

    SmartGuard.NotNull(() => diagramView, diagramView); 
    SmartGuard.NotNull(() => modelElement, modelElement); 

    // Get the shape element that corresponds to the model element 

    ShapeElement shapeElement = modelElement.GetPresentation<ShapeElement>(); 
    if (shapeElement != null) 
    { 
     // Make sure the shape element is visible (because connectors can be hidden) 

     if (!shapeElement.IsVisible) 
     { 
      shapeElement.Show(); 
     } 

     // Create a diagram item for this shape element and select it 

     diagramView.SelectDiagramItem(new DiagramItem(shapeElement), ensureVisible); 
     return true; 
    } 

    // If the model element does not have a shape, try to cast it IModelElementCompartmented 

    IModelElementCompartmented compartmentedModelElement = modelElement as IModelElementCompartmented; 
    if (compartmentedModelElement != null) 
    { 
     // Get the parent 

     IModelElementWithCompartments parentModelElement = compartmentedModelElement.ParentModelElement; 
     if (parentModelElement != null) 
     { 
      // Get the compartment that stores the model element 

      ElementListCompartment compartment = parentModelElement.GetCompartment(compartmentedModelElement.CompartmentName); 
      if (compartment == null) 
      { 
       throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.RES_Error_CannotFindCompartment, compartmentedModelElement.CompartmentName)); 
      } 

      // Expand the compartment? 

      if (!compartment.IsExpanded) 
      { 
       using (Transaction trans = modelElement.Store.TransactionManager.BeginTransaction("IsExpanded")) 
       { 
        compartment.IsExpanded = true; 
        trans.Commit(); 
       } 
      } 

      // Find the model element in the compartment 

      int index = compartment.Items.IndexOf(modelElement); 
      if (index >= 0) 
      { 
       // Create a diagram item and select it 

       diagramView.SelectDiagramItem(new DiagramItem(compartment, compartment.ListField, new ListItemSubField(index)), ensureVisible); 

       // Result OK 

       return true; 
      } 
     } 
    } 

    // Default result 

    return false; 
} 

注意,這最後的方法有一個「絕招」,以處理有車廂(IModelElementCompartmented)的形狀。如果你的形狀沒有隔間,你可以省略這部分。