TheSwamp

Code Red => .NET => Topic started by: Atook on January 11, 2019, 11:48:02 AM

Title: DocumentBecameCurrent firing more than once, maybe it had too much coffee?
Post by: Atook on January 11, 2019, 11:48:02 AM
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. }
Title: Re: DocumentBecameCurrent firing more than once, maybe it had too much coffee?
Post by: Jeff_M on January 11, 2019, 05:54:03 PM
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.
Title: Re: DocumentBecameCurrent firing more than once, maybe it had too much coffee?
Post by: MickD on January 11, 2019, 07:04:19 PM
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?
Title: Re: DocumentBecameCurrent firing more than once, maybe it had too much coffee?
Post by: It's Alive! on January 11, 2019, 08:17:59 PM
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.  
Title: Re: DocumentBecameCurrent firing more than once, maybe it had too much coffee?
Post by: Atook on January 11, 2019, 10:52:03 PM
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.

Title: Re: DocumentBecameCurrent firing more than once, maybe it had too much coffee?
Post by: jmaeding on January 14, 2019, 04:51:04 PM
I have used the approach by nullptr in bricscad since v16, seems to behave properly.
Title: Re: DocumentBecameCurrent firing more than once, maybe it had too much coffee?
Post by: Keith Brown on January 15, 2019, 02:54:30 PM
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. }