Dear all!
My code mirrors a selection by either the x-axis or the y-axis.
It is working fine.
Exept, the drawing shows the result, when I move my cursor to the active dwg.
How can I refresh my drawing, direct after modification of a block?
Any sugestions to a clean solution?
Thank you!
I use the code below to mirror a selected block by a button on a docking pallette:
private void btn_Vertical_Mirror_Click(object sender, EventArgs e) { (new Modifikation()).Mirror("v"); }
the code, which is called is:
public void Mirror(String axis = "") { //--------------------------------------------------------------------------------------------------------------------------------------- Document dwg = Application.DocumentManager.MdiActiveDocument; Database db = dwg.Database; Editor edt = dwg.Editor; //--------------------------------------------------------------------------------------------------------------------------------------- try { Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView(); PromptSelectionResult sel = edt.SelectImplied(); //----------------------------------------------------------------------------------------------------------------------------------- if (sel.Status == PromptStatus.Error) { //Selection filter TypedValue[] tv = new TypedValue[] { new TypedValue( (int)DxfCode.Start, "INSERT") }; SelectionFilter sf = new SelectionFilter(tv); PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "\nSelect block"; sel = edt.GetSelection(pso, sf); if (sel.Status != PromptStatus.OK)// { edt.WriteMessage("\n#ERROR! Selection failed\n"); return; }//if } //----------------------------------------------------------------------------------------------------------------------------------- while (axis == "") { axis = edt.GetString("Axis ('H'orizontaly oder 'V'erticaly)").StringResult.ToUpper(); if (axis.StartsWith("H")) { axis = "h"; } else if (axis.StartsWith("V")) { axis = "v"; } else { axis = ""; } } //----------------------------------------------------------------------------------------------------------------------------------- using (Transaction tr = db.TransactionManager.StartTransaction()) { using (DocumentLock lk = dwg.LockDocument()) { for (int i = 0; i < sel.Value.Count; i++) { if (sel.Value[i].ObjectId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(BlockReference))))// Blöcke werden der Auswahl entnommen { BlockReference blk_ref = (BlockReference)tr.GetObject(sel.Value[i].ObjectId, OpenMode.ForWrite); //------------------------------------------------------------------------------------------------------------------- if (axis == "h") { Matrix3d spgl = Matrix3d.Mirroring( new Line3d( blk_ref.Position, new Point3d( blk_ref.Position.X + 1, blk_ref.Position.Y, 0))); blk_ref.TransformBy(spgl); } //------------------------------------------------------------------------------------------------------------------- else if (axis == "v") { Matrix3d spgl = Matrix3d.Mirroring( new Line3d( blk_ref.Position, new Point3d( blk_ref.Position.X, blk_ref.Position.Y + 1, 0))); blk_ref.TransformBy(spgl); } //------------------------------------------------------------------------------------------------------------------- }//if }// for }// using DocumentLock tr.Commit(); }// using Transaction edt.WriteMessage("\nOkay\n"); }// try //--------------------------------------------------------------------------------------------------------------------------------------- catch { edt.WriteMessage("\n#Error!\n"); } //--------------------------------------------------------------------------------------------------------------------------------------- finally { edt.WriteMessage("\nDone\n"); } }// public void
Solved! Go to Solution.
Solved by Ajilal.Vijayan. Go to Solution.
try by adding this line at the end of your code
'' Regenerate the drawing edt.Regen()
Calling Regen can be a tad slow for a large drawing. When I've modified a BlockTableRecord, I prefer to iterate through all the BlockReferences for that BlockTableRecord and call RecordGraphicsModified(0 on each one. Something like this:
http://adndevblog.typepad.com/autocad/2012/05/redefining-a-block.html
Its personal choice really - just mentioning this for others who may find this post in the future.
Hi Stephen!
Some kind of loop was also my first idea.
I tryed to refresh my drawing by using the code below.
It's a function, which is called after closing the transaction.
private void RefreshBlocks() { //------------------------- Document dwg = Application.DocumentManager.MdiActiveDocument; Database db = dwg.Database; Editor edt = dwg.Editor; //------------------------- Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView(); PromptSelectionResult sel = edt.SelectImplied(); if (sel.Status == PromptStatus.Error) { sel = edt.SelectAll(); } //------------------------- try { using (Transaction tr = db.TransactionManager.StartTransaction()) { using (DocumentLock lk = dwg.LockDocument()) { for (int i = 0; i < sel.Value.Count; i++)// Loop objects { if (sel.Value[i].ObjectId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(BlockReference))))// proceed only blocks { BlockReference blk_ref = (BlockReference)tr.GetObject(sel.Value[i].ObjectId, OpenMode.ForWrite); blk_ref.RecordGraphicsModified(true); }// if }// for }// using DocumentLock tr.Commit(); }// using Transaction }// try //------------------------- catch { } //------------------------- }
But something is wrong. The changes on the block are not shown, until i set the focus to the drawing.
By calling < regen > everything goes well.
Can you point your finger to the mistake or error of the code?
Thank you!
After playing around I finaly have a (partial) solution.
I insered the following rows to my code:
using (Transaction tr = db.TransactionManager.StartTransaction()) { using (DocumentLock lk = dwg.LockDocument()) { dwg.TransactionManager.EnableGraphicsFlush(true);// new // Code for modification of the block(s) db.TransactionManager.QueueForGraphicsFlush();// new
dwg.TransactionManager.FlushGraphics();// new
}// using DocumentLock
tr.Commit();
}// using Transaction
BUT!! It showes some strainge behaviour:
Rotating of blocks is working fine.
Mirroring of blocks is only working, by selecting the blocks by a < edt.GetSelection(pso, sf) > command.
Using < edt.SelectImplied(); >, the updating of the drawing fails (must be triggered by activating by the operator)
I can overcome this, by using the code below.
But it looks not nice to me.
PromptSelectionResult sel = edt.SelectImplied(); if (sel.Status == PromptStatus.OK) { ObjectId[] sel_tmp = new ObjectId[sel.Value.Count]; for (int i = 0; i < sel.Value.Count; i++) temp_sel[i] = sel.Value[i].ObjectId; edt.SetImpliedSelection(new ObjectId[0]); edt.SetImpliedSelection(sel_tmp); }// if
Can't find what you're looking for? Ask the community or share your knowledge.