Silverlight: Dropdown Menu Control
In a previous post I showed how we can build a simple menu control for Silverlight 2 Beta 2 (Silverlight: how to build a simple menu control); then with the release of Silverlight RC0 some things were changed and the menu stopped working, due to how events are handled for disabled controls (Silverlight 2 RC0 – first problems due to undocumented breaking changes on disabled controls).
The only way to overcome these problems was to completely rewrite the control, I also took advantage of this to implement some more features, such as the possibility to have nested menus and a better support for skinning through styles.
Here’s what we want to obtain:
The new dropdown menu is now composed of 4 different controls:
- MenuBar: a container for the menu, it only supports horizontal placing of elements right now.
- MenuPanel: a control that provides the frame in which the menu items are displayed (for styling purposes).
- MenuItem: the base class for a single menu item, it can contain a list of menu items (to support nested menus).
- MainMenuItem: the class that ‘describes’ a menu item that belongs to the MenuBar, it keeps a list of Menu Items.
The MenuItem control is still based on the Button control, but instead of having it placed in a xaml file alongside a grid, this time we derive the new control from the Button class. This way the control can be skinned using the standard way with templates.
The MainMenuItem derives from MenuItem and overrides some internal members.
The previous PopupProvider class was renamed MenuPopupProvider and modified to handle special cases related to the way the popup windows of chained menus are closed when the user clicks on menu items or when he moves the mouse outside the menu itself; with the current modification this class is no more a generic popup handler but it’s became specific for this menu control.
The two major changes were made to the ClosePopup() function, which now has to take into account the fact that we cannot close a menu if there’s a submenu opened and also, if the closing of the current menu is confirmed, it has to forward the closing request to the parent menu (if there’s any).
1: private void ClosePopup()
Silverlight: simulate a ‘Windows’ desktop application - part 2 (Dragging Window)
With the release of Silverlight RC0 it was finally time to update this sample application. Let’s now go on with the tutorial and take a look at how the dragging capability of the Window is implemented, you can state if you want to enable or disable the dragging feature for an instance of the control simply by setting the ‘DraggingEnabled’ property.
All the code is encapsulated in the “Dragging functions” region, the Idea is quite simple, we will subscribe to the MouseLeftButtonDown, MouseMove and MouseLeftButtonUp events and handle the stuff from there:
- MouseLeftButtonDown : here we capture the mouse, then we take note of the current Window position and the position where the user clicked (this value will be used to compute the offset of the movement). In the end we set the internal status variable that states we are inside a dragging operation.
Silverlight, Pluggable Architectures, Composite Applications and future plans…
The new project my small company is working on is quite interesting…since this will be our first ‘real’ application developed in .NET 3.5 we evaluated the possibility to develop the whole application as a web application due to the new possibilities offered by the environment.
The hard task is mainly that we need to develop it as a composite application to have the possibility to ‘inject’ new blocks of functionality when the users ask for them, also separate the application in small blocks make our life a little easier.
I will not go into detail of how composite applications works cause you can already find a lot of good sources of information on the web.
Why use Silverlight instead of..lets say Flash? well we made a preliminary check of all the ‘coolest’ feature we needed and we made some simple test projects to see if they could be doable as a web app (it took some time yes), stated that..we made a simple consideration…since we are not yet 100% sure we can make it all (you never know what your users will ask to you in the future) we decided to try Silverlight simply cause if the project is well structured you can easily build a safe WPF application for the UI interaction.
Spoke like that it seems an easy task to do…but believe me it’s not, so the first thing to do is look around for some framework that can you along the way, I knew it existed a ‘Composite Application Guidance for WPF’ from the P&P team (codename PRISM) and some days ago they released new version which start to have Silverlight support too (see http://www.pnpguidance.net/Post/Prism2Drop1CompositeWPFSilverlightApplicationGuidancePatternsPractices.aspx for details).
Actually they are introducing multi-targeting…that is structuring the project to isolate the completely the business code from the presentation code so you can easily have multiple UIs for the same application…PERFECT just what I needed…the only drawback is that the whole project still uses SL2B2 :) however I’ll give it a shot for sure to see if it completely fits my needs (hoping to not have to convert too many things).
The second point to note is that a Silverlight application can become quite huge fast and it’s not very good to force the users to download all the modules during the startup (even the ones they do not use or the ones they’ll use at a later time), the first version of composite application for Silverlight (you can still get the source code from Codeplex as a spike from the main project) used the Unity IoC container to obtain the modularity, but didn’t supported the ‘deferred loading and registration of types’. That is you still had to download the whole application at start.
So In the past days I was working on a wrapper over the default Unity IoC Container to add support for delayed download of assemblies and ‘deferred registration of types’, the goal is obtain a generic IoC layer (with the ability to swap the default container, cause sooner or later Spring.NET or Castle Windsor will also offer a Silverlight solution, NInject is also a good project, at that point one will choose the one he loves most) that is able to register Types from already downloaded and available assemblies so the types can be directly created, and to store the registration of types in assemblies that have to be downloaded in some internal structures.
In this way when the code ask for a type the container is not able to create, we start download the related assembly, load it into the runtime, proceed to register the type into the IoC container, and finally we use the IoC to instantiate the type, all the next requests of the same time do not require to download the assembly (or the xap containing it) anymore. All of it it completely transparent to the caller which only ask the Container Wrapper to resolve a type. I call this process ‘deferred downloading and registration’.
A basic version of this IoC wrapper with limited configuration functionality (it’s still too much tight coupled to Unity yet) is ready so expect an article ‘soon’.
In the end I just want to thank the P&P team for their effort and Michael Sync for the porting of Unity to Silverlight.
Related Content
- Silverlight, M-V-VM ... and IoC - part 1 (26/08/2015)
- Silverlight, M-V-VM … and IoC – part 2 (26/08/2015)
- Silverlight, M-V-VM ... and IoC - part 3 (26/08/2015)
- Silverlight Navigation Framework: resolve the pages using an IoC container (04/08/2010)
- Structura (Alpha version) a Silverlight/WPF Line of Business Application Framework (26/08/2015)
- More related document (43)
Silverlight 2 RC0 – first problems due to undocumented breaking changes on disabled controls
Yesterday I was about to use my brand new menu control in a new project, and after having recompiled and run the test with the brand new runtime…well…as usual the first problems arose.
It seems that some undocumented changes were made again to the event bubbling and mechanics…so when I was moving the mouse over some disabled menu items I saw the whole popup disappear.
The problem is caused by the fact that the menu is implemented like a bunch of buttons inside a StackPanel, the popup is closed when the MouseLeave event of the StackPanel is fired; with SL2RC0 when I move the mouse over a disabled button the StackPanel fire an ‘unwanted’ MouseLeave event too…this behaviour wasn’t present in SL2B2.
For some more info look at my post in Silverlight Forum: http://silverlight.net/forums/t/30778.aspx
The ‘Breaking Changes’ document doesn’t mention anything about the ‘new’ event system, so we are left alone and have to experiment a bit.
I have a workaround for this in mind but it will require a complete rework of the Menu Control, stay tuned for updates.
Related Content
- Silverlight: Dropdown Menu Control (10/07/2008)
- Silverlight: How to Add a Context Menù to a FrameworkElement (26/08/2015)
- Silverlight: how to build a simple Menu Control (26/08/2015)
- Silverlight Pagination Control – bug fixed (26/08/2015)
- Silverlight: simulate a 'Windows' desktop application - part 1 (26/08/2015)
- More related document (42)
Silverlight 2 RC0 Available
Finally we have new update of the runtime and of the development tools that will bring us closer to the final release, for more info:
http://silverlight.net/GetStarted/sl2rc0.aspx
I’ll start to convert all my projects this afternoon, note that this update is devoted to developers only the runtime will not be available to all users yet by the automated installation process, you have to install it manually :D
Related Content
- Silverlight 2.0 RTW silently released (26/08/2015)
- Silverlight Datagrid Updated (01/12/2009)
- Last few days to sign up for the 12th DotNetMarche / Community Tour 2009 workshop (26/08/2015)
- Getting ready for the 12th DotNetMarche Workshop “Community Tour 2009” (12/03/2009)
- Workshop: ‘Silverlight in Action - a starting point for Line of Business Applications’ (26/08/2015)
- More related document (41)
Silverlight: how to build a simple Menu Control
In my current project I needed to use a dynamic Menu Control (a completely declarative approach hardcoding the structure in XAML wasn’t a good fit for my application cause I need to dynamically add, remove, enable and disable menu items). Since Silverlight doesn’t support a menu control yet I had 3 options:
1- look for a 3rd party component (which actually can be an expensive solution if you need only a single control)
2- look around the web to see if there’s something free to use as a starting point
3- build it from scratch.
I tryed the way number 2 first but I wasn’t able to find anything, so I gathered some information and started to build it from ground up.
Control requirements:
1- a basic menu control which will expose Add() and Remove() functions to manage menuitems.
2- the menu will be hosted in a menu bar control which will display the menu items in an horizontal fashion, each ‘level 0’ menu can have sub items (that is the drop down with some menu items in it), a sub menu cannot have children (yet).
Here’s the final result at this stage:
Let’s have a look at the solution.
The final control is actually composed of 3 XAML files and 2 support files:
- MainMenu.xaml – contains the definition of the menu bar that will host all the ‘Level 0’ menu items, actually it’s nothing more than a stackpanel with horizontal orientation.
- Menu.xaml – contains the definition of Menu Items hosted in the MainMenu control, the menu is actually just a button contained in a Grid, its template was completely redefined using blend to obtain a more ‘flat’ appearence.
- SubMenu.xaml – contains the Menu Items that can be nested in a Menu control, again it’s a simple button with its template redefined.
- PopupProvider – defines the class that manages the popup menu display logic, the original code was taken from Chuck Kinnan article (http://www.codeproject.com/KB/silverlight/Silverlight_Popup_Logic.aspx); some fixes were made to it.
- MenuSupport – contains interfaces declaration and some support classes.
Going on a complete code analysys is beyond the scope of this article, mainly cause it’s extremly simple to follow, so just focus on why we made soem choices:
We have different classes for ‘Level 0’ and ‘Level 1’ menu items cause we need different graphical representation for them, this way we leave some room for customize it.
Why use buttons: mainly cause they already support all the state needed by a menu: normal, hover and pressed state (some states were removed like the focus ones).
The menu is actually displayed using a Popup which contains a StackPanel with vertical orientation, both the Popup and the StackPanel are created by code in the AddMenu() function exposed by the Menu control for two reasons: 1- to save resources (if a menu do not have childern it’s useless to create them); 2- it seems there’s a bug of some sort in how the silverlight runtime manages the Popups, if they were declared in Xaml, with a name given to them, and you dynamically adds the controls to the bar when you try to open 2 or more popups at the same that have the same name (even if they have different parents in the visualization tree) you get an exception, this doesn’t happens if you create the controls by code.
here’s the AddMenu() function