Listing 1

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.WinForms;

namespace ListManagerShell
{
    /// <summary>
    /// This class inherits from CompositeUI.WinForms.FormShellApplication.
    /// The two types that are specified on initialization
    /// are the type of the WorkItem and the shell windows form.
    /// </summary>
    public class ShellApplication : FormShellApplication<WorkItem,ShellForm>
    {
        /// <summary>
        /// The default static void Main() method for a Windows Forms application
        /// </summary>
        [STAThread]
        static void Main()
        {
            // Create a new instance of this class and call the Run method
            // inherited from the base class.
            new ShellApplication().Run();
        }
    }
}

Listing 2

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.SmartParts;

namespace ListOrganizerModule
{
    public class ListOrganizerWorkItem : WorkItem
    {
        /// <summary>
        /// Override of the default Run method
        /// </summary>
        /// <param name="workspace">The workspace
        /// in which the module is to be shown</param>
        public void Run(IWorkspace workspace)
        {
            //Add a new instance of the SmartPart to the workspace
            workspace.Show(Items.AddNew
			<ListOrganizerListBox>());
        }
    }
}

Listing 3

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.CompositeUI;

namespace ListOrganizerModule
{
    /// <summary>
    /// Inherits from ModuleInit, which is the
    /// default implementation of IModule
    /// </summary>
    public class ListOrganizerInit : ModuleInit
    {
        //Private member to hold the parent work item
        private WorkItem _parentWorkItem;

        //Public property to hold the parent work item.
        //The ServiceDependency attribute tells CAB to
        //initialize the value of this property at runtime
        [ServiceDependency]
        public WorkItem ParentWorkItem
        {
            set { _parentWorkItem = value; }
        }
		public override void Load()
        {
            //Call the base class load method
            base.Load();

            //Create a new instance of the local WorkItem
            //using the generic factory on the parent WorkItem's
            //WorkItem collection
            ListOrganizerWorkItem _workItem = _	
			parentWorkItem.WorkItems.AddNew
			   <ListOrganizerWorkItem>();

            //Call the overload of Run that takes in the parent
            //workspace as a parameter. This will inject our
            //control into the specified workspace.
            _workItem.Run(_parentWorkItem.Workspaces
			["navigationWorkspace"]);
        }
    }
}

Listing 4

<?xml version="1.0" encoding="utf-8" ?>
<SolutionProfile xmlns="http://schemas.microsoft.com/ pag/cab-profile" >
	<Modules>
	   <ModuleInfo AssemblyFile="ListOrganizerModule.dll" />
	   <ModuleInfo AssemblyFile="ListViewerModule.dll" />
	</Modules>
</SolutionProfile>

Listing 5

<?xml version="1.0" encoding="utf-8" ?>
<Lists>
	<List name="Grocery">
		<Item name="Milk"/>
		<Item name="Cereal"/>
	</List>
	<List name="Auto Parts">
		<Item name="Spark Plugs"/>
		<Item name="Oil Filter"/>
	</List>
</Lists>


Listing 6

private void ListOrganizerListBox_Load(object sender, EventArgs e)
{
    //Create a new untyped DataSet
    DataSet dataSetLists = new DataSet();

    //Load the xml file into the DataSet
    dataSetLists.ReadXml("Lists.xml");

    //Bind the DataSet to the ListBox and set
    //display and value properties
    listBoxLists.DataSource = dataSetLists.Tables["List"];
    listBoxLists.DisplayMember = "name";
    listBoxLists.ValueMember = "List_Id";
}

Listing 7

[EventPublication("topic://ListOrganizer/ListSelected")]
public event EventHandler<DataEventArgs<string>> ListSelected;

private void listBoxLists_Click(object sender, EventArgs e)
{
    //Get the name of the selected list
    string _selectedList = listBoxLists.SelectedValue.ToString();

    //Call the EventHandler delegate, passing in the list name
    ListSelected(sender, new DataEventArgs<string>(_selectedList));
}

Listing 8

[EventSubscription("topic://ListOrganizer/ListSelected")]
public void OnListSelected(object sender, DataEventArgs<string> args)
{
    //Create a new untyped DataSet
    DataSet dataSetList = new DataSet();

    //Load the DataSet from XML
    dataSetList.ReadXml("Lists.xml");

    //Select the items for the specified list into a DataRow array
    //based on the parameter
    DataRow[] _rows = dataSetList.Tables["Item"].Select
	("List_Id = '" + args.ToString() + "'");

    //Convert the DataRow array into a DataTable for binding by name
    DataTable _dt = dataSetList.Tables["Item"].Clone();
    foreach (DataRow _row in _rows)
    {
        _dt.ImportRow(_row);
    }

    //Bind the ListBox to the DataTable
    listBoxLists.DataSource = _dt;
    listBoxLists.DisplayMember = "name";
}