Welcome to The Digital Lifestyle and Media Center Show Sign in | Join | Help
in Search
mControl for Windows Media Center

The Digital Lifestyle Developer Blog

Windows Media Center development hints, tips, tutorials and information

Control Interaction - Menu's and Sub-Menus, using Invoke

Although this really isn't really very difficult from what's been explained before, some people have trouble with getting their controls to interact - to change one control based on another.

So I thought I'd spend a little time covering the basics, so that people who are having trouble can get a walk-through of how to do it.

The most common problem is in making a list of items appear based on the state of another list of items. A simple example of this is the menu in a program (press 'ALT' if you are using IE7 and you'll see what I'm talking about).

In this case, we have two menus - the contents of the sub-menu depends on what is selected in the main-menu.

 

Well, in previous blog posts we have already seen how to load an on-screen list using a Repeater in MCML and a Choice in our C# object. So all we need to do now is extend it slightly to involve TWO repeaters, and TWO Choice objects, then link them together.

So let's say we have to Choice objects, once called MainMenu and the other called SubMenu.

To display these on the screen, we need to create the UI's for the Repeater/Scroller combination (with the ScrollingData and ScrollingHandler of course, so we can handle the scrolling correctly - see the earlier blog posts if you don't quite follow).

So we have our MainMenuUI and SubMenuUI, which are the UI's containing our scroller and repeater. Now we build two UI's for the objects within the scrollers - let's call them MainMenuItem and SubMenuItem.

We give these Item UI's a property called Label

<Properties>

   <cor:string name="Label" cor:string="$Required"/>

</Properties>

 

 So, we have the following layout...

Base Item

   MainMenuUI

       MainMenuItems...

   SubMenuUI

        SubMenuItems

 

And finally, we load both items from our C# code - filling the ArrayListDataSets.

 

But - what about making them work WITH eachother? Well, that is done - like ALL communication between UI elements in MCML - via shared properties.

Now there are a variety of ways to do the next part of our task. I'm going to show you a simple method that will work both with and without a Choice object being used to load the data - this way, if you ever need to replicate this situation with a FIXED list of items, you'll still know how it's done. But just to cover the options, you could...

   * Make your own subclass of Choice and use it instead of normal Choice objects for the content of your main menu. By overriding the OnChosenChanged member of the Choice class, your code will be automatically called whenever the ChosenIndex of the Choice object is changed.

   * Make a Command object that is Invoked when a menu item is selected. By setting the description of the Command object to the Label of the MainMenuItem, you can then communicate not only that the selection has changed, but what the new selected item actually IS. Note that to make this work, the Command object must be shared between all of the UI components - it would be a property of the Base Item, and passed as properties through to all other UI elements.

   * Invoke a function on your main class (which is what I'll be showing you).

 

So, we will be doing the last - and probably the simplest - of the techniques. The other methods also have their uses - the first one is completely seamless when done correctly and requires virtually no code on the MCML side, while the 2nd one is perfect if your C# code is not actually involved in the loading of more information (eg. if you are switching between fixed lists by changing the Visible property on sub-menus) because it's entirely contained in MCML, with no code on the C# side.

This technique requires both C# and MCML code, but is a little more intuitive.

 

Let's say our main class (the ModelItem class we do most of our C#->MCML interaction with) is called MainClass. What we can do is add a new member function, called NewMenuSelected.

public void NewMenuSelected(String MenuName);

 

This function takes a single parameter - the name of the menu that is currently selected. It just so happens that our UI already has a property called Label, which is the name of the menu. So all that is left is to get our MainClass object to the SubMenuUI. This means that both the SubMenuUI and SubItem elements need a property...

 

<Properties>

   <a:MainClass name="MyClass" a:MainClass="$Required"/>

</Properties>

 

So now, when our MainMenuItem objects get the focus, we want it to call our function....

<Rules>

   <Condition Source="[Input.KeyFocus]" SourceValue="true">

       <Actions>

          <Invoke Target="[MyClass.NewMenuSelected]" ManuName="[Label]"/>

       </Actions>

   </Condition>

</Rules> 

This means that when our MainMenuItem gets the focus (meaning that it is the active menu we want to see) then we call our C# or VB object and load the new contents of our SubMenu.

public void NewMenuSelected(String MenuName)

{

   _SubMenu.Clear();

   switch (MenuName)

   {

       case "File":

          _SubMenu.Options.Add("Open");

          _SubMenu.Options.Add("Save");

          _SubMenu.Options.Add("Save As");

          break;

       case "Edit":

          _SubMenu.Options.Add("Copy");

          _SubMenu.Options.Add("Cut");

          _SubMenu.Options.Add("Paste");

          break;

   }

   FirePropertyChanged("SubMenu");

}

 

So hopefully you've seen how these objects can be combined to control the contents of one repeater with another.

Published 19 December 2007 08:14 by IgnoranceIsBliss
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required
Submit
mControl for Windows Media Center
Powered by Community Server (Personal Edition), by Telligent Systems