2016-05-20 32 views
0

Ich verwende die AutoConnect-Methode, um Formen programmgesteuert für einen Export von "Aktionen" aus einer Datenbank in meinem Programm zu verbinden. Wenn eine Form sich mit sich selbst verbindet, bombardiert die AutoConnect-Methode. Ich habe mich gefragt, ob jemand Ideen über einen anderen Weg hat, dies zu erreichen.Programmatisches Verbinden einer Form mit sich selbst

private void connectExportedActions(DataTable dt, Page page, Document currentStencil) 
    { 
     List<string> Connectors = new List<string>(); 
     Shape parallelShape; 
     Shape successShape; 
     Shape unsuccessShape; 
     Shape timeoutShape; 
     Master connector; 
     Shape timeout; 
     string timeoutDisplay; 


     foreach (DataRow row in dt.Rows) 
     { 

      Shape shape = page.Shapes.get_ItemFromID((int)row["ShapeID"]); 

      if (row["acdParallelActionDefID"].ToString() != "" && row["acdParallelActionDefID"].ToString() != "NULL") 
      { 
       Connectors.Add("Parallel Connector"); 
      } 
      if (row["acdPositiveActionDefID"].ToString() != "" && row["acdPositiveActionDefID"].ToString() != "NULL") 
      { 
       Connectors.Add("Successful Connector"); 
      } 
      if (row["acdNegativeActionDefID"].ToString() != "" && row["acdNegativeActionDefID"].ToString() != "NULL") 
      { 
       Connectors.Add("Unsuccessful Connector"); 
      } 
      if (row["acdTimeOutActionDefID"].ToString() != "" && row["acdTimeOutActionDefID"].ToString() != "NULL") 
      { 
       Connectors.Add("Timeout Connector"); 

      } 

      foreach (string conn in Connectors) 
      { 

       foreach (Master mst in currentStencil.Masters) 
       { 
        if (mst.Name == conn) 
        { 
         Console.WriteLine(String.Format("Action Name: {0}, ActionDefID: {1}", row["acdName"].ToString(), row["ActionDefID"].ToString())); 
         switch (conn) 
         { 
          case "Parallel Connector": 
           connector = mst; //page.Drop(mst, 0, 0); 
           parallelShape = getShape(dt, row, "ActionDefID", "acdParallelActionDefID", page); 
           **shape.AutoConnect(parallelShape, VisAutoConnectDir.visAutoConnectDirRight, connector);** 
           break; 
          case "Successful Connector": 
           connector = mst; //page.Drop(mst, 0, 0); 
           successShape = getShape(dt, row, "ActionDefID", "acdPositiveActionDefID", page); 
           **shape.AutoConnect(successShape, VisAutoConnectDir.visAutoConnectDirDown, connector);** 
           break; 
          case "Unsuccessful Connector": 
           connector = mst; // page.Drop(mst, 0, 0); 
           unsuccessShape = getShape(dt, row, "ActionDefID", "acdNegativeActionDefID", page); 
           //Console.WriteLine(String.Format("Action Name: {0}, ActionDefID: {1}", row["acdName"].ToString(), row["ActionDefID"].ToString())); 
           **shape.AutoConnect(unsuccessShape, VisAutoConnectDir.visAutoConnectDirLeft, connector);** 
           break; 
          case "Timeout Connector": 
           timeout = page.Drop(mst, 0, 0); 
           timeoutShape = getShape(dt, row, "ActionDefID", "acdTimeOutActionDefID", page); 
           timeoutDisplay = "T = " + row["acdDeadlinePeriod"].ToString() + " days"; 
           timeout.Cells["Prop.Display"].FormulaU = "\"" + timeoutDisplay + "\""; 
           **shape.AutoConnect(timeoutShape, VisAutoConnectDir.visAutoConnectDirLeft, timeout);** 

           timeout.Delete(); 

           break; 
         } 


        } 
       } 
      } 
      Connectors.Clear(); 
     } 
    } 

    private Shape getShape(DataTable dt, DataRow row, string fieldname, string rowcolumn, Page page) 
    { 
     DataRow[] foundRows; 

     foundRows = dt.Select(fieldname + " = " + row[rowcolumn].ToString()); 

     int ShapeID = (int)foundRows[0]["ShapeID"]; 

     Shape shape = page.Shapes.get_ItemFromID(ShapeID); 

     return shape; 
    } 
+1

Das ist eine Menge von Text (und zu verstehen) zu lesen ist und eine Menge Code auch (und verstehen) zu lesen. Kannst du das Ganze eingrenzen? –

+0

Grundsätzlich verwende ich die Autoconnect-Methode, um Shapes miteinander zu verbinden. Wenn ich versuche, eine Form mit sich selbst zu verbinden, bombardiert die Autoconnect-Methode. Gibt es eine Möglichkeit, dies programmgesteuert ohne Verwendung der Autoconnect-Methode zu tun? – user2048126

Antwort

0

Ich arbeitete an etwas ähnlich wie Sie tun. Ich habe verhindert, dass sich Shapes mit sich selbst verbinden, um Endlosschleifen zu vermeiden. Wenn dies jedoch erforderlich ist, sollte die ConnectWithDynamicGlueAndConnector-Methode aus den Visio SDK-Codebeispielen dazu in der Lage sein.

public void ConnectWithDynamicGlueAndConnector(
     Microsoft.Office.Interop.Visio.Shape shapeFrom, 
     Microsoft.Office.Interop.Visio.Shape shapeTo) { 


     if (shapeFrom == null || shapeTo == null) { 
      return; 
     } 


     const string BASIC_FLOWCHART_STENCIL = 
      "Basic Flowchart Shapes (US units).vss"; 
     const string DYNAMIC_CONNECTOR_MASTER = "Dynamic Connector"; 
     const string MESSAGE_NOT_SAME_PAGE = 
      "Both the shapes are not on the same page."; 

     Microsoft.Office.Interop.Visio.Application visioApplication; 
     Microsoft.Office.Interop.Visio.Document stencil; 
     Microsoft.Office.Interop.Visio.Master masterInStencil; 
     Microsoft.Office.Interop.Visio.Shape connector; 
     Microsoft.Office.Interop.Visio.Cell beginX; 
     Microsoft.Office.Interop.Visio.Cell endX; 

     // Get the Application object from the shape. 
     visioApplication = (Microsoft.Office.Interop.Visio.Application) 
      shapeFrom.Application; 

     try { 

      // Verify that the shapes are on the same page. 
      if (shapeFrom.ContainingPage != null && shapeTo.ContainingPage != null && 
       shapeFrom.ContainingPage.Equals(shapeTo.ContainingPage)) { 

       // Access the Basic Flowchart Shapes stencil from the 
       // Documents collection of the application. 
       stencil = visioApplication.Documents.OpenEx(
        BASIC_FLOWCHART_STENCIL, 
        (short)Microsoft.Office.Interop.Visio. 
         VisOpenSaveArgs.visOpenDocked); 

       // Get the dynamic connector master on the stencil by its 
       // universal name. 
       masterInStencil = stencil.Masters.get_ItemU(
        DYNAMIC_CONNECTOR_MASTER); 

       // Drop the dynamic connector on the active page. 
       connector = visioApplication.ActivePage.Drop(
        masterInStencil, 0, 0); 

       // Connect the begin point of the dynamic connector to the 
       // PinX cell of the first 2-D shape. 
       beginX = connector.get_CellsSRC(
        (short)Microsoft.Office.Interop.Visio. 
         VisSectionIndices.visSectionObject, 
        (short)Microsoft.Office.Interop.Visio. 
         VisRowIndices.visRowXForm1D, 
        (short)Microsoft.Office.Interop.Visio. 
         VisCellIndices.vis1DBeginX); 

       beginX.GlueTo(shapeFrom.get_CellsSRC(
        (short)Microsoft.Office.Interop.Visio. 
         VisSectionIndices.visSectionObject, 
        (short)Microsoft.Office.Interop.Visio. 
         VisRowIndices.visRowXFormOut, 
        (short)Microsoft.Office.Interop.Visio. 
         VisCellIndices.visXFormPinX)); 

       // Connect the end point of the dynamic connector to the 
       // PinX cell of the second 2-D shape. 
       endX = connector.get_CellsSRC(
        (short)Microsoft.Office.Interop.Visio. 
         VisSectionIndices.visSectionObject, 
        (short)Microsoft.Office.Interop.Visio. 
         VisRowIndices.visRowXForm1D, 
        (short)Microsoft.Office.Interop.Visio. 
         VisCellIndices.vis1DEndX); 

       endX.GlueTo(shapeTo.get_CellsSRC(
        (short)Microsoft.Office.Interop.Visio. 
         VisSectionIndices.visSectionObject, 
        (short)Microsoft.Office.Interop.Visio. 
         VisRowIndices.visRowXFormOut, 
        (short)Microsoft.Office.Interop.Visio. 
         VisCellIndices.visXFormPinX)); 
      } 
      else { 

       // Processing cannot continue because the shapes are not on 
       // the same page. 
       System.Diagnostics.Debug.WriteLine(MESSAGE_NOT_SAME_PAGE); 
      } 
     } 
     catch (Exception err) { 
      System.Diagnostics.Debug.WriteLine(err.Message); 
      throw; 
     } 
    } 
+0

Das hat mich in die richtige Richtung denken lassen. Vielen Dank! – user2048126

0

AutoConnect erzeugt dynamischen Klebstoff, den Sie sich vorstellen können, wenn Sie ihn an die ganze Form kleben. In diesem Fall möchten Sie stattdessen statischen oder Punkt-zu-Punkt-Kleber erstellen. Wie @bcwhims darauf hinweist, verwenden Sie die GlueTo-Methode des Zellenobjekts.

ich einige Codes hinzufügen, werde ich bereits geschrieben hatte, die über eine alternative Zellnamen-Syntax verwendet:

var shpTarget = vApp.ActivePage.DrawRectangle(1.0, 10.0, 1.5, 9.5); 

    shpTarget.CellsU["FillForegnd"].FormulaU = "THEMEGUARD(RGB(122,201,118))"; 
    shpTarget.CellsU["LineColor"].FormulaU = "THEMEGUARD(RGB(255,255,255))"; 

    shpTarget.AddNamedRow((short)Visio.VisSectionIndices.visSectionConnectionPts, 
          "Top", 
          (short)Visio.VisRowTags.visTagDefault); 
    shpTarget.CellsU["Connections.Top.X"].FormulaU = "Width*0.5"; 
    shpTarget.CellsU["Connections.Top.Y"].FormulaU = "Height"; 

    shpTarget.AddNamedRow((short)Visio.VisSectionIndices.visSectionConnectionPts, 
          "Right", 
          (short)Visio.VisRowTags.visTagDefault); 
    shpTarget.CellsU["Connections.Right.X"].FormulaU = "Width"; 
    shpTarget.CellsU["Connections.Right.Y"].FormulaU = "Height*0.5"; 


    var shpConnector = vApp.ActivePage.Drop(vApp.ConnectorToolDataObject, 1.5, 10.0); 

    var beginCell =shpConnector.CellsU["BeginX"]; 
    var endCell =shpConnector.CellsU["EndX"]; 

    beginCell.GlueTo(shpTarget.CellsU["Connections.Top.X"]); 
    endCell.GlueTo(shpTarget.CellsU["Connections.Right.X"]); 

    shpConnector.CellsU["EndArrow"].FormulaU = "5"; 

Die folgende Formen mit den Anschlüssen Beginn/Ende-Zellen produziert, die erzeugten Klebstoff Formeln zeigen :

enter image description here

+0

Danke, das ist im Grunde das, was ich brauchte, um mich in die richtige Richtung zu bringen. Danke vielmals! – user2048126