VSTO 任务窗格中 WPF 控件的 Dispatcher 关闭

3
我们有一个WPF控件,它被托管在Word应用程序级别插件中的自定义任务窗格中的Windows用户控件中。
该插件具有一个带有加载和关闭按钮的功能区。加载按钮将加载文档,然后加载自定义任务窗格并将其关联到文档窗口。
插件代码如下:
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;
}

WPF控件的代码如下所示。
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);            
    }
}

当我点击插件中的“加载”按钮时,文档会正确打开,然后屏幕底部的任务窗格会显示一个WPF控件,其中有一个计时器显示时间。
关闭按钮的代码如下。
 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 
            }
         }

现在,当我在事件处理程序执行后单击"Ribbon"中的关闭时,WPF中的"Dispatcher"已经启动关闭并触发了"ShutdownStarted"事件。看起来上面的"VstoDocument.Close"语句导致了调度程序的关闭。当我删除该行时,它不会关闭。
问题在于,同样的代码已经在生产环境中运行了两年,并且在100多个机器(Windows XP)上继续工作,并且在关闭时从未关闭过调度程序。然而,在过去的两天里,这只发生在两台机器上。
如果有人能解释为什么在少数机器上文档关闭时调度程序会关闭,而大多数机器上则不会关闭,我将不胜感激。如果有人知道我是否可以更改插件中托管的WPF控件的调度程序的关闭模式,请告诉我。
1个回答

0

我曾经遇到过类似的问题,就是在 Word 中关闭 WPF 窗口。我只需调用 Dispatcher.InvokeShutdown 方法即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接