Author Topic: DocumentBecameCurrent firing more than once, maybe it had too much coffee?  (Read 467 times)

0 Members and 1 Guest are viewing this topic.

Atook

  • Swamp Rat
  • Posts: 928
I'm trying to catch the DocumentBecameCurrent event so I can check when a user switches open drawings and do things like update palettes with drawing info, add command handlers etc.
The problem I'm having is that the eventhandler is firing 3 times every time the active drawing is changed (via tabs). I want it to fire just once, feels like I'm missing something obvious...

Here's the code in my IExtensionApplication:
Code - C#: [Select]
  1. #if BRX_APP
  2. using Teigha.DatabaseServices;
  3. using Teigha.Runtime;
  4. using Bricscad.ApplicationServices;
  5. using Bricscad.Windows;
  6. using _AcadApp = Bricscad.ApplicationServices.Application;
  7. using _Ribbon = Bricscad.Ribbon;
  8. #elif ACAD_APP
  9. using Autodesk.AutoCAD.DatabaseServices;
  10. using Autodesk.AutoCAD.Runtime;
  11. using Autodesk.AutoCAD.ApplicationServices;
  12. using Autodesk.Windows;
  13. using _AcadApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
  14. using _Ribbon = Autodesk.AutoCAD.Ribbon;
  15. #endif
  16.  
  17. public void Initialize()
  18. {
  19.  // does this mean every time a document becomes current we add another EventHandler?
  20.  docManager.DocumentBecameCurrent+=new DocumentCollectionEventHandler(UpdateUI);
  21. }
  22.  
  23. private void UpdateUI(object sender, DocumentCollectionEventArgs documentCollectionEventArgs)
  24. {
  25.  Document doc = _AcadApp.DocumentManager.MdiActiveDocument;
  26.  string name = doc.Database.Filename;
  27.  Debug.WriteLine($"Document Made Active: {name}"); //<---Fires 3 times?
  28.  // Show our palette if our objects are found in the drawing.
  29.  // maybe import needed blocks/styles
  30. }

Jeff_M

  • King Gator
  • Posts: 3940
  • C3D user & customizer
Have you tried the DocumentActivated event instead? Also, at one time we had a problem with the MdiActiveDocument not being correct during the event. So we changed to using the eventArgs.Document property.

That being said, I have no idea if this would work with Bricscad as I've never used or programmed for it.

MickD

  • Gator
  • Posts: 3261
  • !false...it's funny 'cause it's true!
It's not uncommon for events to be fired more than once as events can cause ripple effects that fire the same event again.

You could set an event flag that you set after doing your thing then at the end of the command/routine set the flag to false ready for next event perhaps?
Debugging:
Being the detective in a crime movie where you're also the murderer.

“Someone's sitting in the shade today because someone planted a tree a long time ago.”
- Warren Buffet

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6927
  • AKA Daniel
maybe you can store the doc... something like

Code - C#: [Select]
  1.    public  class Commands : IExtensionApplication
  2.    {
  3.        static private Document m_lastdoc = null;
  4.        static private AcAp.DocumentCollection m_docMan = null;
  5.  
  6.        public void Initialize()
  7.        {
  8.            m_docMan = AcAp.Application.DocumentManager;
  9.            m_docMan.DocumentBecameCurrent += new DocumentCollectionEventHandler(UpdateUI);
  10.            m_lastdoc = m_docMan.MdiActiveDocument;
  11.        }
  12.  
  13.        public void Terminate() { }
  14.  
  15.        private static void UpdateUI(object sender, DocumentCollectionEventArgs documentCollectionEventArgs)
  16.        {
  17.            Document doc = documentCollectionEventArgs.Document;
  18.            if (doc != m_lastdoc)
  19.            {
  20.                m_lastdoc = doc;
  21.                doc.Editor.WriteMessage("\nDocumentBecameCurrent {0}", doc.Name);
  22.            }
  23.        }
  24.    }
  25.  

Atook

  • Swamp Rat
  • Posts: 928
Thanks for the input guys. I've switched to the DocumentActivated event, and it seems to be behaving properly. Interesting note, the DocumentActivated event also appears to fire when an autosave happens, and when it does, the MdiActiveDocument.name is the autosave file (*.sv$)

Jeff, that's an interesting problem you were having with MdiActiveDocument. I haven't noticed this issue, but I have had some recent eNotFromThisDocument errors that might be caused from it.

« Last Edit: January 11, 2019, 10:56:00 PM by Atook »

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
I have used the approach by nullptr in bricscad since v16, seems to behave properly.
James Maeding

Keith Brown

  • Swamp Rat
  • Posts: 596
I do not like the fact that DocumentActivated fires even when the previous document is the same document.  For instance, i believe is you click to another program and then come back the event will fire.  I use the code below to stop that by creating my own event.  Modify to your needs.


Code - C#: [Select]
  1. internal class MyClass
  2. {
  3.   internal void Initialize()
  4.   {
  5.      Kab.Tools.DocumentEvents.DocumentActivated += OnDocumentActivated;
  6.   }
  7.  
  8.  
  9.   private OnDocumentActivated(object sender, DocumentCollectionEventArgs e)
  10.   {
  11.      // DO SOMETHING HERE
  12.   }
  13. }
  14.  
  15.  
  16. namespace Kab.Tools
  17. {
  18.   #if BricsCAD
  19.      using Bricscad.ApplicationServices;
  20.      using cadApp = Bricscad.ApplicationServices.Application;    
  21.   #elif AutoCAD
  22.      using Autodesk.AutoCAD.ApplicationServices;
  23.      using cadApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
  24.   #endif
  25.  
  26.  
  27.   internal static class DocumentEvents
  28.   {
  29.      internal  static event DocumentCollectionEventHandler DocumentActivated;
  30.      private static Document _currentDocument;
  31.  
  32.      static DocumentEvents()
  33.      {
  34.         cadApp.DocumentManager.DocumentActivated += OnDocumentActivated;
  35.      }
  36.  
  37.  
  38.      private static void OnDocumentActivated(object sender, DocumentCollectionEventArgs e)
  39.      {
  40.         if (e.Document != null && _currentDocument != e.Document)
  41.         {
  42.            DocumentActivated?.Invoke(sender, e);
  43.            _currentDocument = e.Document;
  44.         }
  45.      }
  46.   }
  47. }
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013