3
votes

We have a WPF control hosted in a windows User control hosted in Custom Task Pane in Word Application level Addin.

The addin has a ribbon with a load button and close button. The load button will load a document and then load the custom task pane and associate it the documents window.

The addin code looks like this

void Ribbon_LoadJob(object sender, EventArgs e) {
    object missing = Type.Missing;
    Globals.ThisAddIn.Application.Documents.Open("C:\\trash\temp.docx", ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
    VstoDocument = Globals.ThisAddIn.Application.ActiveDocument.GetVstoObject();
    VstoDocument.ActiveWindow.Caption = "Current Window";

    //bottom pane is a task pane
    bottomPane = this.CustomTaskPanes.Add(new TaskControl(), "Status");
    // task control is windows control which will be hosted in task pane
    taskControl = (TaskControl)bottomPane.Control;
    bottomPane.DockPosition = MsoCTPDockPosition.msoCTPDockPositionBottom;
    bottomPane.Visible = true;

    //Call the WPF control code 
    taskControl.Control.Load();
    VstoDocument.BeforeClose -= vstoDocument_BeforeClose;
}

The WPF Control code looks like this

public partial class TaskControl : UserControl
{
    private DispatcherTimer statusTimer;
    private DateTime workStartTime;

    public string StatusMessage
    {
        set
        {
            this.statusMessage.Text = value;
        }
    }

    public TaskControl()
    {
        InitializeComponent();            
        statusTimer = new DispatcherTimer();
        statusTimer.Tick += statusTimer_Tick;
        statusTimer.Interval = TimeSpan.FromSeconds(1D);
        Unloaded += TaskControl_Unloaded;
        Dispatcher.ShutdownStarted += new EventHandler(Dispatcher_ShutdownStarted);
    }

    void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    {
        TheLogger.Debug("Shutting Down");
    }

    public void Load()
    {
        workStartTime = DateTime.UtcNow;

        Dispatcher.CurrentDispatcher.BeginInvoke(new Action(delegate
        {               
            theStats.Content = string.Format("Current Task: [ {0} ]", "Editing");
            StatusMessage = string.Empty;
            statusTimer.Start();
        }
        ));
    }
    void TaskControl_Unloaded(object sender, RoutedEventArgs e)
    {
        Cleanup();
    }
    private void Cleanup()
    {
        statusTimer.Stop();
        statusTimer.Tick -= statusTimer_Tick;
        statusTimer = null;
        this.Unloaded -= TaskControl_Unloaded;
    }
    private void statusTimer_Tick(object sender, EventArgs e)
    {
        TimeSpan elapsed = DateTime.UtcNow - workStartTime;
        elapsedWorkTime.Content = string.Format("{0:00}:{1:00}",
            elapsed.Minutes, elapsed.Seconds);            
    }
}

When I click on the Load button on the addin the document opens up properly and then the task pane at bottom of screen shows wpf control with a timer displaying the time.

Close button code looks like this

 void Ribbon_CloseJob(object sender, EventArgs e)
         {
            object save = true;
            object route = false;
            object format = Word.WdOriginalFormat.wdOriginalDocumentFormat;
            try
            {
                VstoDocument.BeforeClose -= vstoDocument_BeforeClose;
                Globals.ThisAddIn.Application.Caption = "Waiting for user to load again";
                VstoDocument.Close(ref save, ref format, ref route);
                bottomPane.Visible = false;
            }
            catch (Exception e)
            {
               //exception handling 
            }
         }

Now when I click the close in Ribbon after the event handler gets executed the Dispatcher in WPF has started shutdown and fires ShutdownStarted event. Looks like VstoDocument.Close statement above causes the dispatcher to shutdown. When I remove that line it does not shutdown.

The problem here is the same code has been in production for last two years and continues to work on 100+ machines (Windows XP) and it never shutsdown the dispatcher on close. However for the last two days this has been observed only on two machines.

I would appreciate if someone can throw light on why the dispatcher shuts down on document close in few machines and why not on majority machines. I would also appreciate if someone can let me know if I can change the shutdownmode of the dispatcher for hosted WPF control in addin.

1

1 Answers

0
votes

I had similar problem with closing WPF window inside Word. I just called Dispatcher.InvokeShutdown method