locked
Re-opening a custom editor RRS feed

  • Question

  • I have a WPF-based custom editor (derived from WindowPane) and would like to essentially programmatically close and re-open it in response to a particular internal event within my project system.  I know I could use IVsUIShellOpenDocument to get the window frame, close it, then open it again, but I'm fearful that this would change where the document resides in the document well and perhaps whether it's pinned or not or in a provisional state, etc.  Essentially, I'd like to re-open it sort of "in place", with minimal "jarring" of the UI.  I've tried simply setting the Content property of the WindowPane to a new instance of my WPF UIElement, but that doesn't seem to do anything.

    The behavior I essentially want is the same as the standard editors do when they detect an external file edit -- they reload their UI "in place".

    Thanks in advance for your help here.


    Kirk Fertitta

    Tuesday, February 14, 2017 2:07 PM

All replies

  • Hi Kirk Fertitta ,

    >>  Essentially, I'd like to re-open it sort of "in place", with minimal "jarring" of the UI.  I've tried simply setting the Content property of the WindowPane to a new instance of my WPF UIElement.

    Based on your description, it seems that you could hide the window instead of close, and show the window instead of re-open it.

    Best regards,

    Cole Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 15, 2017 6:32 AM
  • Hi Cole,

    Thank you for taking the time to reply.  I tried what you suggested via the code below, but did not see the WindowPane.Initialize method called again or the WindowPane.Content property even re-queried.  So, I'm not sure what you had envisioned as the interception point for the hosted WPF UIElement to be re-created.  Can you clarify?  Here is the code I used that didn't seem to do anything with regards to re-creating my custom editor:

    IVsUIHierarchy hierarchy;
    uint itemId;
    IVsWindowFrame frame;
    var open = VsShellUtilities.IsDocumentOpen(this, path, VSConstants.LOGVIEWID_Designer, out hierarchy, out itemId, out frame);
    
    var hr = frame.Hide();
    ErrorHandler.ThrowOnFailure(hr);
    
    hr = frame.Show();
    ErrorHandler.ThrowOnFailure(hr);


    Kirk Fertitta

    Wednesday, February 15, 2017 1:39 PM
  • Hi Kirk,

    If all you're looking to do is refresh the existing editor/designer instance because the underlying file was updated, IVsPersistDocData.ReloadDocData might fit the bill. Just a stab in the dark :-).

    Sincerely,


    Ed Dore

    Wednesday, February 15, 2017 9:53 PM
  • Hi Ed,

    Thanks for the reply.  Always good to "see" you here.  I did give ReloadDocData a whirl and it didn't seem to do anything.  However, I'm not actually sure what the proper interception point is on WindowPane-derived class.  Currently, I'm just setting a breakpoint in Initialize and also on the getter for the Content property.  Neither are getting hit after a ReloadDocData.


    Kirk Fertitta

    Thursday, February 16, 2017 12:16 AM
  • Hi Kirk,

    Does your ReloadDocData implementation, do you call anything to tell the UI it needs to update itself due to new data being loaded? That's probably the missing link.

    Sincerely,


    Ed Dore

    Friday, February 17, 2017 4:30 AM
  • Hi Ed,

    I'm actually not implementing ReloadDocData, as my editor factory uses a textbuffer as its docData, via the following pretty standard mechanism:

    var textLinesType = typeof(IVsTextLines);
    var riid = textLinesType.GUID;
    var clsid = typeof(VsTextBufferClass).GUID;
    textBuffer = (IVsTextLines)this.Package.CreateInstance(ref clsid, ref riid, typeof(IVsTextLines));
    
    var text = File.ReadAllText(documentMoniker);
    
    var hr = textBuffer.InitializeContent(text, text.Length);
    ErrorHandler.ThrowOnFailure(hr);
    
    docData = Marshal.GetIUnknownForObject(textBuffer);
    


    Kirk Fertitta

    Friday, February 17, 2017 7:57 PM