In my C# interop addin created using VSTO, I subscribe to the Document.BeforeSave event. However, another MS Word addin is active on our client's computer also subscribing to this exact same event.
The third party addin cancels the default Word SaveAsDialog and shows its own custom SaveAsDialog (it is a DMS dialog). Our use-case is that we want to show our own SaveAsDialog and override the behavior from the third party.
The calling order of the Document.BeforeSave event seem arbitrary. Sometimes our subscriber is called first, sometimes the third-party addin is called first.
Is there a way to reliably cancel the third-party call?
Edit:
I have tried the following code:
private void ThisAddIn_Startup(object sender, System.EventArgs e) {
Application.DocumentOpen += Application_DocumentOpen;
}
void Application_DocumentOpen(Word.Document Doc) {
Application.DocumentBeforeSave += Application_DocumentBeforeSave;
var handler = new Word.ApplicationEvents2_DocumentBeforeSaveEventHandler(Application_DocumentBeforeSave);
MulticastDelegate multicastDelegate = handler;
var subscribers = handler.GetInvocationList();
for (int i = 0; i < handler.GetInvocationList().Count(); i++) {
Delegate.RemoveAll(multicastDelegate, subscribers[i]);
}
Application.DocumentBeforeSave += Application_DocumentBeforeSave2;
Application.DocumentBeforeSave += Application_DocumentBeforeSave;
}
void Application_DocumentBeforeSave(Word.Document Doc, ref bool SaveAsUI, ref bool Cancel) {
MessageBox.Show("Save 1");
}
void Application_DocumentBeforeSave2(Word.Document Doc, ref bool SaveAsUI, ref bool Cancel) {
MessageBox.Show("Save 2");
}
This does not give the intended effect of having 2 messageboxes showing "2" then "1" consecutively. Instead, it displays "1", "2", "1".
Edit 2: This code works as intended:
public class HasEvents {
public delegate void WoeiHandler();
public event WoeiHandler Woei;
public void OnWoei() {
Woei();
}
}
public class Program {
static void Main(string[] args) {
HasEvents hasEvents = new HasEvents();
hasEvents.Woei += () => Console.WriteLine("ShortVersion");
hasEvents.Woei += Program_Woei;
hasEvents.OnWoei();
BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
FieldInfo field = hasEvents.GetType().GetField("Woei", bindingFlags);
MulticastDelegate multicastDelegate = (MulticastDelegate)field.GetValue(hasEvents);
Delegate[] subscribers = multicastDelegate.GetInvocationList();
Delegate current = multicastDelegate;
for (int i = 0; i < subscribers.Length; i++) {
current = Delegate.RemoveAll(current, subscribers[i]);
}
Delegate[] newSubscriptions = new Delegate[subscribers.Length + 1];
newSubscriptions[0] = new HasEvents.WoeiHandler(Program_Woei_First);
Array.Copy(subscribers, 0, newSubscriptions, 1, subscribers.Length);
current = Delegate.Combine(newSubscriptions);
field.SetValue(hasEvents, current);
hasEvents.OnWoei();
}
static void Program_Woei() {
Console.WriteLine("Program_Woei");
}
static void Program_Woei_First() {
Console.WriteLine("First!");
}
}