-[Danny Chen]- Blog of an ASP.NET QA tester

Tips and info about Site Navigation, ImageMap, Menu and other cool ASP.NET v2.0 features.

November 2005 - Posts

Using Device Filters (and making Menu work with Safari)

Well, as much as I would hate to admit it, there are a few bugs in the Menu control.  For the most part, I'm OK with that.  Some of the bugs are a matter of interpretation and those kind will always exist.  But one really sticks as a thorn in my side. 

  If you specify a DynamicMenuStyle (or LevelSubMenuStyles) on the Menu control, sub menus seem to disappear on "downlevel" browsers.  Well it's really there (if you look at the source) but it's styles make it hidden. 

There are very few workarounds for this bug.

1) Remove runat="server" from <head>
   Cons: HoverStyles are no longer allowed even in rich renderings

2) Remove the DynamicMenuStyle
   Cons: No Dynamic styles allowed even in rich renderings

3) Use device filters to selectively apply styles
   Cons: Still limited in what can be done but uplevel is not affected


note: This bug is being fixed and will eventually be availible through a patch, update, service pack, or etc in the future. Looks like I spoke too soon, this may not get fixed, what you should do instead is see if you can use the CSS Adaptors:  http://www.asp.net/cssadapters/


What are device filters?

Device filters are a somewhat lesser known feature of ASP.NET.  It isn't a feature I actively work with but since there seems to be little information about it, I'll give a brief description of how it works.

In the folder <SysDrive>\Windows\Framework\v2.0.50727\CONFIG\Browsers is a series of .browser files.  These contain some information about every type of web browsing device that ASP.NET knows about.  This information is used for a number of things, among which, choosing whether to render the 'downlevel' menu or the 'uplevel' menu based on which browser is being used. 

Device filters can use the browser information to selectively apply properties to a control depending on which browser is viewing the page.  Here's an example:

<asp:Label runat="server" id="Label1"
  ie:Text="Hello Internet Explorer browser
  Mozilla:Text="Hello Mozilla Browser"
  Text="Hello other browser" />

  This works as you might predict: the IE user gets a message about IE, a Mozilla user gets a message about Mozilla and other browsers, like Opera or Netscape, get the standard message.  One interesting observation is that IE is considered a Mozilla browser.  However, since the IE: filter is more specific, it wins over the Mozilla filter.

  Device filters can only be used declaratively and there is no designer support for them.  The syntax is:  browsername:Property=<value>.  browsername comes from the id field of each recognized browser in the .browsers files.  Any property (that isn't explicitly set as Filterable(false) through an attribute in the control code) can be filtered.  This includes collections and templates:

<asp:Menu runat="server" id="Menu1">
  <ie:Items>
   <asp:MenuItem Text="IE Item" />
  </ie:Items>

  <Items>
    <asp:MenuItem Text="Other Item" />
  </Items>

  <ie:StaticItemTemplate>
     This item is templated only in IE: <%# Eval("Text") %>
  </ie:StaticItemTemplate>

</asp:Menu>

So, can we work around this Menu bug with Device Filters? Kind of.

Ok, so we really can't, but what we can do is limit the damage that any of the workarounds I listed above would do to the uplevel rendering.  After all, they work fine.  The most basic improved workaruond is to recognize that IE 5 and Safari are the two browsers affected by this bug (for some reason Netscape is ok).  So, we could simply not apply a DynamicMenuStyle to those browsers:

<asp:Menu ... >
 <DynamicMenuStyle [my styles here] />
 <Safari:DynamicMenuStyle />
 <IE5:DynamicMenuStyle />
</asp:Menu>

But even better.  It's possible in many cases to produce a less desirable but still functional and styled menu using only DynamicMenuItemStyles. 

<asp:Menu ... >
 <DynamicMenuStyle [my styles here] />
 <Safari:DynamicMenuStyle />
 <IE5:DynamicMenuStyle />
 
 <Safari:DynamicMenuItemStyle ... />
 <IE5:DynamicMenuItemStyle ... />

</asp:Menu>

More Posts