2014-10-14 2 views
0

좋은 날,블록 삽입 루프 오류

나는 사용자가 클릭하는 지점에서 블록을 몇 레벨을 계산하고 삽입하기위한 AutoCAD를 CSHARP 프로그램을 만들고, 사용자 있도록 while 루프에서이 작업을하고 있어요 계산하고 삽입 할 새 포인트를 계속 선택할 수 있습니다. 사용자가 지정한 첫 번째 지점에서만 완벽하게 작동하지만 다른 지점을 클릭하면 "eInvalidOpenState"라는 오류 메시지가 나타납니다. 프로그램이 취소됩니다. 이 문제에 익숙하고 왜 그런 일이 일어나는가?

문제점이있는 곳에서 프로그램의 일부를 추가 했으므로 프로그램의 내용을 볼 수 있습니다.

* 편집 : 잠금을 추가하고 처분을 제거했지만 while 루프의 원래 오류는 여전히 작동하지 않습니다.

******** : 그것은 사용자가 점을 지정 요청하고 사용자가 수행 할 때 충돌 및 다음과 같은 오류 메시지를 제공하는 동안 전체 프로그램의 두 번째 루프, 주위 올바르게 처음 작동 ****** Exception Text ************* Autodesk.AutoCAD.Runtime.Exception : Autodesk.AutoCAD.DatabaseServices.DBObject.UpgradeOpen()의 eInvalidOpenState Level_Arrow.Program의 에 있습니다. .InsertBLock (문자열 [] args) c : \ Users \ \ Documents \ Visual Studio 2013 \ Projects \ 수준 화살표 \ 수준 화살표 \ myCommands.cs : 줄 94 at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker (MethodInfo mi, Object 커맨드 객체, 부울 bLispFunction) at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter (MethodInfo mi, Object co Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke에서 mmandObject, 부울 bLispFunction) ()

if (drgUnits == "mm") 
{ 
    while (drgUnits == "mm") 
    { 
     using (tr) 
     { 
      PromptPointOptions ptIns = new PromptPointOptions(""); 
      ptIns.Message = "\nSpecify insertion point: "; 
      PromptPointResult ptInsert = ed.GetPoint(ptIns); 

      if (ptInsert.Status == PromptStatus.Cancel) return; 

      double yInsert = ptInsert.Value.Y; 

      Scale3d blkScale = new Scale3d(drgScalemm, drgScalemm, drgScalemm); 
      ObjectId bdId = bt[blkName]; 
      Point3d pt = ptInsert.Value; 

      BlockReference insblkref = new BlockReference(pt, bdId); 
      insblkref.ScaleFactors = blkScale; 
      insblkref.Rotation = 0; 

      btr.UpgradeOpen(); 
      btr.AppendEntity(insblkref); 
      btr.DowngradeOpen(); 
      tr.AddNewlyCreatedDBObject(insblkref, true); 

      if (OrgBtr.HasAttributeDefinitions) 
      { 
       foreach (ObjectId id in OrgBtr) 
       { 
        DBObject obj = tr.GetObject(id, OpenMode.ForRead); 
        AttributeDefinition ad = obj as AttributeDefinition; 

        if (ad != null && !ad.Constant) 
        { 
         AttributeReference ar = new AttributeReference(); 
         ar.SetAttributeFromBlock(ad, insblkref.BlockTransform); 
         ar.Position =ad.Position.TransformBy(insblkref.BlockTransform); 
         if (ad.Justify != AttachmentPoint.BaseLeft) 
         { 
          ar.AlignmentPoint.TransformBy(insblkref.BlockTransform); 
         } 
         if (ar.IsMTextAttribute) 
         { 
          ar.UpdateMTextAttribute(); 
         } 
         ar.TextString = ptDisp.ToString(); 
         ObjectId arId = insblkref.AttributeCollection.AppendAttribute(ar);       
         tr.AddNewlyCreatedDBObject(ar, true); 
         break; 
        } 
       } 
      } 

      tr.Commit(); 
      tr.Dispose(); 
     } 
    } 
} 

답변

0

활성 문서를 업데이트 할 때 잠글 수 있습니다. using 문을 사용하여 처리되는지 확인하십시오. 대부분의 AutoCAD 기능은 이와 같이 작동합니다. VB 구문에서 :

Using lock = Acdoc.lockdocument 
     Using trans = acdoc.TransactionManager.starttransaction 
      <<do your stuff>> 
     end using 
    end using 
1

코드에서 이해하기 (불완전하기 어려운 것 같다 그것의) 그리고 당신의 출처를 언급하지 않았다 예외는 아니지만 빠른 눈으로 보면 처분 한 후에 tr 개체에 액세스 할 가능성이있는 것처럼 보입니다.

using()을 사용할 때 어떤 경우라도 처분하거나 닫을 필요가 없습니다.

+0

tr 처리 된 후에 tr 객체가 액세스 될 가능성이있는 것처럼 보입니다. tr이 사용중인 블록에서 액세스되면 중괄호를 일치 시키십시오. –

+1

그는 또한 그것을 사용하는 블록 안에 버립니다. – Amorphis

+0

업데이트 할 때 활성 문서를 잠 가야합니다. using 문을 사용하여 처리되는지 확인하십시오. 대부분의 AutoCAD 기능은 이와 같이 작동합니다. – Alain