Hello Gentlemen,
May be a bit lengthy question. Please bear with me.
I would like to synchronize view in two open drawings in autocad.
If I change view or zoom or scroll mouse center button in one drawing, the second drawing needs to be updated in the same view simultaneously with view changed event in C#
Now, I have lisp code to do the same manually.
What the code does is that,
when I enter command "V" in drawing-1
it will store viewsize and viewctr variable in a text file.
when I enter command "VV" in drawing-2
it will read the viewsize and viewctr variable from the text file and execute in the commandline.
I tried the following code, It is not working. Can you please help me.
This is my C# code
public class SimultaneousViewChange : IExtensionApplication
{
Document doc = Application.DocumentManager.MdiActiveDocument;
public void Initialize()
{
doc.ViewChanged += doc_ViewChanged;
}
public void Terminate()
{
doc.ViewChanged -= doc_ViewChanged;
}
void doc_ViewChanged(object sender, EventArgs e) { doc.SendStringToExecute("V ", true, true, true); foreach (Document document in Application.DocumentManager) { if (document.Name != doc.Name) { //doc.SendStringToExecute("VV ", true, true, true); } } }
}
This is my lisp code.
;;;-------------------------------------------------------------------
;;; Store the current display size in a specified text file
;;;------------------------------------------------------------------- (defun c:V (/ viewsize viewctr file space) (setq viewsize (getvar 'viewsize) viewctr (getvar 'viewctr) space (getvar 'tilemode) ) (setq file (open "C:\\Zoom Spot.txt" "w")) (write-line (rtos space) file) (write-line (rtos viewsize) file) (write-line (rtos (nth 0 viewctr)) file) (write-line (rtos (nth 1 viewctr)) file) (write-line (rtos (nth 2 viewctr)) file) (close file) (command "ucs" "p") );End
;;;------------------------------------------------------- ;;; Apply stored display size from specified text file
;;;------------------------------------------------------- (defun c:VV (/ file counter string viewsize viewctr_X viewctr_Y viewctr_Z viewctr space) (setq file (open "C:\\Zoom Spot.txt" "r") counter 0 ) (while (setq string (read-line file)) (if (= 0 counter) (setq space (atoi string))) (if (= 1 counter) (setq viewsize (atof string))) (if (= 2 counter) (setq viewctr_X (atof string))) (if (= 3 counter) (setq viewctr_Y (atof string))) (if (= 4 counter) (setq viewctr_Z (atof string))) (setq counter (1+ counter)) ) (setq viewctr (list viewctr_X viewctr_Y viewctr_Z)) (if (/= (getvar 'tilemode) space) (if (= (getvar 'tilemode) 1) (setvar "tilemode" 0) (setvar "tilemode" 1) ) )
(command "zoom" "c" viewctr viewsize) );End
Thanks in advance.
One of the great things about stepping up into .NET API over that of LISP, is the ease with which one can work in MDI using Fields, or Properties.
In your LISP example, you'd write to an external file from one drawing, and then from another, if the external file existed, you'd read those formatted values.
In .NET, specifically C#, you'd simply implement a static class, which would implement a static field for each of your needed value types (i.e., int, string, etc.). This way, from the same Namespace, when in one Document and your CommandMethod Method is invoked, these static fields are populated, and then in the second Document these static fields can be consumed from another CommandMethod.
Consider this example, using Zoom() Method found here:
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using acApp = Autodesk.AutoCAD.ApplicationServices.Application; using System; [assembly: CommandClass(typeof(BlackBox.AutoCAD.Sample.FOO))] namespace BlackBox.AutoCAD.Sample { public class FOO { static bool stored; static double viewsize; static Point3d viewctr; [CommandMethod("V")] public void V() { Document doc = acApp.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; try { viewsize = Convert.ToDouble(acApp.GetSystemVariable("VIEWSIZE")); viewctr = (Point3d)acApp.GetSystemVariable("VIEWCTR"); if (!stored) { stored = true; } ed.WriteMessage("\n\"VIEWCTR\" and \"VIEWSIZE\" have been stored. "); } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage("\nException: {0}\n", ex.Message); } } [CommandMethod("VV")] public void VV() { Document doc = acApp.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; try { if (stored) { Zoom(new Point3d(), new Point3d(), viewctr, viewsize); ed.WriteMessage("\nView restored. "); } else { ed.WriteMessage("\n\"VIEWCTR\" and \"VIEWSIZE\" have not been stored, please run \"V\" Command. "); } } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage("\nException: {0}\n", ex.Message); } } } }
"How we think determines what we do, and what we do determines what we get."
Oh! As for sending a command (instead of using .NET API), look here:
http://docs.autodesk.com/ACD/2014/ENU/files/GUID-F4A36181-39FB-4923-A2AF-3333945DB289.htm
... Going from memory (which may be faulty):
doc.SendStringToExecute("._zoom _c " + viewctr.ToString() + " " + viewsize.ToString() + "\n", false, false, true);
"How we think determines what we do, and what we do determines what we get."
Thank you BlockBox for your response & modified code.
The problem what I am facing is,
In the viewchangedevent, in Active document, doc.sendstringtoexecute(.....) is working correctly. No worries.
But in Non-Active document, doc.sendstringtoexecute(.....) is not working and creates error.
what I want is, I will vertically arrange two drawings side by side one Autocad Instance. When I scroll or zoom in drawing-1 (Active document) on the left side, the other drawing-2 (Non-Active document) on the right side should changed its view automatically based on document-1.
Is it possible?
"How we think determines what we do, and what we do determines what we get."
"How we think determines what we do, and what we do determines what we get."
Can't find what you're looking for? Ask the community or share your knowledge.