Application Patterns for Visual Studio

Note

This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

Window interactions

Overview

The two main window types used in Visual Studio are document editors and tool windows. Rare, but possible, are large modeless dialogs. Although these are all modeless in the shell, their patterns are fundamentally different. This topic covers the difference between document windows, tool windows, and modeless dialogs. Modal dialog patterns are covered in Dialogs.

Comparing window usage patterns

Document windows are almost always displayed within the document well. This gives the document editor a “center stage” to arrange supplemental tool windows around.

A tool window is most often displayed as a separate, smaller window – which can be visible, hidden, or auto-hidden – collapsed against the edge of the IDE. However, sometimes they are presented within the document well, by unchecking the Window/Docking property on the window. This results in more real estate, but also a common design decision: when attempting to integrate into Visual Studio, you must decide whether your feature should display a tool window or a document window.

Modeless dialogs are not encouraged in Visual Studio. To a large extent, they are – by definition – floating tool windows and should be implemented as such. Modeless dialogs are allowed in cases where the size of a normal tool window docked to the side of the shell would be too limiting. They are also allowed in cases where the user would be likely to move the dialog to a secondary monitor.

Think carefully about which container type you need. Common usage pattern considerations for UI design are in the following table.

Document window Tool window Modeless dialog
Position Always positioned within the document well and does not dock around the edges of the IDE. It can be “pulled off” so that it floats separately from the main shell. Generally tab-docked around the edges of the IDE, but can be customized to be floating, auto-hidden (unpinned), or docked within the document well. Large floating window separate from the IDE.
Commit model Delayed commit

In order to save the data in a document, the user must issue the File/Save, Save As, or Save All command. A document window has the concept of the data within it being "dirtied" then committed to one of the save commands. When closing a document window, all contents are either saved to disk or lost.
Immediate commit

There is no save model. For inspector tool windows that assist in editing a file, the file must be open in the active editor or designer, and the editor or designer owns the save.
Delayed or immediate commit

Most often, a large modeless dialog requires an action to commit changes and allows for a “Cancel” operation, which rolls back any changes made within the dialog session. This differentiates a modeless dialog from a tool window in that tool windows always have an immediate commit model.
Visibility Open/Create (file) and Close

Opening a document windows is done through either opening an existing document or using a template to create a new document. There is no “Open <specific editor>” command.
Hide and show

Single-instance tool windows can be hidden or shown. Contents and states within the tool window persist whether in view or hidden. Multi-instance tool windows can be closed as well as hidden. When a multi-instance tool window is closed, the content and state within the tool window is discarded.
Launched from a command

Dialogs are launched from a task-based command.
Instances Multi-instance

Several editors can be open at the same time and editing different files, while some editors also allow the same file to be open in more than one editor (using the Window > New Window command).

A single editor may be editing one or multiple files at the same time (Project Designer).
Single- or multi-instance

Contents change to reflect context (as in the Property Browser) or push focus/context to other windows (Task List, Solution Explorer).

Both single-instance and multi-instance tool windows should be associated with the active document window unless there is a compelling reason not to.
Single-instance
Examples Text editors, such as the code editor

Design surfaces, such as a form designer or a modeling surface

Control layouts similar to dialogs, such as the Manifest Designer
The Solution Explorer provides a solution and projects contained within the solution

The Server Explorer provides a hierarchical view of servers and data connections that the user chooses to open in the window. Opening an object from the database hierarchy, such as a query, opens a document window and allows the user to edit the query.

The Property Browser displays properties for the object selected either in a document window or another tool window. The properties are presented either in a hierarchical grid view or in complex dialog-like controls and allow the user to set the values for those properties.

Tool windows

Overview

Tool windows support the user's work that happens in document windows. They can be used to display a hierarchy that represents a fundamental root object that Visual Studio provides and can manipulate.

When considering a new tool window in the IDE, authors should:

  • Use task-appropriate existing tool windows and not create new ones with similar functionality. New tool windows should only be created if they offer a significantly different “tool” or functionality that cannot be integrated into a similar window, or by turning an existing window into a pivoting hub.

  • Use a standard command bar, if needed, at the top of the tool window.

  • Be consistent with patterns already present in other tool windows for control presentation and keyboard navigation.

  • Be consistent with control presentation in other tool windows.

  • Document-specific tool windows should be auto-visible when possible so that they appear only when the parent document is activated.

  • Ensure their window content is navigable by the keyboard (support arrow keys).

Tool window states

Visual Studio tool windows have different states, some of which are user-activated (like the auto-hide feature). Other states, such as auto-visible, allow tool windows to appear in the correct context and hide when not needed. There are five tool window states in total.

  • Docked/pinned tool windows can be attached to any of the four sides of the document area. The pushpin icon appears in the tool window title bar. The tool window can be docked horizontally or vertically along the edge of the shell and other tool windows, and can also be tab-linked.

  • Auto-hidden tool windows are unpinned. The window can slide out of sight, leaving a tab (with the name of tool window and its icon) on the edge of the document area. The tool window slides out when a user hovers over the tab.

  • Auto-visible tool windows automatically appear when another piece of UI, such as an editor, is launched or gains focus.

  • Floating tool windows hover outside the IDE. This is useful for multi-monitor configurations.

  • Tabbed document tool windows can be docked within the document well. This is useful for large tool windows, such as the Object Browser, that need more real estate than docking to the edges of the frame allows.

    Tool window states in Visual Studio

    Tool window states in Visual Studio

Single-instance and multi-instance

Tool windows are either single-instance or multi-instance. Some single-instance tool windows might be associated with the active document window, while multi-instance tool windows might not. Multi-instance tool windows respond to the Window/New Window command by creating a new instance of the window. The following image illustrates a tool window enabling the New Window command when an instance of the window is active:

Tool window enabling commands in Visual Studio

Tool window enabling ‘New Window’ command when an instance of the window is active

Single-instance tool windows can be hidden or shown, while multi-instance tool windows can be closed as well as hidden. All tool windows can be docked, tab-linked, floating, or set as a Multiple-Document Interface (MDI) child window (similar to a document window). All tool windows should respond to the appropriate window management commands in the Window menu:

Window management commands in Visual Studio

Window management commands in the Visual Studio Window menu

Document-specific tool windows

Some tool windows are designed to change based on a given type of document. These windows continually update to reflect functionality applicable to the active document window in the IDE.

Examples of tool windows whose contents change to reflect the selected editor are the Toolbox and the Document Outline. These windows show a watermark when an editor has focus that does not offer context to the window.

Some tool windows display a list of navigable items the user can interact with. In this type of window, there should always be feedback for the current item in the list, even if the window is inactive. The list should respond to the GoToNextLocation and GoToPrevLocation commands by also changing the currently selected item in the window

Examples of navigable list tool windows are the Solution Explorer and the Find Results window.

Tool window types

Common tool windows and their functions

Type Tool window Function
Hierarchy Solution Explorer A hierarchical tree that displays a list of documents contained in projects, miscellaneous files, and solution items. The display of the items within projects is defined by the package that owns the project type (for example, reference-based, directory-based, or mixed-mode types).
Hierarchy Class View A hierarchical tree of the classes and various elements in the working set of documents, independent of the files themselves.
Hierarchy Server Explorer A hierarchical tree that displays all the servers and data connections in the solution.
Hierarchy Document Outline The hierarchical structure of the active document.
Grid Properties A grid that displays a list of properties for the selected object, along with value pickers to edit those properties.
Grid Task List A grid that allows the user to create/edit/delete tasks and comments.
Content Help A window that allows users access to various methods of getting help, from “How Do I?” videos to MSDN forums.
Content Dynamic Help A tool window that displays links to help topics applicable to the current selection.
Content Object Browser A two-column frameset with a list of hierarchical object components in the left pane and the object's properties and methods in the right column.
Dialog Find, Advanced Find A dialog that allows the user to find or find and replace in various files within the solution.
Other Toolbox The tool window used to store elements that will be dropped onto design surfaces, providing a consistent drag-source for all designers.
Other Start Page The user's portal to Visual Studio, with access to feeds of developer news, Visual Studio help, and recent projects. Users can also create custom start pages by copying the StartPage.xaml file from the “Common7\IDE\StartPages\” Visual Studio program files directory to the StartPages folder in the Visual Studio documents directory, and then either editing the XAML by hand or opening it in Visual Studio or another code editor.
Debugger: a group of windows specific to debugging tasks and monitoring activities Autos
Debugger: a group of windows specific to debugging tasks and monitoring activities Immediate
Debugger: a group of windows specific to debugging tasks and monitoring activities Output The output window can be used whenever you have textual events or status to declare.
Debugger: a group of windows specific to debugging tasks and monitoring activities Memory
Debugger: a group of windows specific to debugging tasks and monitoring activities Breakpoints
Debugger: a group of windows specific to debugging tasks and monitoring activities Running
Debugger: a group of windows specific to debugging tasks and monitoring activities Documents
Debugger: a group of windows specific to debugging tasks and monitoring activities Call Stack
Debugger: a group of windows specific to debugging tasks and monitoring activities Locals
Debugger: a group of windows specific to debugging tasks and monitoring activities Watches
Debugger: a group of windows specific to debugging tasks and monitoring activities Disassembly
Debugger: a group of windows specific to debugging tasks and monitoring activities Registers
Debugger: a group of windows specific to debugging tasks and monitoring activities Threads

Document editor conventions

Document interactions

The "document well" is the largest space within the IDE and is where the user generally has focused their attention in order to complete their tasks, assisted by supplemental tool windows. Document editors represent the fundamental units of work that the user opens and saves within Visual Studio. They retain a strong sense of selection tied to Solution Explorer or other active hierarchy windows. The user should be able to point to one of those hierarchy windows and know where the document is contained and its relationship to either the solution, the project, or another root object provided by a Visual Studio package.

Document editing requires a consistent user experience. To allow the user to focus on the task at hand instead of on window management and finding commands, select a document view strategy that best fits the user tasks for editing that document type.

Common interactions for the document well

  • Maintain a consistent interaction model in the common New File and Open File experiences.

  • Update related functionality in related windows and menus when the document window opens.

  • Menu commands are appropriately integrated into common menus such as Edit, Format, and View menus. If a substantial amount of specialized commands are available, then a new menu can be created which is visible only when the document has focus.

  • An embedded toolbar may be placed at the top of the editor. This is preferable to having a separate toolbar that appears outside the editor.

  • Always maintain a selection in the Solution Explorer or similar active hierarchy window.

  • Double-clicking a document in the Solution Explorer should perform the same action as Open.

  • If more than one editor can be used on a document type, the user should be able to override or reset the default action on a given document type using the Open With dialog box by right-clicking on the file and selecting Open With from the shortcut menu.

  • Don’t build a wizard in a document well.

User expectations for specific document types

There are several different basic types of document editors and each has a set of interactions that are consistent with others of the same type.

  • Text-based editor: code editor, log files

  • Design surface: WPF forms designer, Windows forms

  • Dialog-style editor: Manifest Designer, project properties

  • Model designer: workflow designer, codemap, architecture diagram, progression

    There are also several non-editor types that use the document well. While they don't edit documents themselves, they do need to follow standard interactions for document windows.

  • Reports: IntelliTrace report, Hyper-V report, profiler report

  • Dashboard: Diagnostics Hub

Text-based editors

  • The document participates in the preview tab model, allowing for previewing the document without opening it.

  • The structure of the document may be represented within a companion tool window, such as a document outline.

  • IntelliSense (if appropriate) will behave consistently with other code editors.

  • Pop-ups or assistive UI follow similar styles and patterns for existing similar UI, such as CodeLens.

  • Messages regarding document status will be presented in an infobar control at the top of the document or in the status bar.

  • The user must be able to customize the appearance of fonts and colors using a Tools > Options page, either the shared Fonts and Colors page or one specific to the editor.

Design surfaces

  • An empty designer should have a watermark on the surface indicating how to get started.

  • View-switching mechanisms will follow existing patterns such as double-click to open a code editor, or tabs within the document window allowing interaction with both panes.

  • Adding elements to the design surface should be done via the Toolbox, unless a highly specific tool window is required.

  • Items on the surface will follow a consistent selection model.

  • Embedded toolbars contain document-specific commands only, not common commands such as Save.

Dialog-style editors

  • Control layout should follow normal dialog layout conventions.

  • Tabs within the editor should not match the appearance of the document tabs, they should match one of the two allowed interior tab styles.

  • Users must be able to interact with the controls using keyboard only; either by activating the editor and tabbing through controls or by using standard mnemonics.

  • The designer should use the common Save model. No overall Save or commit buttons should be placed on the surface, although other buttons may be appropriate.

Model designers

  • An empty designer should have a watermark on the surface indicating how to get started.

  • Adding elements to the design surface should be done via the Toolbox.

  • Items on the surface will follow a consistent selection model.

  • Embedded toolbars contain document-specific commands only, not common commands such as Save.

  • A legend may appear on the surface, either indicative or a watermark.

  • The user must be able to customize the appearance of the fonts/colors using a Tools > Options page, either the shared Fonts and Colors page or one specific to the editor.

Reports

  • Reports are typically information-only and don’t participate in the Save model. However, they may include interaction such as links to other relevant information or sections that expand and collapse.

  • Most commands on the surface should be hyperlinks, not buttons.

  • Layout should include a header and follow the standard report layout guidelines.

Dashboards

  • Dashboards don’t have an interaction model themselves, but serve as a means to offer a variety of other tools.

  • They do not participate in the Save model.

  • Users must be able to interact with the controls using keyboard only, either by activating the editor and tabbing through controls or by using standard mnemonics.

Dialogs

Introduction

Dialogs in Visual Studio should typically support one discrete unit of the user's work and then be dismissed.

If you have determined that you need a dialog, you have three choices, in order of preference:

  1. Integrate your features into one of the shared dialogs in Visual Studio.

  2. Create your own dialog using a pattern found in an existing similar dialog.

  3. Create a new dialog, following interaction and layout guidelines.

    This topic describes how to choose the correct dialog pattern within Visual Studio workflows and the common conventions for dialog design.

Themes

Dialogs in Visual Studio follow one of two basic styles:

Standard (unthemed)

The majority of dialogs are standard utility dialogs and should be unthemed. Do not re-template common controls or attempt to create stylized "modern" buttons or controls. Controls and chrome appearance follow standard Windows Desktop interaction guidelines for dialog boxes.

Themed

Specialty "signature" dialogs may be themed. Themed dialogs have a distinct appearance, which also has some special interaction patterns associated with the style. Theme your dialog only if it meets these requirements:

  • The dialog is a common experience that will be seen and used often or by many users (for example, the New Project dialog.

  • The dialog contains prominent product brand elements (for example, the Account Settings dialog).

  • The dialog appears as an integral part of a larger flow that includes other themed dialogs (for example, the Add Connected Service dialog).

  • The dialog is an important part of an experience that plays a strategic role in promoting or differentiating a product version.

    When creating a themed dialog, use the appropriate environment colors and follow the correct layout and interaction patterns. (See Layout for Visual Studio)

Dialog design

Well-designed dialogs take the following elements into consideration:

  • The user task being supported

  • The dialog text style, language, and terminology

  • Control choice and UI conventions

  • Visual layout specification and control alignment

  • Keyboard access

Content organization

Consider the differences between these basic types of dialogs:

  • Simple dialogs present controls in a single modal window. The presentation might include variations of complex control patterns, including a field picker or an icon bar.

  • Layered dialogs are used to make the most of screen real estate when a single piece of UI comprises multiple groups of controls. The dialog's groupings are "layered" through tab controls, navigation list controls, or buttons so that the user can choose which grouping to see at any given moment.

  • Wizards are useful for directing the user through a logical sequence of steps toward the completion of a task. A series of choices are offered in sequential panels, sometimes introducing different workflows ("branches") dependent on a choice made in the previous panel.

Simple dialogs

A simple dialog is a presentation of controls in a single modal window. This presentation might include variations of complex control patterns, such as a field picker. For simple dialogs, follow the standard general layout as well as any specific layout required for complex control groupings.

Simple dialog in Visual Studio

Create Strong Name Key is an example of a simple dialog in Visual Studio.

Layered dialogs

Layered dialogs include tabs, dashboards, and embedded trees. They are used to maximize real estate when there are multiple groups of controls offered in a single piece of UI. The groupings are layered so that the user can choose which grouping to see at any one time.

In the most straightforward case, the mechanism for switching between groupings is a tab control. There are several alternatives available. See Prioritizing and layering for how to choose the most appropriate style.

The Tools > Options dialog is an example of a layered dialog using an embedded tree:

Layered dialog in Visual Studio

Tools > Options is an example of a layered dialog in Visual Studio.

Wizards

Wizards are useful for directing the user through a logical sequence of steps in the completion of a task. A series of choices are offered in sequential panels, and the user must continue through each step before proceeding to the next. Once sufficient defaults are available, the Finish button is enabled.

Modal wizards are used for tasks that:

  • Contain branching, where different paths are offered depending on user choices

  • Contain dependencies between steps, where subsequent steps depend on user input from the preceding step(s)

  • Are sufficiently complex that the UI should be used to explain the choices offered and the possible outcomes in each step

  • Are transactional, requiring a set of steps to be completed in its entirety before any changes are committed

Common conventions

To achieve optimal design and functionality with your dialogs, follow these conventions on dialog size, position, standards, control configuration and alignment, UI text, title bars, control buttons, and access keys.

For layout-specific guidelines, see Layout for Visual Studio.

Size

Dialogs should fit within a minimum 1024x768 screen resolution, and initial dialog size should not exceed 900x700 pixels. Dialogs may be resizable, but it is not a requirement.

There are two recommendations for resizable dialogs:

  1. That a minimum size is a defined for the dialog that will optimize for the control set without clipping, and adjust to accommodate reasonable localization growth.

  2. That the user-scaled size persists from session to session. For example, if the user scales a dialog to 150%, then a subsequent launch of the dialog will display at 150%.

Position

Dialogs must appear centered within the IDE on first launch. For non-resizable dialogs, it is not required that the last position of the dialog be persisted, so it will appear centered on subsequent launches. For resizable dialogs, the size should be persisted on subsequent launches. For resizable dialogs that are modal, the position does not need to be persisted. Displaying them centered within the IDE prevents the possibility of the dialog appearing in an unpredictable or unusable position when the user's display configuration has changed. For modeless dialogs that can be repositioned, the user's position should be maintained on subsequent launches, as the dialog may be used frequently as an integral part of a larger workflow.

When dialogs must spawn other dialogs, the topmost dialog should cascade to the right and down from the parent so that it is obvious to the user that they have navigated to a new place.

Modality

Being modal means that users are required to complete or cancel the dialog before continuing. Since modal dialogs block the user from interacting with other parts of the environment, your feature's task flow should use them as sparingly as possible. When a modal operation is necessary, Visual Studio has a number of shared dialogs you can integrate your features into. If you must create a new dialog, follow the interaction pattern of an existing dialog with similar functionality.

When users need to perform two activities at once, such as Find and Replace while writing new code, the dialog should be modeless so that the user can easily switch between them. Visual Studio generally uses tool windows for this kind of editor-supporting linked task.

Control configuration

Be consistent with existing control configurations that accomplish the same thing in Visual Studio.

Title bars

  • The text in the title bar must reflect the name of the command that launched it.

  • No icon should be used in dialog title bars. In cases where the system requires one, use the Visual Studio logo.

  • Dialogs should not have minimize or maximize buttons.

  • Help buttons in the title bar have been deprecated. Do not add them to new dialogs. When they do exist, they should launch a Help topic that is conceptually relevant to the task.

    Title bar specifications for Visual Studio

    Guideline specifications for title bars in Visual Studio dialogs.

Control buttons

In general, OK/Cancel/Help buttons should be arranged horizontally in the lower right corner of the dialog. The alternate vertical stack is permitted if a dialog has several other buttons at the bottom of the dialog that would present visual confusion with the control buttons.

Control button configurations in Visual Studio

Acceptable configurations for control buttons in Visual Studio dialogs

The dialog must include a default control button. To determine the best command to use as the default, choose from the following options (listed in order of precedence):

  • Choose the safest and most secure command as the default. This means choosing the command most likely to prevent data loss and avoid unintended system access.

  • If data loss and security aren't factors, then choose the default command based on convenience. Including the most likely command as the default will improve the user’s workflow when the dialog supports frequent or repetitive tasks.

    Avoid choosing a permanently destructive action for the default command. If such a command is present, choose a safer command as the default instead.

Access keys

Do not use access keys for OK/Cancel/Help buttons. These buttons are mapped to shortcut keys by default:

Button name Keyboard shortcut
OK Enter
Cancel Esc
Help F1

Imagery

Use images sparingly in dialogs. Do not use large icons in dialogs merely to use up space. Use images only if they are an important part of conveying the message to the user, such as warning icons or status animations.

Prioritizing and layering

Prioritizing your UI

It might be necessary to bring certain UI elements to the forefront and place more advanced behavior and options (including obscure commands) into dialogs. Bring commonly used functionality to the forefront by making room for it, and by making it visible by default in the UI with a text label when the dialog is shown.

Layering your UI

If you have determined that a dialog is necessary but the related functionality you want to present to the user goes beyond what can be displayed in a simple dialog, then you need to layer your UI. The most common layering methods Visual Studio uses are tabs and hallways or dashboards. In some cases, regions that can expand and collapse might be appropriate. Adaptive UI is generally not recommended in Visual Studio.

There are advantages and disadvantages to different methods of layering UI through tab-like controls. Review the list below to ensure that you are choosing a layering technique that is appropriate to your situation.

Tabbing
Switching mechanism Advantages and appropriate use Disadvantages and inappropriate use
Tab control Logically group dialog pages into related sets

Useful for fewer than five (or the number of tabs that fit in one row across the dialog) pages of related controls in dialog

Tab labels must be short: one or two words that can easily identify the content

A common system dialog style

Example: File Explorer > Item Properties
Making descriptive short labels can be difficult

Generally doesn't scale past five tabs in one dialog

Inappropriate if you have too many tabs for one row; use an alternative layering technique

Not extensible
Sidebar navigation Simple switching device that can accommodate more categories than tabs

Flat list of categories (no hierarchy)

Extensible

Example: Customize… > Add Command
Not a good use of horizontal space if there are fewer than three groups

Task might be better suited to a drop-down
Tree control Allows for unlimited categories

Allows for grouping and/or hierarchy of categories

Extensible

Example: Tools > Options
Heavily nested hierarchies can cause excessive horizontal scrolling

Visual Studio has an overabundance of tree views
Wizard Aids in task completion by guiding through task-based, sequential steps. The wizard represents a high-level task and the individual panels represent subtasks needed to accomplish the overall task.

Useful when the task crosses Ui boundaries, as when the user would otherwise have to use multiple editors and tool windows to complete the task

Useful when the task requires branching

Useful when the task contains dependencies between steps

Useful when several similar tasks with one decision fork can be presented in one dialog to reduce the number of different similar dialogs.
Inappropriate for any task that does not require a sequential workflow

Users can become overwhelmed and confused by a wizard with too many steps

Wizards have inherently limited screen real estate
Hallways or dashboards

Hallways and dashboards are dialogs or panels that serve as launching points to other dialogs and windows. The well-designed "hallway" immediately surfaces only the most common options, commands, and settings, allowing the user to readily accomplish common tasks. Like a real-world hallway provides doorways to access the rooms behind them, here the less-common UI is collected into separate "rooms" (often other dialogs) of related functionality that can be accessed from the main hallway.

Alternatively, a UI that offers all available functionality in a single collection rather than refactoring the less-common functionality into separate locations is simply a dashboard.

Hallway concept in Outlook

Hallway concept for exposing additional UI in Outlook

Adaptive UI

Showing or hiding UI based on usage or a user's self-reported experience is another way of presenting necessary UI while hiding other portions. This is not recommended in Visual Studio as the algorithms for deciding when to show or hide UI can be tricky, and the rules will always be wrong for some set of cases.

Projects

Projects in the Solution Explorer

Most projects are classified as reference-based, directory-based, or mixed. All three types of projects are supported simultaneously in the Solution Explorer. The root of the user experience in working with projects takes place inside this window. Although different project nodes are reference, directory, or mixed-mode type projects, there is a common interaction pattern that should be applied as a starting point before diverging into project-specific user patterns.

Projects should always:

  • Support the ability to add project folders to organize project contents

  • Maintain a consistent model for project persistence

    Projects should also maintain consistent interaction models for:

  • Removing project items

  • Saving documents

  • Project property editing

  • Editing the project in an alternate view

  • Drag-and-drop operations

Drag-and-drop interaction model

Projects typically classify themselves as reference-based (able to persist only references to project items in storage), directory-based (able to persist only project items physically stored within a project's hierarchy), or mixed (able to persist references or physical items). The IDE accommodates all three types of projects simultaneously within the Solution Explorer.

From a drag-and-drop perspective, the following characteristics should apply to each type of project within the Solution Explorer:

  • Reference-based project: The key point is that the project is dragging around a reference to an item in storage. When a reference-based project acts as a source for a move operation, it should only remove the reference to the item from the project. The item should not actually be deleted from the hard drive. When a reference-based project acts as a target for a move (or copy) operation, it should add a reference to the original source item without making a private copy of the item.

  • Directory-based project: From a drag-and-drop point of view, the project is dragging around the physical item rather than a reference. When a directory-based project acts as a source for a move operation, it should end up deleting the physical item from the hard drive as well as removing it from the project. When a directory-based project acts as a target for a move (or copy) operation, it should make a copy of the source item in its target location.

  • Mixed-target project: From a drag-and-drop point of view, the behavior of this type of project is based on the nature of the item being dragged (either a reference to an item in storage or the item itself). The correct behavior for references and physical items are described above.

    If there were only one type of project in the Solution Explorer, then drag-and-drop operations would be straightforward. Because each project system has the ability to define its own drag-and-drop behavior, certain guidelines (based on the Windows Explorer drag-and-drop behavior) should be followed to ensure a predictable user experience:

  • An unmodified drag operation in the Solution Explorer (when neither Ctrl nor Shift keys are held down) should result in a move operation.

  • Shift-drag operation should also result in a move operation.

  • Ctrl-drag operation should result in a copy operation.

  • Reference-based and mixed project systems support the notion of adding a link (or reference) to the source item. When these projects are the target of a drag-and-drop operation (when Ctrl + Shift is held down), it should result in a reference to the item being added to the project

    Not all drag-and-drop operations are sensible across combinations of reference-based, directory-based, and mixed projects. In particular, it is problematic to pretend to allow a move operation between a directory-based source project and reference-based target project because the source directory-based project will have to delete the source item upon completion of the move. The target reference-based project would then end up with a reference to a deleted item.

    It is also misleading to pretend to allow a copy operation between these types of projects because the target reference-based project should not make an independent copy of the source item. Similarly, Ctrl + Shift dragging to a directory-based target project should not be allowed because a directory-based project is unable to persist references. In cases where the drag-and-drop operation is not supported, the IDE should disallow the drop and show the user the no-drop cursor (shown in the pointer table below).

    To properly implement drag-and-drop behavior, the source project of the drag needs to communicate its nature (for example, is it reference- or directory-based?) to the target project. This information is indicated by the clipboard format that is offered by the source. As the source of a drag (or clipboard copy operation) a project should offer either CF_VSREFPROJECTITEMS or CF_VSSTGPROJECTITEMS respectively, depending on whether the project is reference-based or directory-based. Both of these formats have the same data content, which is similar to the Windows CF_HDROP format except that lists of strings, instead of being filenames, are a double-NULL terminated list of Projref strings (as returned from IVsSolution::GetProjrefOfItem or ::GetProjrefOfProject as appropriate).

    As the target of a drop (or clipboard paste operation), a project should accept both CF_VSREFPROJECTITEMS and CF_VSSTGPROJECTITEMS, though the exact handling of the drag-and-drop operation varies depending on the nature of the target project and the source project. The source project declares its nature by whether it offers CF_VSREFPROJECTITEMS or CF_VSSTGPROJECTITEMS. The target of the drop understands its own nature and thus has enough information to make decisions as to whether a move, copy, or link should be performed. The user also modifies which drag-and-drop operation should be performed by pressing the Ctrl, Shift, or both Ctrl and Shift keys. It is important for the drop target to properly indicate which operation will be performed in advance in its DragEnter and DragOver methods. The Solution Explorer automatically knows whether the source project and the target project are the same project.

    Dragging project items across instances of Visual Studio (for example, from one instance of devenv.exe to another) is specifically not supported. The Solution Explorer also directly disables this.

    The user should always be able to determine the effect of a drag-and-drop operation by selecting an item, dragging it to the target location, and observing which of the following mouse pointers appears before the item is dropped:

Mouse pointer Command Description
Mouse "no drop" icon No drop Item cannot be dropped to the specified location.
Mouse "copy" icon Copy Item will be copied to the target location.
Mouse "move" icon Move Item will be moved to the target location.
Mouse "add reference" icon Add reference A reference to the selected item will be added to the target location.

Reference-based projects

The following table summarizes the drag-and-drop (as well as cut/copy/paste) operations that should be performed based on the nature of the source item and modifier keys pressed for referenced-based target projects:

Source item: Reference/Link Source item: Physical item or file system (CF_HDROP)
No modifier Action Move Link
No modifier Target Adds reference to original item Adds reference to original item
No modifier Source Deletes reference to original item Retains original item
No modifier Result DROPEFFECT_MOVE is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_LINK is returned as action from ::Drop and item remains in original location in storage
Shift+Drag Action Move No drop
Shift+Drag Target Adds reference to original item No drop
Shift+Drag Source Deletes reference to original item No drop
Shift+Drag Result DROPEFFECT_MOVE is returned as action from ::Drop and item remains in original location in storage No drop
Ctrl+Drag Action Copy No drop
Ctrl+Drag Target Adds reference to original item No drop
Ctrl+Drag Source Retains reference to original item No drop
Ctrl+Drag Result DROPEFFECT_COPY is returned as action from ::Drop and item remains in original location in storage No drop
Ctrl+Shift+Drag Action Link Link
Ctrl+Shift+Drag Target Adds reference to original item Adds reference to original item
Ctrl+Shift+Drag Source Retains reference to original item Retains original item
Ctrl+Shift+Drag Result DROPEFFECT_LINK is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_LINK is returned as action from ::Drop and item remains in original location in storage
Ctrl+Shift+Drag Note Same as drag-and-drop behavior for shortcuts in Windows Explorer.
Cut/Paste Action Move Link
Cut/Paste Target Adds reference to original item Adds reference to original item
Cut/Paste Source Retains reference to original item Retains original item
Cut/Paste Result Item remains in original location in storage Item remains in original location in storage
Copy/Paste Action Copy Link
Copy/Paste Source Adds reference to original item Adds reference to original item
Copy/Paste Result Retains reference to original item Retains original item
Copy/Paste Action Item remains in original location in storage Item remains in original location in storage

Directory-based projects

The following table summarizes the drag-and-drop (as well as cut/copy/paste) operations that should be performed based on the nature of the source item and modifier keys pressed for directory-based target projects:

Source item: Reference/Link Source item: Physical item or file system (CF_HDROP)
No modifier Action Move Move
No modifier Target Copies item to target location Copies item to target location
No modifier Source Deletes reference to original item Deletes reference to original item
No modifier Result DROPEFFECT_ MOVE is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_ MOVE is returned as action from ::Drop and item remains in original location in storage
Shift+Drag Action Move Move
Shift+Drag Target Copies item to target location Copies item to target location
Shift+Drag Source Deletes reference to original item Deletes item from original location
Shift+Drag Result DROPEFFECT_ MOVE is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_ MOVE is returned as action from ::Drop and item remains in original location in storage
Ctrl+Drag Action Copy Copy
Ctrl+Drag Target Copies item to target location Copies item to target location
Ctrl+Drag Source Retains reference to original item Retains reference to original item
Ctrl+Drag Result DROPEFFECT_ COPY is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_ COPY is returned as action from ::Drop and item remains in original location in storage
Ctrl+Shift+Drag No drop No drop
Cut/Paste Action Move Move
Cut/Paste Target Copies item to target location Copies item to target location
Cut/Paste Source Deletes reference to original item Deletes item from original location
Cut/Paste Result Item remains in original location in storage Item is deleted from original location in storage
Copy/Paste Action Copy Copy
Copy/Paste Target Adds reference to original item Copies item to target location
Copy/Paste Source Retains original item Retains original item
Copy/Paste Result Item remains in original location in storage Item remains in original location ins storage

Mixed-target projects

The following table summarizes the drag-and-drop (as well as cut/copy/paste) operations that should be performed based on the nature of the source item and modifier keys pressed for mixed-target projects:

Source item: Reference/Link Source item: Physical item or file system (CF_HDROP)
No modifier Action Move Move
No modifier Target Adds reference to original item Copies item to target location
No modifier Source Deletes reference to original item Deletes reference to original item
No modifier Result DROPEFFECT_ MOVE is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_ MOVE is returned as action from ::Drop and item is deleted from original location in storage
Shift+Drag Action Move Move
Shift+Drag Target Adds reference to original item Copies item to target location
Shift+Drag Source Deletes reference to original item Deletes item from original location
Shift+Drag Result DROPEFFECT_ MOVE is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_ MOVE is returned as action from ::Drop and item is deleted from original location in storage
Ctrl+Drag Action Copy Copy
Ctrl+Drag Target Adds reference to original item Copies item to target location
Ctrl+Drag Source Retains reference to original item Retains original item
Ctrl+Drag Result DROPEFFECT_ COPY is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_ COPY is returned as action from ::Drop and item remains in original location in storage
Ctrl+Shift+Drag Action Link Link
Ctrl+Shift+Drag Target Adds reference to original item Adds reference to original source item
Ctrl+Shift+Drag Source Retains reference to original item Retains original item
Ctrl+Shift+Drag Result DROPEFFECT_ LINK is returned as action from ::Drop and item remains in original location in storage DROPEFFECT_ LINK is returned as action from ::Drop and item remains in original location in storage
Cut/Paste Action Move Move
Cut/Paste Target Copies item to target location Copies item to target location
Cut/Paste Source Deletes reference to original item Deletes item from original location
Cut/Paste Result Item remains in original location in storage Item is deleted from original location in storage
Copy/Paste Action Copy Copy
Copy/Paste Target Adds reference to original item Copies item to target location
Copy/Paste Source Retains original item Retains original item
Copy/Paste Result Item remains in original location in storage Item remains in original location in storage

These details should be taken into consideration when implementing dragging in the Solution Explorer:

  • Design for multiple selection scenarios.

  • File names (full path) must be unique across the target project or the drop should not be allowed.

  • Folder names must be unique (case-insensitive) at the level they are being dropped.

  • There are behavior differences between files that are open or closed at time of drag (not mentioned in scenarios above).

  • Top-level files behave slightly differently than files in folders.

    Another issue to be aware of is how to handle move operations on items that have open designers or editors. The expected behavior is as follows (this applies to all project types):

  1. If the open editor/designer does not have any unsaved changes, then the editor/designer window should be silently closed.

  2. If the open editor/designer does have unsaved changes, then the source of the drag should wait for the drop to occur and then ask the user to save the uncommitted changes in the open documents before closing the window with a prompt similar to the following:

    ==========================================================
         One or more open documents have unsaved changes.
    Do you want to save uncommitted changes before proceeding?
                      [Yes]  [No]  [Cancel]
    ==========================================================
    

    This gives the user the opportunity to save work in progress before the target makes its copies. A new method IVsHierarchyDropDataSource2::OnBeforeDropNotify has been added to enable this handling.

    The target will then copy the state of the item as it is in storage (not including the unsaved changes in the editor if the user chose No). After the target has completed its copying (in IVsHierarchyDropDataSource::Drop), the source is given the opportunity to complete the delete portion of the move operation (in IVsHierarchyDropDataSource::OnDropNotify).

    Any editors with unsaved changes should be left open. For those documents with unsaved changes, this means that the copy portion of the move operation will be performed but the delete portion will be aborted. In a multiple selection scenario when the user chooses No, those documents with unsaved changes should not be closed or removed, but those without unsaved changes should be closed and removed.