C# VSTO Visio Addin页面切换事件注册时机问题求助
Fixing Null Reference Exception for Visio Page Switch Detection in VSTO Add-in
Hey Andrew, I’ve run into this exact timing issue with Visio VSTO add-ins before—let’s get this sorted out!
The Root Cause
When your add-in’s ThisAddIn_Startup method runs, Visio might not have any open documents or active windows yet. That’s why accessing Application.ActiveWindow throws a null reference exception—it simply doesn’t exist at that point. We need to adjust how we register our page switch event to account for this timing.
Step-by-Step Solution
Here’s a revised approach that handles both existing windows (if any) at startup and new windows created later:
- Register window creation/activation events first in
ThisAddIn_Startup - Bind the
WindowTurnedToPageevent only when a valid window exists - Optimize the page detection to use the window object passed to the event (more reliable than
ActivePage)
Full Revised Code
private void ThisAddIn_Startup(object sender, System.EventArgs e) { // Register event for when new windows are created Application.WindowAdded += Application_WindowAdded; // Check if there's already an active window at startup (e.g., Visio opened with a document) if (Application.ActiveWindow != null) { BindPageSwitchEvent(Application.ActiveWindow); } } private void Application_WindowAdded(Visio.Window newWindow) { // Bind the page switch event to every new window that's created BindPageSwitchEvent(newWindow); } private void BindPageSwitchEvent(Visio.Window targetWindow) { // Make sure we don't bind the event multiple times to the same window targetWindow.WindowTurnedToPage -= Window_WindowTurnedToPage; targetWindow.WindowTurnedToPage += Window_WindowTurnedToPage; } public void Window_WindowTurnedToPage(Visio.Window window) { // Use the window's Page property directly (more reliable than ActivePage) if (window.Page != null) { Debug.WriteLine($"Window switched to page: {window.Page.Name}"); } else { Debug.WriteLine("Window switched to a view without an active page (e.g., master stencil)"); } } private void ThisAddIn_Shutdown(object sender, System.EventArgs e) { // Clean up event handlers (optional but good practice) Application.WindowAdded -= Application_WindowAdded; if (Application.ActiveWindow != null) { Application.ActiveWindow.WindowTurnedToPage -= Window_WindowTurnedToPage; } }
Key Improvements
- Avoids NPE: We only access windows when we know they exist (either at startup if present, or when
WindowAddedfires) - Handles multiple windows: Every window (including new ones created after startup) will trigger the page switch event
- More reliable page detection: Using
window.Pageinstead ofApplication.ActivePageensures we get the page that’s actually visible in the triggered window, not just the global active page (useful if multiple Visio windows are open) - Prevents duplicate event bindings: We unbind the event before rebinding it in
BindPageSwitchEventto avoid multiple triggers for the same action
Additional Notes
- If you need to handle cases where a document is opened (not just a window created), you can also register the
Application.DocumentOpenedevent and bind the page switch event to its associated window - The shutdown cleanup is optional but helps prevent memory leaks, especially if your add-in is loaded/unloaded multiple times without restarting Visio
内容的提问来源于stack exchange,提问作者Andrew Tyson
相关产品推荐
相关产品推荐

