Is this FireBug for IE?

by Bobbi Perreault 22. September 2008 22:11
Share on Facebook

Nikhil Kothari's tool here, may be what we need to be able to work with IE like we can work in FireFox when using FireBug.  Here's what he says about it:

"Web Development Helper is a free browser extension for Internet Explorer that provides a set of tools and utilities for the Web developer, esp. Ajax and ASP.NET developers. The tool provides features such as a DOM inspector, an HTTP tracing tool, and script diagnostics and immediate window."

I'm going to check it out, and I hope it helps. 

Web Development Helper

Tags:

menu in html and silverlight

by Bobbi Perreault 12. September 2008 22:27
Share on FacebookDemo source links (big download warning)

Links to this demo project, which is created from MVC Storefront -  (Updated:  link to the demonstration page)

MVC Storefront. is an ecommerce demo and is a perfect starting place for Silverlight enhancement - you can get help for MVC Storefront here:  http://www.codeplex.com/mvcsamples

This html/silverlight demo is built as it is to enable the site to conform with a Web standards-based approach. On the UI layer, conforming to Web standards means 100% separation of presentation from content and structure, as well as the scripting behavior of UI elements. On the back end, this means limiting the mixing of UI code in the Web applications and CMS code that may need periodic updates, it means applying the same strict separation as to any other static screen.

There’s a fine line here, at the same time we need to avoid the appearance of "cloaking".  "Cloaking" is the tactic of detecting search engine spiders when they visit and varying the HTML code specifically for the spiders in order to improve rankings. This is only acceptable in a very limited use: namely, as a way of simplifying search engine unfriendly links. If you are in any way selectively modifying the page content, this is nothing less than a bait-and-switch. Search engines have undercover spiders that masquerade as regular visitors to detect such unscrupulous behavior.

In this demo, The Silverlight control will be responsible for both retrieving it ‘s content from the server as well as hiding the indexable content using CSS. By having the Silverlight menu hide the indexable menu we have just solved the problem of how to know if the user has Silverlight Installed and how to know if the user has Javascript enabled.

Let’s look at the Silverlight project: I’m going to start off by opening an mvc project that I downloaded from Codeplex, the MVC Storefront. This is an ecommerce demo and is a perfect starting place for Silverlight enhancement.

The requirements for the menu are this:   If the client doesn't support Silverlight ( bots, clients who  haven't installed it yet, older browsers, etc.)  - keep the page in pure html. If the client does support Silverlight, load this menu from the exact same source that the MVC view menu is using.

As stated previously, the Silverlight control is constructed in such a way that it will – if created – retrieve it’s contents from the server and after formatting it’s self – hide the html version. Once we have our Silverlight, we don’t really give control back to the html and that avoids any further delays to the user.

Let’s look at how this is setup. Here is the MVC Storefront application. Let’s have a really quick overview of how an MVC app is constructed. First, Global.asax file has code in application startup to assign controller classes to specific urls. All the controller files are located in folder: Controllers. When a request for one of the assigned urls is received at the server, that controller is called along with the default action. In our case, the MVC storefront default page goes into the CatalogController,and uses the function of Index. Index method will gather the menu details into a list of type CatalogData and pass that list over to the View also called Index - which will use that data to present the user page. All the view files are located in the folder called View. So, we can find our Index view in folder View/Catalog/Index.aspx. Index view renders a control called CategoryList.ascx which presents the CatalogData list in the form of an html menu. Here’s what this page looks like.

<div id="sl-categoryNavigation" ></div>
<div id="categoryNavigation" class="categoryNavigation">
    <%foreach (Category parent in ViewData) { %>
    <h3><%=parent.Name %></h3>
    <ul>
        <%foreach (Category child in parent.SubCategories) { %>
        <li>
        <%=Html.ActionLink<CatalogController>(x=>x.Index(parent.Name,child.Name),child.Name) %>
        </li>
        <%} %>
    </ul>
    <%} %>
</div>

View the source of this MVC page, and you’ll see clear, clean html. No mangled ID’s. No ViewState.  When this page loads, this Index.aspx view, there is some javascript contained in an included file that comes into play. The javascript is contained in an included file to preserve the separation of presentation from content and structure. This script is is executed when the page is ready. The file is called menu.js, and it uses JQuery to simplify scripting.

We’ll see that in great detail in our next demo. For this demo, we’re going to skip that part and get right to the Silverlight.

What we’re interested in here is in how this Silverlight menu can be created from the same source as the html menu. That saves me as the programmer from a lot of maintenance during the life of this application.

Let’s look at the Silverlight control first. In our Silverlight project there’s a control called menu.xaml. In menu.xaml we have a Grid which contains a StackPanel which contains a ListBox. There is a template applied to the ListBox which enables another ListBox to be embedded within. All this xaml is written in such a way so as to make it skinnable.

We’re going to skip over the part where this Silverlight control contacts the server for it’s menu details and save that for later. Right now, we’ll look at what happens when fully formatted web.sitemap xml is ready to be turned into a menu. Here’s what the web.sitemap this control works with looks like.

<?xml version="1.0" encoding="utf-8" ?>
<siteMap >
<siteMapNode>
    <siteMapNode url="" title="Apparel" description="Apparel" menugroup="Apparel" itemType="menuTitle"  >
          <siteMapNode url="/store/Apparel/Boots" title="Boots" description="Boots" menugroup="Apparel" itemType="menuItem"  />
           <siteMapNode url="/store/Apparel/Hats" title="Hats" description="Hats" menugroup="Apparel" itemType="menuItem"  />
           <siteMapNode url="/store/Apparel/Sunglasses" title="Sunglasses" description="Sunglasses" menugroup="Apparel" itemType="menuItem"  />
         </siteMapNode>
...
    <siteMapNode url="" title="Featured Items" description="Featured Items" menugroup="Featured Items" itemType="menuTitle"  >
          <siteMapNode url="/store/Featured Items/All Items" title="All Items" description="All Items" menugroup="Featured Items" itemType="menuItem"  />
         </siteMapNode>
</siteMapNode>
</siteMap>

This data is passed into the code behind of menu.xaml first as a string. (open the menu.xaml.cs file and move to method setMenu())

In the setMenu method,

I’m going to build some business objects to represent the Silverlight menu and I’m going to use  LINQ over Xml ( Xlinq  )

One thing I ran into while working with LINQ over Xml that I’ll just mention real quick and that is: namespaces can complicate the code. And in my case, since it was my site map, talking to my server, I just removed the namespace which was in the first node.   This saved me from writing some code to match namespaces.

To get the Xdocument to load up in my Silverlight control from my Sitemap XML,  I created two new Business Object classes in my project.  The first class represents a SiteMapNode.  The second class represents a MenuGroup.

Here’s what the LINQ looks like which is going to parse the XML into an IEnumerable list of my sitemap objects, which are the menu items. Use the XDocument.Parse to get my xml string into an XDocument. And then I’m going to select from xdoc.Decendentants(“siteMapNode”) new SitemapBO objects – and load em up right there. The url property is assigned from the sitemap attribute “url”. The title is assigned from attribute title, and so on.

The sitemapbo class, which we have just made a list of is just a property bag which stores and organizes my XML for me.

SiteMapBO.cs:

public class SiteMapBO
    {
        public string url { get; set; }
        public string title { get; set; }
        public string description { get; set; }
        public string menugroup { get; set; }
        public string itemType { get; set; }
    }

XLINQ:

xdoc = XDocument.Parse(sitemapXML);

IEnumerable<SiteMapBO> menuitems = from menuitem in xdoc.Descendants("siteMapNode")
               select new SiteMapBO
               {
                   url = (string)menuitem.Attribute("url"),
                   title = (string)menuitem.Attribute("title"),
                   description = (string)menuitem.Attribute("description"),
                   menugroup = (string)menuitem.Attribute("menugroup"),
                   itemType = (string)menuitem.Attribute("itemType")
               };

Once I have this list of sitemapbo objects, I still need to organize it into a list of MenuGroup objects.

How I format the menu using "menuItem" and "menuTitle" of the sitemap.

What I want is to have my menu titles to be independently skinnable from my menu items.  It gives me freedom, I can make my menu look special because I can touch each type of object within it with a skin. I have the ability to make this Silverlight something special and That's what the MenuGroups class is for.  After getting a list of SiteMapBO's from the Xdocument, in the olden days, I would then re-traverse the list to load a new IEnumerable list of MenuGroups - and this is the list that gets bound to my ListBox.

Today, I’m able to do this using LINQ to Objects.

MenuGroup class consists of a Title property , and a list of SiteMapBO’s.

MenuGroups.cs:

public class MenuGroups
   {
       public string title { get; set; }
       public List<SiteMapBO> itemsList { get; set; }

       public MenuGroups()
       {
           itemsList = new List<SiteMapBO>();
       }
   }

 

Here’s the code that will load the list which will become my ItemsSource of the menu ListBox  using LINQ to Objects, Framework V3.5:

List<MenuGroups> menus = new List<MenuGroups>();
if (menuitems.Count() > 0)
{
    foreach (var menugroup in menuitems.Where(grp => grp.itemType == "menuTitle"))
    {
        MenuGroups mnu = new MenuGroups();
        mnu.title = menugroup.title;
        mnu.itemsList = menuitems.Where(p => p.itemType != "menuTitle" && p.menugroup == menugroup.menugroup).ToList();
        menus.Add(mnu);
    }
    this.MenuList.ItemsSource = menus;

    //the object is ready to show itself - this is javascript call.
    HtmlPage.Window.Invoke("showSlMenu");
    //here, we'll show ourself with an animation
    this.showMyself.Begin();
}

Ok, at the end, then, when I’ve finished building the list of MenuGroup objects, I just set the ItemsSource of the MenuGrid Listbox to this list, menus. And the Styling takes care of the rest of it – that’s it, we’re done.

This is how I build this Silverlight menu control so that it is skinnable and that way I can re-use it in different projects.

In the XAML, notice that this solution allows for individual formatting of the header and the items.

This is the menu: (a stackpanel which contains an image and a listbox.)

<StackPanel x:Name="MenuGrid" >
<Image Source="images/bdlogo.png" Stretch="Fill"/>
<ListBox x:Name="MenuList" Style="{StaticResource menuTitleStyle}" >
</ListBox>
</StackPanel>

 

The listbox name is Menulist, and it’s styled with a StaticResource, menuTitleStyle. The menuTitleStyle is contained in the top of the XAML file, inside the UserControl.Resources section.

Here is the menuTitleStyle:

   It has an Item Template which contains a TextBlock and a ListBox. The TextBlock is using databinding to set it to the MenuGroup property, Title. And the ListBox is databound to the itemsList property of that menugroup.

<Style TargetType="ListBox" x:Key="menuTitleStyle" >
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding title}"
Style="{StaticResource menuTitle}" />
<ListBox ItemsSource="{Binding itemsList}" SelectionChanged="MenuList_SelectionChanged"
Style="{StaticResource menuItemsStyle}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

So, to finish this piece I need to discuss how the Silverlight menu replaces the html menu. While the Silverlight menu is getting it’s xml, formatting it’s xml, putting it’s face on – it’s not visible on the web page. Once it’s ready there is a line of code here that runs a javascript which is linked to the web page. Here’s the line of code that executes the javascript, which will take care of sizing the div which contains our Silverlight control to place it over the top of the Html control (this is a modified version of CSS Image replacement technique)

//the object is ready to show itself - this is javascript call.
HtmlPage.Window.Invoke("showSlMenu");

Following this line is the animation (Silverlight) which fades in the new menu.

//here, we'll show ourself with an animation
this.showMyself.Begin();

Let’s look at showSLMenu in the file menu.js file

First, in this SLMenu function we get the width and height of the html menu.

Then, The div which holds the Silverlight control is then resized to match the original menu. In our css, we’ve set the z-index property of this div very high which will position it over any html content with a lower z-index.

And lastly, the Silverlight contol’s opacity is brought from 0 to 100 which fades it into place.

Show Multiple Silverlight Controls in the Same Page with jQuery

by Bobbi Perreault 10. September 2008 08:02
Share on Facebook

This is an updated version of an older post - and at the bottom is a link to the entire eCommerce demo project that I used for my MDC presentation.  I'll write more about the rest of the MDC demos later.

As I’ve already mentioned, I'm an advocate for using Silverlight in moderation - keeping the web WEBBY. I'm also one very excited Silverlight programmer. That's why I use islands of Silverlight in my html pages instead of one huge monolithic Silverlight application that takes over the entire experience.

I’ve developed a method which I think will enable me to show those clients who are capable of enjoying a Rich Internet Application experience a Rich Internet Application and at the same time, if my visiting client isn’t going to be able to use the RIA, it’s not sent down at all.

I deal with this situation by loading the Silverlight controls upon request using an AJAX request that will retrieve and load the Silverlight control when the document is ready (the document is ready when the required elements are loaded). I'm using jQuery for this.  It makes my life easy. If you haven’t heard of jQuery it’s a javascript framework that makes manipulating the Document Object Model (DOM ) as easy as calling out a CSS selector.

jQuery makes it very easy to retrieve the html that will load a beautiful Silverlight menu up.  And To keep presentation separate from content, I put this in an external javascript file, which is menu.js, and link to it in the html of the page.

<script src="/Scripts/menu.js" type="text/javascript"></script> 

This Silverlight control loading process consists of:

  • Request the html snippet which is the html object element that will name the Silverlight .XAP file.
  • Replace two tags within the html with the proper values.
    • o tag 1 is the server path to the silverlight control. it is in the html snippet as [path] and is replaced with the proper path
    • o tag 2 is the control parameters - controlid is used by app.xaml to identify which control to show. Any other parameter needed by the current control is also placed into the object html at this time by using the format: "ControlId=4,ExtraParam=...." where ExtraParam will be that parameter whatever it's called and it's value will follow. (maybe a guid for an id ) the text that is replaced in tag2 is [initparams]
  • · insert that html is into a div within the document - at which time the Silverlight control is created

In menu.js, the contents of the javascript function that take care of loading Silverlight if javascript is enabled in this user’s browser is:

$(document).ready(function () { 
//fetch the silverlight menu and plug it in, it's controlid #1
$.get('/Content/sl.htm', function(data){
setSilverlight(data, 'ControlId', 1, '');})
});

The document ready function is JQuery’s way to let you attach to the onload event of the window. And what it does is wait for all the elements your javascript needs to load. It doesn’t necessarily wait for the whole page to be loaded and when these elements are present, it executes your named function. Document ready is chainable. So you can have your Document Readys ALL over the place and they will just keep adding on to each other. They don’t replace each other. So one document ready in one file and a document ready in another file are going to complement each other.

The contents of the file that we’re going to be retrieving in this AJAX request is html and it is the <object> element that loads the Silverlight object. Here’s the sample.

<object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="100%" height="100%">

<param name="source" value="[path]"/> 
<param name="onerror" value="onSilverlightError" />
<param name="initparams" value="[config]" />
<param name="windowless" value="true" />
<param name="background" value="#00000000" />
</object>

I have a couple of variables in this html that I can replace in the javascript which enables this to be used as a template.

When the jQuery HttpRequest is completed, the function setSilverlight is executed with the parameters ‘ControlId’ and 1. ‘ControlId’ is the name of the parameter which will be sent to Silverlight and 1 is the value Controlid will be set to. ControlId=1

This is the setSilverlight javascript, you can see that the square-bracket-config value is replaced with my param and value:

function setSilverlight(data, param, controlId, divname, requested) { 
data = data.replace('[path]', '/Content/MDCSilverlightDemo.xap');
data = data.replace('//', '/');
data = data.replace('[config]', 'ControlId=' + controlId + ',requested=' + requested );
$('#' + divname).html(data);//don't want to see it until it shows it's self.
}

The last line is where we see dollar, pound plus divname.html(data) is where the html in this browser window has the object element inserted into it. At this time, the Browser will retrieve and create the Silverlight control.

So to recap the loading process consists of

· Request the html

· Replace two tags

· insert that html is into a div

Link to the MDC powerpoint slides

Links to this demo project, which is created from MVC Storefront - 

MVC Storefront. is an ecommerce demo and is a perfect starting place for Silverlight enhancement - you can get help for MVC Storefront here:  http://www.codeplex.com/mvcsamples

August 08 Minneapolis Silverlight User Group

by Bobbi Perreault 7. September 2008 00:29
Share on Facebook

Tips and Tricks for Dealing with Data in Silverlight

Scott Davis

Ignition Point Solutions

Scott talked about why you may want to use Silverlight for line-of-business applications. He asks: Is anyone aware of any good reporting solutions written for Silverlight?

When planning your Silverlight application, a design consideration is that everything is done asyncronously. Scott has developed a technique which keeps his data updated using threaded services.

WCF full duplex communications do not work in Silverlight.

In the demonstrated WCF communication, the Silverlight client sends a request to the server that says, send me updates since the last time I came back. This is done independent of the UI and thus the UI stays updated.

Aug08 Silverlight User Group

Minnesota Developers Conference, Silverlight Track

by Bobbi Perreault 4. September 2008 00:07
Share on Facebook

Tuesday, September 9, 2008 is the Minnesota Developers Conference, do you have your ticket yet?  If you don't - you can actually save 22% by being a procrastinator. (Sold Out!  whoo hooo) 

I have a late afternoon session, and the topic is one near and dear to my heart, that is Search Engine Optimization for Silverlight Applications.   I'm going to talk about some aspects of Search Engine Optimization, (SEO) effected by the addition of Silverlight controls to your web application.  I’ll show in source code how I solve the following problems:  
1. how to create your Silverlight and html based menus from a single source. And why I use that method to optimize for search engine index-ability.
2. how to switch from one Silverlight control to another programmatically while keeping all controls for the application in a single project. 
3. simplified server communications ( RESTful )  and incorporating these into MVC app
4. I’ll show you how to maintain browser history while switching out your Silverlight controls in the same web page.
And lastly we’ll discuss some of the problems I've encountered while working on my Silverlight applications so that if you should come across them as well you will be forewarned.  

Tags:

 

RSS Feed FriendFeed