1
我正在構建一個Outlook加載項,我想對電子郵件正文中的文本選擇更改做出反應。C#VSTO Outlook加載項 - 調試文本選擇事件?
爲此,我將一個WindowSelectionChange event
附加到郵件項目檢查器中的Word對象。
if (inspector.IsWordMail())
{
wordDoc = inspector.WordEditor as Word.Document;
wordDoc.Application.WindowSelectionChange += new Microsoft.Office.Interop.Word.ApplicationEvents4_WindowSelectionChangeEventHandler(text_selected);
}
這工作正常,但事件停止發射選擇,看似隨意。我一整天都在這裏,並且無法解決問題。
環顧四周後,我發現它可能是wordDoc對象被垃圾收集,所以我確保將它設置爲類變量。
無論如何,也許沒有整個項目,它很難找出問題的確切原因......我的問題是更多的,我將如何去調試這個?如果事件沒有被解僱,我沒有任何斷點。如果我的事件偵聽器不是wordDoc應用程序中的屬性,我該如何監視事件偵聽器的狀態?
下面是來自相關課程的大部分代碼,只是刪除了一些代碼。我很抱歉的混亂 - 我學習,我這個去...
public class InspectorWrapper
{
private Outlook.Inspector inspector;
private CustomTaskPane taskPane;
private Dictionary<string, List<ScanResult>> mailItemEntities;
private bool activated, loaded;
private Word.Document wordDoc;
public InspectorWrapper(Outlook.Inspector Inspector)
{
inspector = Inspector;
loaded = false;
activated = false;
((Outlook.InspectorEvents_Event)inspector).Close +=
new Outlook.InspectorEvents_CloseEventHandler(InspectorWrapper_Close);
taskPane = Globals.ThisAddIn.CustomTaskPanes.Add(
new TaskPaneControl(), "Addin", inspector);
taskPane.VisibleChanged += new EventHandler(TaskPane_VisibleChanged);
mailItemEntities = new Dictionary<string, List<ScanResult>>();
((Outlook.InspectorEvents_10_Event)inspector).Activate += new Outlook.InspectorEvents_10_ActivateEventHandler(ThisAddIn_Activate);
}
void ThisAddIn_Activate()
{
activated = true;
}
void text_selected(Word.Selection selected_text)
{
if (activated && loaded)
{
((TaskPaneControl)this.CustomTaskPane.Control).text_selected(selected_text.Text, selected_text.End - selected_text.Start);
}
}
void TaskPane_VisibleChanged(object sender, EventArgs e)
{
Globals.Ribbons[inspector].Ribbon1.toggleButton1.Checked = taskPane.Visible;
if (!loaded) {
process_email(this.inspector.CurrentItem as Outlook.MailItem);
if (inspector.IsWordMail())
{
wordDoc = inspector.WordEditor as Word.Document;
wordDoc.Application.WindowSelectionChange += new Microsoft.Office.Interop.Word.ApplicationEvents4_WindowSelectionChangeEventHandler(text_selected);
}
loaded = true;
}
}
void InspectorWrapper_Close()
{
if (taskPane != null)
{
Globals.ThisAddIn.CustomTaskPanes.Remove(taskPane);
}
activated = false;
loaded = false;
taskPane = null;
Globals.ThisAddIn.InspectorWrappers.Remove(inspector);
((Outlook.InspectorEvents_Event)inspector).Close -=
new Outlook.InspectorEvents_CloseEventHandler(InspectorWrapper_Close);
((Outlook.InspectorEvents_10_Event)inspector).Activate -=
new Outlook.InspectorEvents_10_ActivateEventHandler(ThisAddIn_Activate);
inspector = null;
}
}
這是我主要的加載項類,如果它的事項:
public partial class ThisAddIn
{
Outlook.Inspectors inspectors;
Outlook.MailItem mailItem;
private string last_id = "";
private Dictionary<Outlook.Inspector, InspectorWrapper> inspectorWrappersValue =
new Dictionary<Outlook.Inspector, InspectorWrapper>();
private Outlook.Inspector ins;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
inspectors = this.Application.Inspectors;
inspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
}
void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
ins = Inspector;
Outlook.MailItem mailItem = ins.CurrentItem as Outlook.MailItem;
if (mailItem != null)
{
inspectorWrappersValue.Add(ins, new InspectorWrapper(ins));
}
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
// Note: Outlook no longer raises this event. If you have code that
// must run when Outlook shuts down, see http://go.microsoft.com/fwlink/?LinkId=506785
inspectors.NewInspector -=
new Outlook.InspectorsEvents_NewInspectorEventHandler(
Inspectors_NewInspector);
inspectors = null;
inspectorWrappersValue = null;
}
public Dictionary<Outlook.Inspector, InspectorWrapper> InspectorWrappers
{
get
{
return inspectorWrappersValue;
}
}
#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
}
似乎已經工作。有一次,我懷疑這是問題的根源,但沒有采取行動。 (「很明顯,如果文檔已打開,應用程序必須打開......不能被收集。」)我想這隻意味着我不理解集合。所以,謝謝 - 但我認爲問題的一部分仍然存在。爲了進行調試,有什麼方法可以更密切地跟蹤聽衆的生活? – Yoni
它不是被收集的內部或GUI對象,而是COM對象。一個COM對象(或多個對象 - 你可以有多個COM對象包裝相同的GUI對象),即使它包裝的對象仍然非常活躍,它們也會被釋放。 –