Using Jigs from Palettes

Facing a problem when trying to combine Jigs and Palettes, I posted a question on the AutoDesk Discussion Forums.

The problem is as followed: I implemented some code from the TTI blog to create polylines with a Jig. (http://through-the-interface.typepad.com/through_the_interface/2006/11/controlling_int_1.html)

It is basically a Jig prompting the user to set points while a line is drawn to show the possible result. This mimics the PLINE functionality, which should be familiar to all of us :).

When doing this from a command, all is good. The line appears nicely when the user is moving his mouse. However, when doing this from a button on a palette, the line drawn by the Jig is not visible, nor are snaps.

I also noticed that when running from a command, the comboboxes in the toolbars lock up, but this does not happen from the palette.

To get around this, Tony Tanzillo posted a nice solution with the AddCommand method in Autodesk.AutoCAD.Internals.Utils. This would work nicely, but this particular project is aimed at AutoCad 2007, where the AddCommand method is not yet present.

So, how can you get around this problem without AddCommand?

There may be many answers, but here is my implementation:

Say there’s a Palette where we want to display the number of Points or Vertices in the Polyline the user has just drawn with the Jig.

image

To display the number of points, we need to have the Polyline that was drawn. So we need to call a method returning the Polyline that was drawn.

Now, the first button is where the problem is. There, I call the Jig directly from the button, and if you’d run the code at the CCN repository, you’d see that the Jig does not really behave as expected.

So, I needed another way. When the Jig is run from a command, the problem is non existent. Bottom line: run a command from the palette, and make sure that the palette receives the result from the command.

We need a command to be run: so that will be the command from the Through The Interface post: MYPOLY. I changed the code a little bit, so that the promt itself is in a separate class.

This simply looks like this:

   1: [CommandMethod("MYPOLY")] 
   2: public void MyPolyJig() 
   3: { 
   4:     new Prompts().PromptNewPolylineByPoints(); 
   5: } 

Second we need a delegate that we can call from the PromptNewPolylineByPoints method, and we need to invoke that delegate from the prompt:



   1: public static Action<Polyline> ActionOnPromptPolyline;

The code stays the same overall, only difference is at the end:



   1: // Added this code, so that a certain action can be called after prompting for polyline
   2: if (ActionOnPromptPolyline != null)
   3: {
   4:     try
   5:     {
   6:         ActionOnPromptPolyline.Invoke(resultingPolyline);
   7:     }
   8:     catch (Exception)
   9:     {
  10:  
  11:         throw;
  12:     }
  13:     finally
  14:     {
  15:         ActionOnPromptPolyline = null;
  16:     }
  17: }



Only thing left to do is setting an action to do when prompting the polyline, and we do this in the buttons Click Event:



   1: private void promptPolylineViaCommand_Click(object sender, EventArgs e)
   2: {
   3:  
   4:     // SendStringToExecute has asynchronous behaviour, so we cannot inspect the result of the
   5:     // command here.
   6:  
   7:     // Set the actionOnPromptPolyline delegate to the desired action and 
   8:     // in the command the action will be executed.
   9:     Prompts.ActionOnPromptPolyline = OnPromptPolyline;
  10:  
  11:     // call command
  12:     Autodesk.AutoCAD.ApplicationServices.Application.
  13:         DocumentManager.MdiActiveDocument.SendStringToExecute("MYPOLY ", true, false, false);
  14:  
  15: }

And, finally, doing the desired logic on the resulting polyline:



   1: private void OnPromptPolyline(Polyline polyline)
   2: {
   3:     if (polyline == null || !polyline.ObjectId.IsValid)
   4:     {
   5:         numberOfPointsTextbox.Text = "No polyline drawn";
   6:         return;
   7:     }
   8:  
   9:     numberOfPointsTextbox.Text = polyline.NumberOfVertices.ToString();
  10:  
  11: }

That’s it, this nicely solved the problem for me. If you have any other solutions, or a different approach, please share :).


Links for the post:


Posted by Bert Vanpeteghem

1 reacties:

Mark said...

I am quite unsure when showing a form what to use. ACAD e.g. recommends Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog instead of System.Windows.Forms.Form.ShowDialog.
I cannot remember exactly but I got problems with the Autodesk version and since then use the Microsoft version with no problems so far.

Google for acad startuserinteraction
You will find some interesting posts which might be helpful for you.