wpf - VSTO 任务 Pane 中 WPF 控件的 Dispatcher 关闭

标签 wpf multithreading ms-word vsto dispatcher

我们有一个 WPF 控件托管在一个 Windows 用户控件中,该控件托管在 Word 应用程序级插件的自定义任务 Pane 中。

插件有一个带有加载按钮和关闭按钮的功能区。加载按钮将加载文档,然后加载自定义任务 Pane 并将其关联到文档窗口。

插件代码如下所示

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);            
    }
}

当我单击加载项上的“加载”按钮时,文档会正确打开,然后屏幕底部的任务 Pane 显示 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 控件的调度程序的关闭模式,我也将不胜感激。

最佳答案

我在关闭 Word 中的 WPF 窗口时遇到了类似的问题。我刚刚调用了 Dispatcher.InvokeShutdown 方法

关于wpf - VSTO 任务 Pane 中 WPF 控件的 Dispatcher 关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23823204/

相关文章:

c# - 重绘图像 WPF

.net - 没有 Windows Media Player 10+ 的 WPF 中的媒体支持?

c# - 单元格编辑后 DataGrid 刷新

c# - 你如何等待网络流有数据读取?

c - OpenMP 多线程更新同一个数组

multithreading - 在非 GUI 线程中创建 QWidget

vba - 如何在MS-Word中删除不同格式的段落标记

vba - 如何更改非英语单词的字体大小?

asp.net-mvc - Asp .Net 文字自动化

wpf - 如何将 WPF WebBrowser 控件滚动到最后?