VsixCommunity / Community.VisualStudio.Toolkit

Making it easier to write Visual Studio extensions
Other
256 stars 44 forks source link

Get a WindowFrame wrapper for a tool window #437

Closed reduckted closed 1 month ago

reduckted commented 1 year ago

This change allows a ToolkitToolWindowPane to get the underlying WindowFrame for the tool window. This is useful if you need to listen to events on the window frame to, for example, know when the tool window focused or closed.

yannduran commented 1 year ago

Hi Dave,

This caught my eye because I'm looking for a way to "redraw" my toolwindow when a setting that affects the structure of the contents is saved. But unfortunately I don't see anything in IVsWindowFrame that will help with that.

Do you know of any way to force a toolwindow to be redrawn?

This is what I've tried:

In my toolwindow called MainWindow, I added this property:

   public class MainWindow : BaseToolWindow<MainWindow>
   {
       public static MainView View { get; private set; }

       // the rest of the code here
   }

Then I modified CreateAync to create an instance of MainWindow which I then save in the property before returning it:

       public override Task<FrameworkElement> CreateAsync(int toolWindowId, CancellationToken cancellationToken)
       {
           View = new MainView();

           return Task.FromResult<FrameworkElement>(View);
       }

Later in the Saved method of a BaseOptionModel I have this code:

          try
          {
              MainWindow.View.InvalidateVisual();
          }
          catch (Exception ex)
          {
              _dialogService.ShowException(ex);
          }

But nothings happens :-( Any pointers you might have would be much appreciated. The solution may also be a good candidate to add to the toolkit.

The it could be as simple as:

          try
          {
              MainWindow.Refresh(); // or .Redraw() etc
          }
          catch (Exception ex)
          {
              _dialogService.ShowException(ex);
          }
reduckted commented 1 year ago

🤔 Hmm, the content of a tool window is just a WPF control, so it should redraw in the usual way that a normal WPF window would redraw (i.e. the tool window host shouldn't be doing anything to prevent redrawing). If you're using data binding, it might be that the INotifyPropertyChanged events are not being raised on whatever object MainView.DataContext is.

yannduran commented 1 year ago

OK, thanks Dave. I'll look into that.

The datacontext is just a viewmodel class. But I think I might be trying to redraw the wrong object. I'm calling InvalidateVisual on the MainWindow class which inherits BaseToolWindow<MainWindow>. Perhaps I need to be calling it on the UserControl itself instead.