- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
When grip editing a polyline, hovering over a grip shows this context menu:
When the user moves the cursor anywhere but over the menu, the menu is removed and the cursor remains visible at all times. In my GripOverrule, adding a ContextMenu to MyGrip works the same, except the menu stays unless the user clicks elsewhere, and the cursor is not visible unless the user manages to pass over the menu. What must I do to get the same functionality as the polyline grip menu?
Here is a small example which adds a single grip to the endpoint of lines. The OnHover() adds a single menu item to set the line's layer to "0". None of the ContextMenuStrip's properties/events that control the display or focus, other than Show() & Hide(), work.
using System; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.GraphicsInterface; using Autodesk.AutoCAD.Runtime; namespace Test_Commands.GripTest { public class GripTest { private static bool ShouldBeOn = false; [CommandMethod("GripTestToggle")] public void griptestCommand() { if (ShouldBeOn) { ShouldBeOn = false; RemoveOverrule(); } else { ShouldBeOn = true; AddOverrule(); } } // Added for grips for line public static TestGripsOverrule mGripOverrule; public static void AddOverrule() { if (ShouldBeOn) { // Instantiate our global Overrule and set it to overrule lines with my data attached mGripOverrule = new TestGripsOverrule(); Overrule.AddOverrule(RXObject.GetClass(typeof(Line)), mGripOverrule, false); //Turn overruling on Overrule.Overruling = true; } } public static void RemoveOverrule() { if (!ShouldBeOn) { Overrule.RemoveOverrule(RXObject.GetClass(typeof(Line)), mGripOverrule); mGripOverrule = null; } } } //Grip overrule to add our custom grips to the line public class TestGripsOverrule : GripOverrule { public static short gripcolor { get; set; } public static System.Windows.Forms.ContextMenuStrip mnu; //Our custom grip class //(Could have derived one class for each grip, but we'll use member data (Ordinal property) to distinguish grips instead) public class MyGrip : GripData { private int mGripNum; public int Ordinal { get { return mGripNum; } set { mGripNum = value; } } public override bool ViewportDraw(ViewportDraw worldDraw, ObjectId entityId, DrawType type, Point3d? imageGripPoint, int gripSizeInPixels) { Point2d unit = worldDraw.Viewport.GetNumPixelsInUnitSquare(GripPoint); var gripPolygonPts = new Point3dCollection(); double lengthVal = 1.20 * gripSizeInPixels / unit.X; gripPolygonPts.Add(new Point3d(GripPoint.X, GripPoint.Y + lengthVal, 0)); gripPolygonPts.Add(new Point3d(GripPoint.X + lengthVal, GripPoint.Y, 0)); gripPolygonPts.Add(new Point3d(GripPoint.X, GripPoint.Y - lengthVal, 0)); gripPolygonPts.Add(new Point3d(GripPoint.X - lengthVal, GripPoint.Y, 0)); // Polygon properties worldDraw.SubEntityTraits.Color = gripcolor; worldDraw.SubEntityTraits.FillType = FillType.FillAlways; worldDraw.Geometry.Polygon(gripPolygonPts); return true; } private ObjectId entId; public override ReturnValue OnHover(ObjectId entityId, Context contextFlags) { if(mnu==null) { mnu = new System.Windows.Forms.ContextMenuStrip(); mnu.Items.Add("Set Layer 0"); } entId = entityId; Document doc = Application.DocumentManager.MdiActiveDocument; System.Windows.Point pos = doc.Editor.PointToScreen(GripPoint, Convert.ToInt16(Application.GetSystemVariable("CVPORT"))); pos.Offset(doc.Window.DeviceIndependentLocation.X + 15, doc.Window.DeviceIndependentLocation.Y + 38); mnu.Show(new System.Drawing.Point(Convert.ToInt32(pos.X), Convert.ToInt32(pos.Y))); mnu.ItemClicked += mnu_ItemClicked; return base.OnHover(entityId, contextFlags); } void mnu_ItemClicked(object sender, System.Windows.Forms.ToolStripItemClickedEventArgs e) { mnu.Hide(); Document doc = Application.DocumentManager.MdiActiveDocument; using (DocumentLock doclock = doc.LockDocument()) { Line line = (Line)entId.Open(OpenMode.ForWrite); line.Layer = "0"; line.Close(); } mnu.ItemClicked -= mnu_ItemClicked; } } //Array to hold our grip public GripData[] mGripData = new GripData[1]; public override void GetGripPoints(Autodesk.AutoCAD.DatabaseServices.Entity entity, Autodesk.AutoCAD.DatabaseServices.GripDataCollection grips, double curViewUnitSize, int gripSize, Autodesk.AutoCAD.Geometry.Vector3d curViewDir, Autodesk.AutoCAD.DatabaseServices.GetGripPointsFlags bitFlags) { //We assume entity is a line Line line = entity as Line; if (line == null) return; gripcolor = (short)Application.GetSystemVariable("GRIPHOT"); // Set point at end of line MyGrip grip = new MyGrip(); grip.Ordinal = 0; mGripData[0] = grip; UpdateGripLocations(line); //Add our grips to the list foreach (MyGrip g in mGripData) { grips.Add(g); } //Get the standard line grip points as well, but not wanted for this test //base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags); } public override void MoveGripPointsAt(Autodesk.AutoCAD.DatabaseServices.Entity entity, GripDataCollection grips, Vector3d offset, MoveGripPointsFlags bitFlags) { //We only take action when we get this call on a database resident entity //Dragging operation makes shallow clone of line, and setting clomeMeForDragging to false is generally a bad idea. //(If you do set clone me for dragging to false, then don't call base class overriden methods). try { if (entity.Id.IsValid) { var line = entity as Line; //Iterate through list of all grips being moved foreach (GripData g in grips) { if (g is MyGrip) { MyGrip grip = g as MyGrip; //Cast to our grip type double newX = g.GripPoint.X + offset.X; double newY = g.GripPoint.Y + offset.Y; switch (grip.Ordinal) { case 0: line.EndPoint = new Point3d(newX, newY, line.EndPoint.Z); break; default: break; } //Tell grip to move itself long the line UpdateGripLocations(line); } } } } catch (System.Exception) { } } private void UpdateGripLocations(Line line) { Point3d pt = new Point3d(line.EndPoint.X, line.EndPoint.Y, 0); mGripData[0].GripPoint = pt; } } }
Solved! Go to Solution.