Archive for July, 2008

ClusterMap just added!

Hi, everyone!

I’ve just added a cluster map to my blog! A pretty nice widget that you may see at the “Map” menu.

 

Enjoy! I’m sure I will! From now on I’ll be able to track from where my blog is visited! :D

 

Cheers!

- Nacho

CAB Quickie – The Plug-in Application: The Message Plug-in (Part 4)

 

In this part, you will finish the quickie by adding a CAB module to the project: the Message plug-in. It is called like that as it will only display a message entered by the user. The input will be performed on a view (a SmartPart), which will be a UserControl, so, you will add a Windows Control Library.

1. In Visual Studio, point to Add on the File menu, and then click New Project.

templateMessageProject

Figure. Creating the MessagePlugin module project.

2. In the New Project dialog box, expand the Visual C# node. Click the Windows project type.

3. In the Templates window, select Windows Control Library.

4. Change the Name to MessagePlugin.

5. Change the location for the solution to the source folder located inside the PluginQuickie folder.

6. Click OK.

SEMessagePlugin

Figure. The MessagePlugin module project added to the solution.

As you have already done, you will change the output path of the MessagePlugin project to bin\Debug folder. To accomplish this, right-click the MessagePlugin project (in the Solution Explorer) and select Properties. In the Build tab, go to the Output section and edit the Output path to %PluginQuickieFolder%\bin\Debug.

Moreover, add only the CAB assemblies located in the Lib folder in the same way you did at the CAB Quickie – The Plug-in Application: The CAB Plug-in System Application post.

Once you have done this, you will start setting up the view:

1. In the Solution Explorer, right-click the UserControl1.cs file, select Rename, and change the name to MessageView.cs.

2. Set its Size property to 210, 80.

3. Add a Label to the MessageView with the following values set to the corresponding properties:

 

Property Value
(Name) titleLabel
AutoSize False
BackColor LightBlueSky
Dock Top
Font Arial, 9,75pt, style=Bold
ForeColor White
Location 210, 19
Text Write a message:

4. Add a TextBox to the MessageView with the following values set to the corresponding properties:

 

Property Value
(Name) messageTextBox
Location 3, 23
Size 202, 20

5. Add a Button to the MessageView with the following values set to the corresponding properties:

 

Property Value
(Name) displayButton
Location 70, 49
Size 75, 23
Text Display

6. Double-click the displayButton to generate the code for the handler for its click and add the following code line inside:

MessageBox.Show(messageTextBox.Text, “Showing message:”);

Done with the View! :)

By now you may be wondering: “Wait a minute! No presenter or controller for this view?” Well, the MVC and the MVP patterns are intended for complex UI logic and to separate it from a complex model. None of these points are present, so none of the patterns (MVC and MVP) are present. :)

Let’s keep going! The MessagePlugin module needs two things to get set up: a WorkItem, to get a container for the module, and a ModuleInit class, to get the module initialized and added to the CAB application.

Firstly, let’s start by adding the WorkItem class:

  1. In the Solution Explorer, right-click the MessagePlugin module project, select Add, and then select Class.
  2. Change the Name to MessagePluginWorkItem.cs.
  3. Click OK.

This class will be used as a container only for the whole MessagePlugin module. It will add a menu item to the Plugins menu item located at the main menu strip of the MainForm, which, on click, will display the MessageView in a WindowWorkspace (that will be added in the ModuleInit class later on). So, now, you’ll configure for that purpose:

1. Add the following using statements:

using System.Drawing;

using System.Windows.Forms;

using Microsoft.Practices.CompositeUI;

using Microsoft.Practices.CompositeUI.WinForms;

2. Replace the signature of the class with this one:

public class MessagePluginWorkItem : WorkItem

3. Add the following code to the class, which overrides the OnRunStarted() method (that is called when the WorkItem gets initializated):

protected override void OnRunStarted()

{

    base.OnRunStarted();

    ToolStripMenuItem item = new ToolStripMenuItem(“Message Window”);

    item.Click += new EventHandler(item_Click);

    RootWorkItem.UIExtensionSites["PluginsMenuBar"].Add<ToolStripMenuItem>(item);

}

void item_Click(object sender, EventArgs e)

{

    MessageView view = SmartParts.AddNew<MessageView>();

    WindowSmartPartInfo wspi = new WindowSmartPartInfo();

    wspi.MaximizeBox = false;

    wspi.Title = “Message Plugin!”;

    wspi.Location = new Point(((Screen.PrimaryScreen.WorkingArea.Width – view.Width) / 2), ((Screen.PrimaryScreen.WorkingArea.Height – view.Height) / 2));

    Workspaces["WinWork"].Show(view, wspi);

}

NOTE: As you can see from this code, you’re adding a new ToolStripMenuItem to the PluginsMenuBar UIExtensionSite (that is the menu located in the main menu strip of the form with the text “Plugins”), plus a handler for its click event which creates and adds a new MessageView to the WorkItem and displays it in the “WinWork” WindowWorkspace with a SmartPartInfo (that locates it at centre screen).

Now, let’s add the ModuleInit class:

  1. In the Solution Explorer, right-click the MessagePlugin module project, select Add, and then select Class.
  2. Change the Name to MessagePluginModuleInit.cs.
  3. Click OK.

Now you will configure the class to get the module plugged in to the CAB application:

1. Add the following using statement:

using Microsoft.Practices.CompositeUI;

using Microsoft.Practices.CompositeUI.WinForms;

2. Replace the signature of the class with this one:

public class MessagePluginModuleInit : ModuleInit

3. Add the following code to get the RootWorkItem injected to the class:

private WorkItem _rootWorkItem;

[ServiceDependency]

public WorkItem RootWorkItem

{

    get { return _rootWorkItem; }

    set { _rootWorkItem = value; }

}

NOTE: When CAB gets this class (the ModuleInit class), it searches for dependencies and inject them. The WorkItem that gets injected in this code is, indeed, the RootWorkItem, as it is where the ModuleInit class gets created and added.

4. Add the following code to the class, which overrides the Load() method (that is called in order to load the module):

public override void Load()

{

    base.Load();

   MessagePluginWorkItem workItem = RootWorkItem.WorkItems.AddNew<MessagePluginWorkItem>();

   workItem.Workspaces.AddNew<WindowWorkspace>(“WinWork”);

    workItem.Run();

}

NOTE: This code adds a new instance of the MessagePluginWorkItem to the RootWorkItem and a WindowWorkspace to the MessagePluginWorkItem with the id “WinWork”.

There’s only one thing left to do! How does the CAB Application know that it has to load the MessagePlugin? Simple: by looking at the ProfileCatalog.xml! But the CAB Application does not have one, so let’s add it!

  1. In the Solution Explorer, right-click the CABPluginApplication project, select Add, and then select New Item.
  2. From the Templates dialog box, select XML File.
  3. Change the Name to ProfileCatalog.xml.
  4. Click OK.

Once it’s added, set its Copy to Output Directory property to Copy always (this is very important, otherwise CAB won’t find it and will not load the plug-ins!), and then add this code to the file, which represents the collection of modules the application must initialize:

<SolutionProfile xmlns=http://schemas.microsoft.com/pag/cab-profile>

    <Modules>

    <ModuleInfo AssemblyFile=MessagePlugin.dll/>

    </Modules>

</SolutionProfile>

Having done all these steps, just save, compile and run the project. You will see that the “Hello World!” application has a new menu item under the “Plugins” menu item saying “Message Window”. When you click on it the view is displayed as a new window, thanks to the WindowWorkspace.

The final solution will look like this:

SEFinalSolution

Figure. The final solution.

And, I leave you with some screenshots:

mainApplicationFinal

mainApplicationFinal2

mainApplicationFinal3

 

Conclusion

This Quickie dealt with one possible way to use the ApplicationContextApplication class provided by CAB. There are much more usages than this, for example, displaying more than one form, or a console application. Moreover, the ApplicationContext class that you add to the ApplicationContextApplication class can have dependencies injected, as it is created by CAB, so you may perform several checks before showing a form or start your program.

I hope that this short example (that’s why it’s called a quickie ;) ) may help you have an overview on this class and its usage.

As always: any feedback is welcome! :)

Cheers,

Nacho

CAB Quickie – The Plug-in Application: The CAB Plug-in System Application (Part 3)

 

In this part, you will add the CAB plug-in application. It will be a Windows Application for two reasons:

  1. You will create a class that inherits from the ApplicationContext class, so you need the System.Windows.Forms assembly.
  2. The CAB plug-in application will become the start up project.

Let’s start by adding the new project.

1. In Visual Studio, point to Add on the File menu, and then click New Project.

templateCABProject

Figure. Creating the CABPluginApplication project.

2. In the New Project dialog box, expand the Visual C# node. Click the Windows project type.

3. In the Templates window, select Windows Application.

4. Change the Name to CABPluginApplication.

5. Change the location for the solution to the source folder located inside the PluginQuickie folder.

6. Click OK.

SECABPluginApplication

Figure. The CABPluginApplication project added to the solution.

Now, you need to change the output path of the CABPluginApplication project to bin\Debug folder, in the same way as you did in the CAB Quickie – The Plug-in Application: The Main Application post. To accomplish this, right-click the CABPluginApplication project (in the Solution Explorer) and select Properties. In the Build tab, go to the Output section and edit the Output path to %PluginQuickieFolder%\bin\Debug.

As I wrote in the first post, the CABPluginApplication will not contain a form to display; instead, it will use the MainForm of the MainApplication in an ApplicationContext class. So, you don’t need the Form1.cs file, so just delete it. To do this, right-click the Form1.cs file, in the Solution Explorer, and select Delete.

 

It’s time to get CAB started! Time to add the references!

1. In the Solution Explorer, right-click the References folder and select Add Reference.

2. In the dialog box, go to the Browse tab, browse to the %PluginQuickieFolder%\Lib folder, and select the assemblies you’ve previously copied there:

  • Microsoft.Practices.CompositeUI
  • Microsoft.Practices.CompositeUI.WinForms
  • Microsoft.Practices.ObjectBuilder

Finally, as the CAB application will use the MainForm class of the “Hello World!“ application, you need to add a reference to this project, so in the Projects tab, select the MainApplication project.

After you have done this, the solution should look like this:

SECABReferencesAdded

Figure. CAB and MainApplication references added to the CABPluginApplication project.

The ApplicationContextApplication<TWorkItem, TShell> class calls the Application.Run(ApplicationContext context) method in its overridden Start() method. This is because TShell is type of ApplicationContext. So, you need to add a class that inherits from the ApplicationContext class.

Let’s do that!

  1. In the Solution Explorer, right-click the CABPluginApplication project, select Add, and then select Class.
  2. Change the Name to PluginContext.cs.
  3. Click OK.

This class will inherit from the ApplicationContext class and will use the MainForm class of the “Hello World!” application, so you need to add the following using statements:

using System.Windows.Forms;

using MainApplication;

Then, make it inherit from ApplicationContext by replacing the signature of the class with this one:

public class PluginContext : ApplicationContext

Finally, you will add the necessary code to set its MainForm property with a new instance of the MainApplication class of the “Hello World!” application in its constructor, as follows:

public PluginContext()

{

       this.MainForm = new MainForm();

}

Alright! Almost done! :)

Ok, now that you have set all the necessary things, it’s time to finish configuring the CAB project to make it the new start-up project:

1. In the Solution Explorer, right-click the Program.cs file, select Rename, and change the name to PluginApplication.

2. Right-click the Program.cs file again, and select View Code.

3. Add the following using statements:

using Microsoft.Practices.CompositeUI;

using Microsoft.Practices.CompositeUI.WinForms;

using Microsoft.Practices.CompositeUI.WinForms.UIElements;

4. Replace the signature of the class with this one:

public class PluginApplication : ApplicationContextApplication<WorkItem, PluginContext>

NOTE: Here, you set a WorkItem type to act as the RootWorkItem and a PluginContext type to act as the ApplicationContext of the CABApplication class.

5. Replace the body of the Main() method with the following code:

new PluginApplication().Run();

NOTE: This line will create a new instance of the PluginApplication class and call the CABApplication.Run() method.

6. Override the AfterShellCreated() method, and place the following code:

protected override void AfterShellCreated()

{

    base.AfterShellCreated();

    ToolStripMenuItem item = new ToolStripMenuItem(“Plugins”);

    this.Shell.MainForm.MainMenuStrip.Items.Add(item);

    ToolStripItemCollectionUIAdapter adapter = new ToolStripItemCollectionUIAdapter(item.DropDownItems);

    RootWorkItem.UIExtensionSites.RegisterSite(“PluginsMenuBar”, adapter);

}

NOTE: This code will add a new menu item in the main menu strip of the application, with the “Plugins” text, and then add a UIElementAdapter for the DropDownItems colletion of the Plugins menu item, which will be available throughout the whole application.

Finally, right-click the CABPluginApplication project and select Set as StartUp Project.

Once you have done all these steps, just save, compile and run the project. You will see the same “Hello World!” application plus the “Plugins” menu item and, now, in an application context running on CAB! :)

mainApplicationOnCAB

Figure. Outcome: The MainApplication running on CAB.

Next Steps

In the next part, you will create the Message plug-in and get it to work with the CAB plug-in system in a loosely coupled way.

CAB Quickie – The Plug-in Application: The Main Application (Part 2)

 

In this part, you will add the “main application”. It will be a “Hello World!” application that will act as the program you are about to extend using a plug-in system based on CAB.

First of all, you will create a new Windows Application project.

1. Return to the PluginQuickie blank solution and, in Visual Studio, point to Add on the File menu, and then click New Project.

templateProject

Figure. Creating the MainApplication project.

2. In the New Project dialog box, expand the Visual C# node. Click the Windows project type.

3. In the Templates window, select Windows Application.

4. Change the Name to MainApplication.

5. Change the location for the solution to the source folder located inside the PluginQuickie folder.

6. Click OK.

SEMainApplication

Figure. The MainApplication project.

As I wrote in the CAB Quickie – The Plug-in Application: Setting up the development environment post, the bin\Debug folder was created to contain all the built projects, so you need to change the output path of the MainApplication project to this folder. To accomplish this, right-click the MainApplication project (in the Solution Explorer) and select Properties. In the Build tab, go to the Output section and edit the Output path to %PluginQuickieFolder%\bin\Debug.

projectProperties

Figure. Output path in the Output section located at Build tab in the Project properties. Note: you might not see a relative path until you close the properties window and open it again.

After doing this, you’ll start setting up the MainForm:

1. In the Solution Explorer, right-click the Form1.cs file, select Rename, and change the name to MainForm.cs.

2. In the Designer, right-click the MainForm and select Properties.

3. Set the following values to the corresponding properties:

 

Property Value
Size 300, 300
StartPosition CenterScreen
Text MainForm

4. Add a Label to the MainForm with the following values set to the corresponding properties:

 

Property Value
(Name) HelloWorldLabel
Font Arial, 20,25pt, style=Bold
Location 61, 115
Text Hello World!

5. Add a MenuStrip to the MainForm and name it HelloWorldMenuStrip.

6. Add a ToolStripMenuItem in the HelloWorldMenuStrip by typing “&File” in the “Type Here” box, and another one inside the fileToolStripMenuItem (this name is given when the item is added) by typing “&Exit” (which will be named exitToolStripMenuItem).

7. Double-click the exitToolStripMenuItem to generate the code for the handler for the click event of the menu item and add the following code line inside:

Application.Exit();

NOTE: This will close the application when clicking on the exitToolStripMenuItem.

8. Once you have done this, in the Designer, right-click the MainForm, select Properties, and set the MainMenuStrip property to the HelloWorldMenuStrip menu strip.

When all these steps are done, just save, compile and run the project. You will see an ordinary Hello World application. So far, we haven’t seen anything about CAB yet.

mainApplication

Figure. Outcome: The MainApplication.

Next Steps

In the next part, you will add the CAB plug-in application (that will be another Windows Application with references to the CAB assemblies).

CAB Quickie – The Plug-in Application: Setting up the development environment (Part 1)

 

In this part, you will set up the development environment. By this, I mean a blank solution to host all the projects and a folder structure for a cleaner view. I would like to remark that these steps are not a “must have“ (they just provide a neater development environment), but they are a good practice.

First of all, you will create a blank solution to host both the non-CAB application and the CAB plug-in application.

1. Open the Visual Studio, point to New on the File menu, and then click Project.

templateSolution

Figure. Setting up the blank solution.

2. In the New Project dialog box, expand the Other Project Types node. Click the Visual Studio Solutions project type.

3. In the Templates window, select Blank Solution.

4. Change the Name to PluginQuickie.

5. Select the location for the solution (e.g.: your Visual Studio Projects folder).

6. Click OK.

SEBlankSolution

Figure. The initial blank solution.

Now, you will create the folder structure for this solution:

  1. Open the PluginQuickie folder and add three new folders: bin, Lib, and source.
  2. Inside the bin folder add a new folder and name it Debug.

The folder structure should look like this:

folderStructure

Figure. The initial folder structure.

The Lib folder will contain the necessary CAB assemblies, the bin\Debug folder will contain all the built projects, and the source folder will contain the source code.

Finally, to finish setting up the environment, you will add the following CAB assemblies to the Lib folder (just copy the assemblies from the CAB folder to the Lib folder):

  • Microsoft.Practices.CompositeUI
  • Microsoft.Practices.CompositeUI.WinForms
  • Microsoft.Practices.ObjectBuilder

Ok, you are done! You have set your development environment! :)

 

Next Steps

In the next part, you will add a Hello World application (that will only be an ordinary Windows Application) which will play the role of the application we are about to extend using the CAB-fashioned plug-in system.

Next Page »