Placement of creation of toolbars etc.

Topics: CAB & Smart Client Software Factory
Nov 7, 2005 at 9:25 AM
originally posted by: dannytuppeny

Hi all,

I've been looking at the BankTeller QuickStart...

Adding the "Queue" menu is done by the BankTellerWorkItem, which seems fair enough.

However, adding items to the File menu etc., is done in BankShellApplication. Given we have a RootWorkItem, wouldn't it be more consistent to be in there?

My form (at design time) just has an empty toolbar, so it makes sense to me, that the RootWorkItem adds the FileMenu, HelpMenu etc., and then my ModuleWorkItem adds its ModuleMenu.

I've tried moving the code around, but I can't get it to work this way, but I think it makes more sense to be able to say "The menus are added by WorkItems", rather than "The menus are added by WorkItems, except the RootWorkItem. That's an empty class, and all of its stuff is actually elsewhere"!

Does this make sense?

Incidentally, I tried installing the Hands on Labs, but got a message about one of the files being corrupt (it's an MSI, and got about 80% through installing before reporting a non-msi file corrupt). Is this just me being silly, or a known issue?
Nov 11, 2005 at 9:12 AM
originally posted by: PProvost

RE: Menus

It is perfectly acceptable to add those common "application wide" menu items and commands from a custom Root Work Item class. If this didn't work for you, perhaps you could post some code and we can figure out what is going on. It should work just fine.

RE: Lab MSI

You probably got a corrupt MSI. Also once you get a working MSI, make sure you have the right version of CAB installed for the version of the labs you've downloaded. (The current labs only work with the June CTP 1 drop.)
Nov 11, 2005 at 2:08 PM
originally posted by: jburkholder

I could not get it to work in the RootWorkItem also, I had to put them in AfterShellCreated.
Nov 12, 2005 at 12:43 AM
originally posted by: dannytuppeny

I can't test it now, because I have problems :(

http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=2c9eb4a8-5c13-4cec-9913-fd18df871b44

But I believe I was using ServiceDependency to get at the UIServer (in the same way as in other WorkItems) but getting a NullReferenceException.

When I can figure out how to get VC# working again, I'll give it another go and post more info!
Nov 13, 2005 at 11:23 AM
originally posted by: dannytuppeny

Here's the error. I've snipped some of the stack trace because it's too long to post here, but it's pretyt much "BuildUp" methods right the way up from my root WorkItem.Run() method.

---------------------------
Service Microsoft.Practices.CompositeUI.UIElements.IUIElementService is not available in the current context.

at Microsoft.Practices.CompositeUI.Collections.ServiceCollection.Get(Type serviceType, Boolean ensureExists) in C:\Program Files\Microsoft patterns and practices\Composite UI Application Block October 2005 Community Technology Preview\Src\CS\CompositeUI\Collections\ServiceCollection.cs:line 299

at Microsoft.Practices.CompositeUI.ServiceDependencyParameter.GetValue(IBuilderContext context) in C:\Program Files\Microsoft patterns and practices\Composite UI Application Block October 2005 Community Technology Preview\Src\CS\CompositeUI\ServiceDependencyParameter.cs:line 48

<snip>

at Microsoft.Practices.CompositeUI.WorkItem.BuildUpYourself() in C:\Program Files\Microsoft patterns and practices\Composite UI Application Block October 2005 Community Technology Preview\Src\CS\CompositeUI\WorkItem.cs:line 551

at Microsoft.Practices.CompositeUI.CabApplication`1.Run() in C:\Program Files\Microsoft patterns and practices\Composite UI Application Block October 2005 Community Technology Preview\Src\CS\CompositeUI\CabApplication.cs:line 52

at DTuppeny.DwingleNews.ShellApplication.Main() in C:\Data\Projects\WinForms\Dwingle\Source\Dwingle\Dwingle\ShellApplication.cs:line 15
---------------------------
OK
---------------------------

My root WorkItem looks like this:

class ShellWorkItem : DwingleWorkItem
{

public override void Run()
{
base.Run();

base.BuildUpYourself();

AddMenuItems();
}

void AddMenuItems()
{
ToolStripMenuItem helpMenuItem = new ToolStripMenuItem("Help");
uiElementService.Add<ToolStripMenuItem>(UIExtensionConstants.File, helpMenuItem);

AddMenuItem(helpMenuItem, "About", CommandConstants.About);
}
}

And the base class, DwingleWorkItem looks like this (last time, I didn't have this base class, all code was in the root WorkItem directly), so I don't think that's part of the problem:

public class DwingleWorkItem : WorkItem
{
protected IUIElementService uiElementService;

ServiceDependency
public IUIElementService UIElementService
{
set { uiElementService = value; }
}

protected void AddMenuItem(ToolStripMenuItem newsMenuItem, string menuText, string command)
{
ToolStripMenuItem item = new ToolStripMenuItem(menuText);
newsMenuItem.DropDownItems.Add(item);
if (command != null)
{
Commandscommand.AddInvoker(item, CommandEventsConstants.Click);
}
}

protected void AddMenuSeperator(ToolStripMenuItem newsMenuItem)
{
newsMenuItem.DropDownItems.Add(new ToolStripSeparator());
}
}
Nov 14, 2005 at 6:41 AM
originally posted by: dannytuppeny

It seems the depedency injection doesn't work on the RootWorkItem. I fixed it by calling Services.Get<IUIElementService>() in the RootWorkItem, and using the injection for my other workitems.

This works fine, but I've now hit another problem... RootWorkItem.Run() seems to run after my module's WorkItem.Run() (which is called by the overriden Load() method on my ModuleInit class). This means my menus appear in the wrong order - I expected the Root menus to be added, then the modules menus - it seems not.

All of this seems to be because I wanted to keep uielement stuff in the same place (WorkItems, whether it's Root or not). Is this a bad idea? Should I just copy the BankTeller app and move it into the ShellApplication class? Will any of this change dramatically for tomorrow? The walkthrough & docs don't seem to cover this stuff in great detail :-(