none
VSTO Document SelectionChange event is not firing RRS feed

  • Question

  •   Hello,

     

    I have a problem with the SelectionChange event from vsto document object.

    I have a Word Addin (application addin) where I have the following code :

     

    public partial class ThisAddIn
      {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
    			this.Application.DocumentOpen += new Word.ApplicationEvents4_DocumentOpenEventHandler(Application_DocumentOpen);
        }
    
    		private Microsoft.Office.Tools.Word.Document _vstoDoc;
    
    		void Application_DocumentOpen(Word.Document Doc)
    		{
    			_vstoDoc = Globals.Factory.GetVstoObject(Doc);
    			_vstoDoc.SelectionChange += new SelectionEventHandler(_vstoDoc_SelectionChange);
    		}
    
    		void _vstoDoc_SelectionChange(object sender, SelectionEventArgs e)
    		{
    			System.Windows.Forms.MessageBox.Show("Selection Fired!");
    		}
    
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }
    
        #region VSTO generated code
    
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
          this.Startup += new System.EventHandler(ThisAddIn_Startup);
          this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        
        #endregion
      }
    

    1. The first document i m opening the selectionchange event is firing properly.

    2. Then i close the document using the Close button in Word. (so the Word Application is still running).

    3. I open another document, selectionchange is not firing anymore...

     

    Any suggestions?

     

    Thanks in advance.

     

    Regards,

     

    Albéric

    Friday, July 16, 2010 7:55 AM

Answers

  • Thanks for the code - that helps explain your scenario, and I can see the problem where customers might cancel closing the document after the BeforeClose or CloseEvent events are raised.

    Can you try removing the SelectionChange event handler during the Microsoft.Office.Tools.Word.Document.Shutdown event instead? This event is raised when the document truly is closing, and this approach seems to work in my testing. I followed up with a developer on the product team, and he also believes this should be the best approach to work around this issue. So, your DocumentControler class might look like the following.

     class DocumentControler
     {
     private Document _vstoDoc;
    
     public DocumentControler(Document vstoDoc)
     {
      _vstoDoc = vstoDoc;
      _vstoDoc.SelectionChange += new SelectionEventHandler(_vstoDoc_SelectionChange);
      _vstoDoc.Shutdown += new EventHandler(_vstoDoc_Shutdown);
     }
    
     void _vstoDoc_SelectionChange(object sender, SelectionEventArgs e)
     {
      System.Windows.Forms.MessageBox.Show("SelectionChange Fired");
     }
    
     void _vstoDoc_Shutdown(object sender, EventArgs e)
     {
      _vstoDoc.SelectionChange -= _vstoDoc_SelectionChange;
     }
     }
    

    To better understand your particular scenario - is it a requirement that you need to generate Microsoft.Office.Tools.Word.Document objects in your add-in, rather than just using Microsoft.Office.Interop.Word.Document objects? In your add-in, you are currently not doing anything with the generated Microsoft.Office.Tools.Word.Document object that you can't do with Microsoft.Office.Interop.Word.Document objects. In other words, could you simply handle the application-level WindowSelectionChange event (and use the Sel.Document property to get the current document whose selection changed) rather than handle the Microsoft.Office.Tools.Word.Document.SelectionChange event? If so, that's another way you could avoid this issue.

    Without going into too much details, it appears that in the mapping that the VSTO runtime is doing between the interop application-level WindowSelectionChange event and the document-level SelectionChange event, there is a corner-case where handling the SelectionChange event of Microsoft.Office.Tools.Word.Document objects created at runtime (using GetVstoObject) can lead to the error condition you're seeing. The VSTO runtime has separate components for .NET Framework 3.5 add-ins and .NET Framework 4 add-ins, so presumably the issue is only in the .NET Framework 4 components in the runtime.


    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Marked as answer by Bessie Zhao Friday, August 6, 2010 9:46 AM
    Thursday, July 29, 2010 6:26 PM
    Answerer

All replies

  • Hello Albéric,

    Sorry for the later reply. As far as I know, you could use DocumentBeforeClose event. Then in this event handler, detach the event handler of SelectionChange. Code like this,

            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                this.Application.DocumentOpen += new Word.ApplicationEvents4_DocumentOpenEventHandler(Application_DocumentOpen);
                this.Application.DocumentBeforeClose += new Word.ApplicationEvents4_DocumentBeforeCloseEventHandler(Application_DocumentBeforeClose);
            }

            void Application_DocumentBeforeClose(Word.Document Doc, ref bool Cancel)
            {
                _vstoDoc.SelectionChange -= new SelectionEventHandler(_vstoDoc_SelectionChange);
                
            } 

    If this post does not help you, please feel free to follow up.

    Best regards,
    Bessie


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Tuesday, July 20, 2010 3:16 PM
  • Hello,

    How this issue is going on in your side? Does this suggestion work for you? If you have any concern for this issue, please feel free to follow up.

    Best regards,
    Bessie


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Friday, July 23, 2010 7:53 AM
  •  

    Hello,

     

    Yesterday i answered the thread, but must have done a mistake. Anyway,

     

    Your suggestion work in this case, but i can't unregister the event on the DocumentBeforeClose because if the user cancel the close (answering cancel when Word ask him if he want to save the document when closing) i m not anymore registered to the event....

     

    I dont understand why the event is not firing if i dont unregister it, my vstoDocument object is getting dispose and i m getting a new one when i m doing the GetVstoObject, i think it is a bug...

     

    The code sample i sent you was a simplify version of my problem. Actually my addin is managing task panes in multiple documents and i m using the removeOrphant method explained here =>http://msdn.microsoft.com/en-us/library/bb264456%28office.12%29.aspx)

    Foreach Document open, i have a customTaskPane opened and a class where i m handling the selectionchange event, when document is closing the customtaskpane is close and i m disposing the class. I can't unregistered the vstoDocument.SelectionChange at this moment because the document is already killed at this moment, so my workaround was to use the Application.WindowSelectionChange instead, and i m unregistering the event on the disposing of my class, when windowSelectionChange is firing i have to check if it is my concerned document that is firing it.

    I noticed that even if i m not unregistering the WindowSelectionChange, it is still firing the second time (it is firing twice wich is normal), it is why i dont understand why the VstoDocument.Selection is not firing even if i havent unregistered before, on the disposing of the vstodocument, the unregistering should be done by itself in my opinion.

    Thanks for your workaround althought i can't apply it in my case, i hope this will get fix one day or maybe it is a feature and i would like somebody explained me why :)

    Best regards,

     

    Albéric

    • Edited by Alberic Monday, July 26, 2010 7:10 AM
    Friday, July 23, 2010 10:00 AM
  • Hello,

      I am having the same problem. Multiple events hooked into the Application and working fine. The SelectionChange on the VSTO Microsoft.Office.Tools.Word.Document works until the document is closed and my classes destroyed. Afterwards there is no issue assigning to a new document a delegate with += operator but no firing occurs (Using Office 2010 / VS 2010).

    Thanks

    Saturday, July 24, 2010 3:44 PM
  • I can reproduce this issue related to the code provided by Alberic in this thread. Interestingly, the issue only appears to occur when your add-in project targets the .NET Framework 4. If it targets the .NET Framework 3.5, the SelectionChange event continues to fire as expected when you close a document and open a different document. I'm opening a bug against the product team to have them investigate this issue, and I'll report back with what I find.
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Monday, July 26, 2010 9:53 PM
    Answerer
  • Ok, thanks a lot!

    you are right, i just tried in framework 3.5, and the event continues to fire. My project was in framework 3.5 earlier, and this bug was report to me few weeks after I migrate to framework 4, but i didnt realized it could be linked, shame on me :)

    I hope this can be solve soon.

     

    Alberic

     

    ps : do i have to check : mark as answer?

    Tuesday, July 27, 2010 7:20 AM
  • Hi Alberic - My contacts on the product team suggested that the proper way to deal with this scenario is to do what Bessie suggested above: to clear the SelectionChange event handler from the Microsoft.Office.Tools.Word.Document object when the corresponding document is closed (for example, during the Microsoft.Office.Interop.Word.Application.DocumentBeforeClose event or the Microsoft.Office.Tools.Word.Document.CloseEvent event). Doing this seems to fix the issue in my tests. Can you clarify why this won't work for your scenario? I'm not quite understanding your following comments, especially since the code examples in http://msdnstage.redmond.corp.microsoft.com/en-us/library/bb264456(office.12).aspx do not explicitly dispose any objects. Could you provide a code example that demonstrates why explicitly removing the SelectionChange event handler won't work in your case

    "Foreach Document open, i have a customTaskPane opened and a class where i m handling the selectionchange event, when document is closing the customtaskpane is close and i m disposing the class. I can't unregistered the vstoDocument.SelectionChange at this moment because the document is already killed at this moment, so my workaround was to use the Application.WindowSelectionChange instead, and i m unregistering the event on the disposing of my class, when windowSelectionChange is firing i have to check if it is my concerned document that is firing it."

    It sounds like the behavior you're seeing is caused by the way the VSTO runtime maps the document-specific Microsoft.Office.Tools.Word.Document.SelectionChange event (which is an event provided by the VSTO runtime) to the underlying application-level Microsoft.Office.Interop.Word.Application.WindowSelectionChange event (which is the "real" event fired by Word). The product team has confirmed that there are potentially some changes they can make to improve your particular scenario, but they are unlikely to do this if it can be avoided by simply removing the SelectionChange event handler for the VSTO document object when the corresponding document is closed.


    This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, July 28, 2010 5:03 PM
    Answerer
  • Hello,

    You can find at this skydrive address a sample project showing you my case (VS2010-VSTO4.0) :

    http://cid-879a624c0f886cbc.office.live.com/browse.aspx/TestChangeSample

    (when you do the test remember that the case is happening when i m closing the document without closing the word application).

    Why i m trying to explain you is that i can't do the unregister on the documentbeforeclose, because the beforeclose event can't guarantee me that the document is going to be really close.

    I tried the sample project in Framework 3.5 and it is working fine. Why does not the framework 4.0 work the same? is it in purpose?

    I still dont understand why i would have to unregistered the event as the document is being closed. (actually i think i understand that it is because the original interop event is on the application (windowselectionchange) and not on the document, i guess it is why it is messing up..., the vstodocument is getting dispose, his events should be unregistered at this moment in my opinion).

    Thanks a lot for the your help,

    Best regards,

    Albéric

    Thursday, July 29, 2010 9:08 AM
  • Thanks for the code - that helps explain your scenario, and I can see the problem where customers might cancel closing the document after the BeforeClose or CloseEvent events are raised.

    Can you try removing the SelectionChange event handler during the Microsoft.Office.Tools.Word.Document.Shutdown event instead? This event is raised when the document truly is closing, and this approach seems to work in my testing. I followed up with a developer on the product team, and he also believes this should be the best approach to work around this issue. So, your DocumentControler class might look like the following.

     class DocumentControler
     {
     private Document _vstoDoc;
    
     public DocumentControler(Document vstoDoc)
     {
      _vstoDoc = vstoDoc;
      _vstoDoc.SelectionChange += new SelectionEventHandler(_vstoDoc_SelectionChange);
      _vstoDoc.Shutdown += new EventHandler(_vstoDoc_Shutdown);
     }
    
     void _vstoDoc_SelectionChange(object sender, SelectionEventArgs e)
     {
      System.Windows.Forms.MessageBox.Show("SelectionChange Fired");
     }
    
     void _vstoDoc_Shutdown(object sender, EventArgs e)
     {
      _vstoDoc.SelectionChange -= _vstoDoc_SelectionChange;
     }
     }
    

    To better understand your particular scenario - is it a requirement that you need to generate Microsoft.Office.Tools.Word.Document objects in your add-in, rather than just using Microsoft.Office.Interop.Word.Document objects? In your add-in, you are currently not doing anything with the generated Microsoft.Office.Tools.Word.Document object that you can't do with Microsoft.Office.Interop.Word.Document objects. In other words, could you simply handle the application-level WindowSelectionChange event (and use the Sel.Document property to get the current document whose selection changed) rather than handle the Microsoft.Office.Tools.Word.Document.SelectionChange event? If so, that's another way you could avoid this issue.

    Without going into too much details, it appears that in the mapping that the VSTO runtime is doing between the interop application-level WindowSelectionChange event and the document-level SelectionChange event, there is a corner-case where handling the SelectionChange event of Microsoft.Office.Tools.Word.Document objects created at runtime (using GetVstoObject) can lead to the error condition you're seeing. The VSTO runtime has separate components for .NET Framework 3.5 add-ins and .NET Framework 4 add-ins, so presumably the issue is only in the .NET Framework 4 components in the runtime.


    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Marked as answer by Bessie Zhao Friday, August 6, 2010 9:46 AM
    Thursday, July 29, 2010 6:26 PM
    Answerer
  • I have found that using the interop Document and Application events gives better feedback on failures than the VSTO document. As suggested above you can simply attach the the Application events and check against a document object reference. Solved the issue for me.
    Monday, August 2, 2010 10:00 AM