October 2014

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  










« Creating a custom PaletteSet class exposing a close event inside AutoCAD using .NET | Main | Flashing messages to the screen from AutoCAD using .NET »

December 27, 2011

Creating a custom PaletteSet class exposing a close event inside AutoCAD using .NET (take 2)

Thanks, once again, to Scott McFarlane for working his magic and finding a simple way to make an approach work that I’d convinced myself wasn’t workable. (He took the implementation in my last post and adjusted it to work via a non-static event – something I had tried to do myself, but had somehow failed… I can probably blame it on post-DevDays fatigue… time for a week off, indeed. :-)

Here’s the adjusted PaletteSet2 implementation, with the event no longer defined as static and the trigger happening via an instance rather than being fired statically:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Windows;

using System;

 

[assembly: CommandClass(typeof(PaletteSet2))]

 

namespace Autodesk.AutoCAD.Windows

{

  public class PaletteSet2 : PaletteSet

  {

    // Hold a static pointer to the palette set being closed

 

    public static PaletteSet2 Current = null;

 

    // Our static event to be fired on close

 

    public event EventHandler PaletteSetClosed;

 

    // In the constructor we add an event handler to check

    // for changes of state (show/hide)

 

    public PaletteSet2(string name) : base(name)

    {

      this.StateChanged +=

        (s, e) =>

        {

          // On hide we fire a command to check the state properly

 

          if (e.NewState == StateEventIndex.Hide)

          {

            // Set the static property to point to our palette

 

            PaletteSet2.Current = this;

 

            // Launch the command quietly

 

            Application.DocumentManager.MdiActiveDocument.

              SendStringToExecute(

                "CHECKPALETTESETCLOSE ", true, true, false

              );

          }

        };

    }

 

    // For some reason we need a default constructor with 0 args

 

    public PaletteSet2()

      : base("")

    {

    }

 

    // Our command implementation

 

    [CommandMethod("CHECKPALETTESETCLOSE", CommandFlags.NoHistory)]

    public static void CheckPaletteSetState()

    {

      // Get the static instance set

 

      PaletteSet2 ps = Current;

 

      // If it's invisible, it has been closed

 

      if (ps != null && !ps.Visible)

      {

        // Set the static instance to null and fire the

        // subscribed event

 

        Current = null;

        if (ps.PaletteSetClosed != null)

        {

          ps.PaletteSetClosed(ps, new EventArgs());

        }

      }

    }

  }

}

Here’s the updated command implementation, which can now support events that are different per PaletteSet2 instance (just as things should be):

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Windows;

 

[assembly: CommandClass(typeof(Test.Commands))]

 

namespace Test

{

  public class Commands

  {

    private static PaletteSet2 _ps1 = null, _ps2 = null;

 

    [CommandMethod("PSTEST")]

    public static void CreatePaletteSet()

    {

      if (_ps1 == null)

      {

        _ps1 = new PaletteSet2("First PaletteSet to Close");

        _ps1.Style =

          PaletteSetStyles.NameEditable |

          PaletteSetStyles.ShowPropertiesMenu |

          PaletteSetStyles.ShowAutoHideButton |

          PaletteSetStyles.ShowCloseButton;

 

        _ps1.MinimumSize = new System.Drawing.Size(300, 300);

 

        _ps1.PaletteSetClosed +=

          (s, e) =>

          {

            PaletteSet2 ps = s as PaletteSet2;

            if (ps != null)

            {

              Application.DocumentManager.MdiActiveDocument.

                Editor.WriteMessage(

                  "\n\"{0}\" closed!", ps.Name

                );

            }

          };

      }

      if (_ps2 == null)

      {

        _ps2 = new PaletteSet2("Second PaletteSet to Close");

        _ps2.Style =

          PaletteSetStyles.NameEditable |

          PaletteSetStyles.ShowPropertiesMenu |

          PaletteSetStyles.ShowAutoHideButton |

          PaletteSetStyles.ShowCloseButton;

 

        _ps2.MinimumSize = new System.Drawing.Size(300, 300);

 

        _ps2.PaletteSetClosed +=

          (s, e) =>

          {

            PaletteSet2 ps = s as PaletteSet2;

            if (ps != null)

            {

              Application.DocumentManager.MdiActiveDocument.

                Editor.WriteMessage(

                  "\n\"{0}\" closed!", ps.Name

                );

            }

          };

      }

 

      _ps1.Visible = true;

      _ps2.Visible = true;

    }

  }

}

 

Otherwise the behaviour is (thankfully) the same as that of the last post, while the implementation is clearly much cleaner. I'm not sure how I managed to not get it working, myself, but am just thankful that Scott's around to point out the obvious when it whooshes past me.

And yes, I did queue this (and the next) post up before heading to the Alps for Christmas, so I’m not really here. Just in case you thought I was actually working. :-)

blog comments powered by Disqus

Feed/Share

10 Random Posts