Closed reduckted closed 3 years ago
Should the BaseToolWindow class have a Package property like commands do, so that the implementation can access the package?
Yes, I'd like that so that I can pass the package to the ViewModel when constructing it inside CreateAsync. (Alternatively CreateAsync could have an AsyncPackage parameter instead of the CancellationToken.)
Yes, I'd like that so that I can pass the package to the ViewModel when constructing it inside CreateAsync.
Cool. I've pushed up that change.
I've also tried out having separate base classes for single-instance and multi-instance tool windows. I've prototyped it on a separate branch. Here's the diff with this PR: https://github.com/reduckted/Community.VisualStudio.Toolkit/compare/0f28a6113524ed645c5c32226af121dd8656c8be...reduckted:4094db37bea4c829c4299b01ca51458be4646908
Essentially, the current BaseToolWindow
becomes BaseMultiInstanceToolWindow
and a new BaseToolWindow
class is created that is the same except it drops the toolWindowId
parameters to the abstract methods.
What does everyone think about that?
Personally, I'd prefer overloaded methods to separate base classes. BaseMultiInstanceToolWindow
is a bit too wordy as well.
A tool windows is a tool window whether it allows multiple instances or not.
I agree on having overloaded methods that take the toolWindowId
. That way there is only a single base class for tool windows which keeps the concept count lower and simplifies the API.
To get rid of the analyzer error reporting the toolwindow isn't async, I think there is a great fix for that. The Pane
class' constructor could take a FrameworkElement
and then assign that to the Content
property in the constructor. That way it looks almost identical to the standard tool window implementation and the existing documentation
@yannduran @madskristensen What method are you suggesting is overloaded? There are three methods that take the toolWindowId
. Two of those are abstract, and in the other one the tool window ID is optional.
public static async Task<ToolWindowPane?> ShowAsync(int id = 0, bool create = true);
public abstract string GetTitle(int toolWindowId);
public abstract Task<FrameworkElement> CreateAsync(int toolWindowId, CancellationToken cancellationToken);
@madskristensen The Pane class' constructor could take a
FrameworkElement
and then assign that to theContent
property in the constructor. That way it looks almost identical to the standard tool window implementation and the existing documentation.
I think it would be a better idea to fix the analyzer. Making the consumer do more work that this library could do automatically doesn't sound very user-friendly.
Yeah, you might be right. Is the PR ready to be merged then?
@madskristensen Is the PR ready to be merged then?
Yep, if you're happy with it, then I'm happy with it. 😃
Corresponding PR for the VSSDK Analyzers: https://github.com/microsoft/VSSDK-Analyzers/pull/131
Fixes #20
Overview
This pull request introduces a base class to help with the creation of tool windows. This makes using tool windows similar to commands, and allows all of the setup and creation of the tool window to occur in one file, instead of having some of it implemented in the
AsyncPackage
class.Creating a Tool Window
Define a tool window by inheriting from
BaseToolWindow<T>
, whereT
is the class that inherits fromBaseToolWindows<T>
(similar to commands).Example:
Declare the
Pane
class on the package using theProvideToolWindow
attribute:Initialize the tool window in the
ToolkitPackage.InitializeAsync
method. ℹ️ Note that you must inherit fromToolkitPackage
instead ofAsyncPackage
.And to show the tool window, call the
ShowAsync
method on the tool window class:Known Issues
By implementing tool windows like this, the analyzer warning VSSDK003: Tool windows should support async construction will appear.
Discussion Points
BaseToolWindow
class have aPackage
property like commands do, so that the implementation can access the package?ToolkitPackage
seems like it could become large if we start adding more stuff to it in the future. How does everyone feel about splitting that file into partial files so that all of the tool window related code is in a file calledToolkitPackage.ToolWindows.cs
? This is similar to how the String class is split up in the .NET runtime, as just one example.