-
Notifications
You must be signed in to change notification settings - Fork 301
UI Design Guidelines
Rubberduck's UI can be broken down in two categories:
- Dockable toolwindows
- Modal dialogs
Each have their own set of guidelines.
All dockable toolwindows involve a WinForms control that hosts a WPF UserControl
. The WinForms part must involve a class derived from DockableToolwindowPresenter
. The role of that class is to merely pass down a specific user control to the base constructor - hence, these classes should not contain any application logic:
public class ToDoExplorerDockablePresenter : DockableToolwindowPresenter
{
public ToDoExplorerDockablePresenter(VBE vbe, AddIn addin, IDockableUserControl window)
: base(vbe, addin, window)
{
}
}
The IDockableUserControl
is the WinForms UserControl
host. Its role is to property-inject a ViewModel into the hosted WPF component, and specify a ClassId
and a Caption
. The ClassId
is a GUID that will be registered as a COM component upon installation.
As an example, here's the ToDoExplorerWindow
implementation:
public partial class ToDoExplorerWindow : UserControl, IDockableUserControl
{
private const string ClassId = "8B071EDA-2C9C-4009-9A22-A1958BF98B28";
string IDockableUserControl.ClassId { get { return ClassId; } }
string IDockableUserControl.Caption { get { return RubberduckUI.ToDoExplorer_Caption; } }
public ToDoExplorerWindow()
{
InitializeComponent();
}
private ToDoExplorerViewModel _viewModel;
public ToDoExplorerViewModel ViewModel
{
get { return _viewModel; }
set
{
_viewModel = value;
TodoExplorerControl.DataContext = _viewModel;
if (_viewModel != null)
{
_viewModel.RefreshCommand.Execute(null);
}
}
}
}
- The dockable presenter implementation must be named
[FeatureName]DockablePresenter
.- The WinForms host control must be named
[FeatureName]Window
.- The WPF hosted control must be named
[FeatureName]Control
.- The main window ViewModel class must be named
[FeatureName]ViewModel
.
As of v2.0, toolwindows that involve a grid should use the XAML control GroupingGrid
, under the Rubberduck.UI.Controls.GroupingGrid
namespace.
Except for the Code Explorer (which uses a tree view), all dockable toolwindows should use a grid view.
All toolwindows that require parser state should include a toolbar that contains a "Refresh" button as the left-most control, followed by a separator.
Modal dialogs should be implemented as a WinForms form containing only a single control which is WPF ElementHost. It is not possible to expose dialogs as a WPF windows, so for that reason, they need to be wrapped in a WinForm control. Due to that requirement, the project must implement two-layered approach for managing the UI. The WinForms dialog should use the MVP pattern while the WPF ElementHost
should use the MVVM pattern. Thus, to implement a dialog that is invoked by a menu command, we require those classes:
xxxCommand.cs
== Implements ICommand
interface
xxxDialog.cs
== WinForms dialog itself, the V of the WinForms MVP pattern
xxxView.xaml
== XAML form for WPF, used in the WinForm's ElementHost
and is the V of WPF's MVVM pattern
xxxPresenter.cs
== The (P)resenter for the WinForm's MVP pattern
xxxViewModel.cs
== The ViewModel (VM) for the WPF's MVVM pattern; should contain all of UI logic specific to the feature
xxxModel.cs
== The model containing only data to satisfy M for both WinForm's MVP and WPF's MVVM pattern
WinForms' presenter should be the starting point, created from a factory. The model and other dependencies such as parser state or indenter should be then passed to the factory's Create
method. The presenter should in turn pass in the model to the WPF's MVVM architecture so that it has the data and instantiate the ViewModel for the contained WPF ElementHost
control. Furthermore, the presenter should listen for the dialog's Close event so that it can then return the DialogResult which should be used by the invoking Command
class to decide whether to proceed with the refactoring. The ViewModel should be the one responsible for performing the validation of data in the model and dictating what actions are allowable. Thus, the Winform dialog should be simply a container to the WPF UI and pass through the model and returning the result from the WPF.
Note that most dialogs are typically a refactoring, so we usually implement a xxxRefactoring
class which is then invoked by the xxxCommand
class if it determines to have a valid result from the dialog by calling the Refactor
method.
In order to maintain a similar look & feel across the entire application, here are design guidelines for dialogs:
- Use
ducky.ico
as an icon for all dialogs - Include a 64px
White
banner at the top including aTitleLabel
and anInstructionsLabel
. -
TitleLabel
font should beMicrosoft Sans Serif, 9pt, bold
-
InstructionsLabel
font should beMicrosoft Sans Serif, 8.25pt
. The label should wrap and provide enough space for non-English localizations. - Include a 43px
ControlDark
banner at the bottom including one of two sets of 23px (height) by a minimum of 75px (width) buttons: -
OkButton
andCancelButton
controls for any action that can be cancelled. -
CloseButton
control, for any dialog that is merely displayed, and then closed by the user. - Textboxes that contain user input that requires validation, should include a
[ValidationReason]ValidationIcon
16x16px containing resource imageRubberduck.Properties.Resources.cross_circle
; theOkButton
should be disabled when this icon is visible, and the icon should only be visible when the textbox contains invalid data. - Textboxes should be 20px in height, and should have a label beside them, with enough room to accomodate non-English localizations.
- All controls should have a meaningful name.
rubberduckvba.com
© 2014-2021 Rubberduck project contributors
- Contributing
- Build process
- Version bump
- Architecture Overview
- IoC Container
- Parser State
- The Parsing Process
- How to view parse tree
- UI Design Guidelines
- Strategies for managing COM object lifetime and release
- COM Registration
- Internal Codebase Analysis
- Projects & Workflow
- Adding other Host Applications
- Inspections XML-Doc
-
VBE Events