A Dynamic Menu For Your Dynamic Data

So I am still playing around with building a Northwind Dynamic Data web site.  Tonight I thought it would be interesting to see what it would take to create a menu for navigating the tables in the site.  I was particularly interested in seeing if I could get some grouping or categorization to the metadata so I could create a multi-leveled menu.  It turns out it wasn't too difficult at all (see the screen shot below - the menu is on the left).  I have my tables organized into 4 categories: Sales, People, Products and Reports.  And the cool thing is that this menu is completely dynamic.  You can add, remove or reorganize the categories without touching the UI.  And depending where you are keeping your metadata you could even do this without recompiling your app.  The grouping is automatically discovered from the metadata and the menu is built solely off the it so everything 'just works'.

Besides adding the grouping information, I also tagged each of my tables with a custom description that I am displaying under the grids title.  Nothing too complicated, but still interesting.  Read on if you are curious how I did this and don't forget to check out the download.

[Update: 9/21/2008]: Added live demo link   

Download | Live Demo

 image

 

Adding Category and Description

When MetaTable objects are created, the Dynamic Data components automatically populate the the MetaTable's DisplayName property from the DisplayNameAttribute that is hanging off the metadata class (if you are using the default metadata provider).  This is why you see the nice 'Products By Category' title in the screen shot above.  I have specifically told Dynamic Data to use this value because I tagged my metadata class with the DisplayName attribute and given it a value of 'Products By Category'.  Below this metadata ...

   1: [MetadataType(typeof(ProductByCategoryMetadata))]
   2: public partial class Products_by_Category { }
   3:  
   4: [DisplayName("Products By Category")]
   5: public class ProductByCategoryMetadata
   6: {
   7:     [ScaffoldColumn(false)]
   8:     public object Discontinued { get; set; }
   9: }

 

To add a category and description to the metadata, I just used the existing Category and Description attributes and added them to the metadata class as well.  So now we have ...

   1: [MetadataType(typeof(ProductByCategoryMetadata))]
   2: public partial class Products_by_Category { }
   3:  
   4: [Category("Products")]
   5: [Description("You can use this page to view your products by category")]
   6: [DisplayName("Products By Category")]
   7: public class ProductByCategoryMetadata
   8: {
   9:     [ScaffoldColumn(false)]
  10:     public object Discontinued { get; set; }
  11: }

 

The Category and Description attributes don't directly map to any properties on the MetaTable type.  But, any extra custom attributes that are applied to in the metadata are passed through to the Attribute collection that hangs off the MetaTable class.  So with a couple of pretty simple extensions methods I can add them myself (ignoring error handling for now) ...

   1: public static class MetaTableExtensions
   2: {
   3:     /// <summary>
   4:     /// Gets the description for the MetaTable
   5:     /// </summary>
   6:     public static string GetDescription(this MetaTable table)
   7:     {
   8:         return ((DescriptionAttribute)table.Attributes[typeof(DescriptionAttribute)]).Description;
   9:     }
  10:  
  11:     /// <summary>
  12:     /// Gets the category for the MetaTable
  13:     /// </summary>
  14:     public static string GetCategory(this MetaTable table)
  15:     {
  16:         return ((CategoryAttribute)table.Attributes[typeof(CategoryAttribute)]).Category;
  17:     }
  18: }

 

... and now to get at the MetaTable's description or category I can just go through these methods.  So I updated the List template and added a little bit of code that generates a simple title bar generated from the MetaTables DisplayName and Description attributes.

image

 

and now our List pages have a nice dynamic title bar ...

image

 

Building the Menu

To build the menu, I am using a ListView tied to a LinqDataSource that uses a Linq query to create a 2 level object structure that I can bind to.  First, I wired the LinqDataSource's Selecting event to the following bit of code that groups my tables by their category ...

   1: protected void LdsMenu_Selecting(object sender, LinqDataSourceSelectEventArgs e)
   2: {
   3:     e.Result =
   4:         from vt in MetaModel.Default.VisibleTables
   5:         //  use the category to group the tables
   6:         group vt by vt.GetCategory() into groups
   7:         select new 
   8:         {
   9:             CategoryName = groups.Key,
  10:             Tables = groups 
  11:         };
  12: }

 

Then I bound this data source to my ListView ...

image

And that's all it took to build my 2 level menu.  Awesome!

image

 

Conclusion

Can Dynamic Data be used for more than admin screens and prototyping?  I think it might.  What about you?

 

That's it.  Enjoy!


TrackBack

TrackBack URL for this entry:
http://mattberseth.com/blog-mt/mt-tb.fcgi/149

Listed below are links to weblogs that reference A Dynamic Menu For Your Dynamic Data:

» A Dynamic Menu For Your Dynamic Data from DotNetKicks.com
You've been kicked (a good thing) - Trackback from DotNetKicks.com [Read More]

» Links from Evonet Consulting
Links [Read More]

» Dynamic Data VB Style from Jim O'Neil's Blog
Thanks to the New England Visual Basic Professionals User Group for the invitation to speak on ASP.NET [Read More]

Comments


Posted by: Derek J. Klingman on August 28, 2008 06:57 AM

As always another awesome post! Even though I haven't had a chance to play around with the dynamic data yet, these posts about it has me very excited and looking forward to using it for future projects.

Can't wait to read your next post!


"Programming isn't science, it's art!"

Posted by: KJosh on August 28, 2008 07:08 PM

Matt,
Could you please tell me Which tool you are usig to create the images used in the Listview like Listview header images?
Thanks.

Posted by: Andy on September 1, 2008 07:37 AM

Great ideas here that I'll certainly be using. The MetaTableExtensions and LINQ query against the metadata are very elegant.

Nice. Thanks for writing this article. Very helpfull

Posted by: Rudolf on October 28, 2008 01:09 PM

hi matt,
beautiful idea with a left side Listview.
Do you have an idea this inside a horizontal menu in one
menueItem?
Rudolf from Germany

I like your design and would like to implement it but when I downloaded your example, it did not have a project file, and it did not appear to have anything going on in the Default.aspx

?

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Consulting Services

Yep - I also offer consulting services. And heck, I'll do just about anything. If you enjoy my blog just drop me an email describing the work you need done.

Recent Comments

  • Bill Ross wrote: I like your design and would like to implement it but when I downloaded your example, it did not hav...
  • Rudolf wrote: hi matt, beautiful idea with a left side Listview. Do you have an idea this inside a horizontal menu...
  • Celik wrote: Nice. Thanks for writing this article. Very helpfull...
  • Andy wrote: Great ideas here that I'll certainly be using. The MetaTableExtensions and LINQ query against the me...
  • KJosh wrote: Matt, Could you please tell me Which tool you are usig to create the images used in the Listview lik...
  • Derek J. Klingman wrote: As always another awesome post! Even though I haven't had a chance to play around with the dynamic ...