Introduction
I often run into creating applications that opens, edits, saves a file/remote script etc. I am sure that most of the developers create such utility applications to make their work/life easy. As I wanted to learn WPF, PRISM, MVVM and create an IDE like application - I created the Wide IDE framework. Rather than a framework, Wide is a set of modules that can help in building VS 2012 like applications quickly. Like every modular PRISM application, modules can participate in building the IDE along with adding new functionality to the application.
Wide framework allows you to build your application by creating PRISM modules which participate in building the IDE. This way you can modularize the code for each functional area of your application.
Background
If you are serious about a building an IDE with debugger etc, you can use Wide however, I would highly recommend you looking at Visual Studio Extensibility (VSX) framework or other real life IDE's such as SharpDevelop, Eclipse or Netbeans.
Background about PRISM Modules
Image from http://msdn.microsoft.com/en-us/library/gg405479(v=pandp.40).aspx
There are some PRISM tutorials available on Code Project which should be a good read to understand how modules are built.
Modules in Wide
Wide comes with two modules and various out of the box functions:
Core module (Required)
- Used for customizable splash screen
- Used for Menus (supports regular menus with icon, checkable menus)
- Used for Toolbar (menu view model can be reused for toolbars)
- Multiple toolbars can be added to the IDE (check demo)
- Themes (VS2010, VS2012 Light theme and no theme)
- ThemeManager to add/remove themes
- Used for Statusbar (in development)
- Open file service with participatory handlers (could be based on extension or even file contents)
- Save and restore layout along with opening documents
Logger module (For the logging tool)
Understanding Wide Framework
As Wide modules are basically PRISM modules, I will start by describing how the code is organized in the framework.
- Wide.Interfaces - Contains all the interfaces, abstract classes needed for your application. Each modules that you create (I generally create
one project per module), need to reference this project/DLL. This project also contains events used by the event aggregator in PRISM.
- Wide.Core - Contains all the core services needed for the application to work. Most of the classes are internal/sealed.
- Wide.Splash - Contains a base implementation of a splash screen. You can override the splash screen by registering your own version of the splash screen with the Unity Container before the module is loaded. See sample application.
- Wide.Shell - Contains two implementations of the Shell which will be the main window hosted by the application. The two flavors are Metro (used for VS 2012 like applications) and Regular (older VS like apps). This can be defined by passing in a value to the constructor of the Bootstrapper.
- Wide.Tools.Logger - Contains the logger module. A good example of how to write modules for your own application. This is not a required module for your application.
- Wide.Settings - Under development. This module is to provide a settings window like the Visual studio settings window for your application. Again, other modules can participate in settings manager.
The above class diagram indicates how the classes are organized in the Wide.Interfaces project. Some of the important classes are described below:
- ContentViewModel - This is the class which you need to inherit to create your own type of document. See
TextViewModel.cs in the Wide.Core project to understand how to create your own type.
- MenuItemViewModel - This is the class which you need to create a menu. This menu needs to be added to the
AbstractMenuItem
singleton object. Check Loader.cs for details on how to add menu.
- ToolbarViewModel - This class is used to create Toolbars. The good part is, toolbar items can be created from
MenuItemViewModel
objects. Again, check Loader.cs for details.
There are also some services added by the Wide.Core project to your application. You can access these services by trying to resolve their corresponding interfaces. Some of the important services are:
- IWorkspace - The workspace itself. You can also register your own workspace before all the modules are loaded which can be used in your application. Check the VS2012TestApp project for more info.
- IOpenFileService - A generic file open service which calls the
OpenFileDialog
and returns the appropriate ContentViewModel.
- IContentHandlerRegistry - Another important service where you can register the type of content that you will be handling. For example: If your ContentViewModel can only be used for ".cs" files, you can create a CSFileHandler (implementing
IContentHandler
), and register it with this service. The IOpenFileService
will call all the Handlers to check if the handler can open the file - if so, the first one which can open the file can process and returns the ContentViewModel. For example, check
AllFileHandler.cs in Wide.Core.
- AbstractMenuItem - This is a service as well as an abstract class which you can inherit to create your own flavor of menu item. Check
Loader.cs.
- IToolbarService - This is an interesting service and it introduces a toolbar pane on the shell. Each ToolbarViewModel can create a new toolbar and can be registered with this service. Currently, the position (band, index) is NOT stored by the application - the support is there, but it is not yet implemented.
- IThemeManager - This service is used to add themes to the application and set a current theme for the application. Check
DarkTheme.cs in Wide.Interfaces project.
- ICommandManager - This service is used to register commands with a key to promote re-usability of the command.
- ILoggerService - The logger module registers a NLogService as a singleton. You can create your own logger service and register it before loading regular modules, this way you can use your preferred logging library.
Creating a simple application
Creating IDE like applications using Wide is going to be really simple. Wide is based on Unity container. The
WideBootstrapper
inherits from UnityBootstrapper
and comes with some basic out of the box functions such as creating splash screen for the application, creating the shell etc.
Your application needs to reference all the dependent libraries and Wide libraries. The following code is used to get a simple Wide application.
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
new WideBootstrapper().Run();
}
}
For more information on how to use Wide, check out the test application at https://github.com/chandramouleswaran/Wide
Sample application on Nuget
You can also install Wide using Nuget. Below given are the steps to install and also start using Wide quickly.
- Create a WPF Application project (4.0) - Give it any name
- Once the project is created, delete
MainWindow.xaml and App.xaml (this needs to be done as NuGet is going to update the project with new files)
- Open Package manager console (View > Other Windows > Package Manager Console)
- Type "Install-Package Wide.Example -Pre" (NuGet)
- Once the package is installed - open the Properties of
App.xaml and set the build action to "ApplicationDefinition"
- Set the Copy to output directory for
NLog.config to "Copy Always"
Screenshots from sample apps
VS 2012 like application
VS 2010 like application
Libraries used
Wide is built using variety of open source projects:
In the process of building Wide, I was able to look at various open source projects, learn and most importantly contribute back to the project.
Plans ahead
- Settings manager for the application
- Status bar service
- Dark, Expression themes
- more on request from users (if any)
Credits
Some open source projects had certain parts built nicely of which a few were used in my project:
- EDI - Visual studio 2010 theme was set perfect. Themes for menu and toolbar were flicked from this project.
-
MetroLikeWindow - This has some bugs but overall, adds a glow effect to the window. Contributed to MahApps.Metro.
-
CBR - One really good and well maintained comic book reader.
-
StackOverflow - Most of my questions already had an answer here.
Points of Interest
As simple as the framework looks, it took me months to build it after my regular working hours between 9am to 5pm. I did look at SoapBox core, Gemini - other similar WPF solutions but building something from scratch makes you learn the language and understand the technology better. If there are any mistakes in my code or anything that I could have done differently, please let me know so that I can improve the framework and update the article.
Overall, I think I have become a Github, CodeProject, Codeplex, Stackoverflow and #D junkie in the process of creating Wide. I like social coding and if you are into social coding, please contribute to Wide/contact me if you have any feedback, questions.
History
- 03/01/2013 - Added library and sample in NuGet.
- 02/24/2013 - First version of Wide on Code project. More details to be added based on request/feedback.