﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Ian T. Lackey (ITLackey)</title>
    <description>Open Source @ Your Service</description>
    <link>http://openlightgroup.net/Blog/tabid/58/BlogId/2/Default.aspx</link>
    <language>en-US</language>
    <managingEditor>webmaster@openlightgroup.net</managingEditor>
    <webMaster>webmaster@adefwebserver.com</webMaster>
    <pubDate>Sat, 31 Jul 2010 19:26:31 GMT</pubDate>
    <lastBuildDate>Sat, 31 Jul 2010 19:26:31 GMT</lastBuildDate>
    <docs>http://backend.userland.com/rss</docs>
    <generator>Blog RSS Generator Version 3.5.1.19887</generator>
    <item>
      <title>Role Based Silverlight Behaviors</title>
      <description>&lt;p&gt;Well working on a few WCF RIA Services projects a need for the UI to update based on what roles the current user belongs to came up with each project. To make this easier for all of us working on these projects I created some behaviors that accepts a list of roles and updates the UI accordingly. I decided to include this in an open source library that is available at the associated &lt;a href="http://olgcommon.codeplex.com/" target="_blank"&gt;OpenLight Group Common CodePlex project site&lt;/a&gt;. In this article we will discuss the base class used for all of the role based behaviors and look at the RoleBasedEnabledBehavior as an example of how to implement the base class.&lt;/p&gt;  &lt;p&gt;The first class we will look at is the abstract BaseRoleBasedBehavior class. This class is takes a generic parameter that is constrained to DependencyObject to keep it consistent with Behavior&lt;T&gt; base class.&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BaseRoleBasedBehavior&lt;T&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        : Behavior&lt;T&gt; where T : DependencyObject&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;BaseRoleBaseBehavior includes a property to hold the list of role names:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 662px; padding-right: 5px; height: 148px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;[Category("&lt;span style="color: #8b0000"&gt;Security Settings&lt;/span&gt;")]
&lt;/p&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;[Description("&lt;span style="color: #8b0000"&gt;Associated control will only be visible if the current user is a member of one or more of these roles.&lt;/span&gt;")]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&gt; AllowedRoles { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The constructor handles initializing the list of roles and wiring handlers to the LoggedIn and LoggedOut events of the current webcontext:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 662px; padding-right: 5px; height: 427px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BaseRoleBasedBehavior()
&lt;/p&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AllowedRoles = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&gt;();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (DesignTimeHelper.IsRuntime)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		WebContextBase.Current.Authentication.LoggedIn += 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;			&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.EventHandler&lt;AuthenticationEventArgs&gt;(UpdateAssociatedObject);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		WebContextBase.Current.Authentication.LoggedOut += 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;			&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.EventHandler&lt;AuthenticationEventArgs&gt;(UpdateAssociatedObject);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;There are a few items to note in this method.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The call to DesignTimeHelper.IsRuntime – this is a static class also included in the common library that is used to allow for a good design time experience. As in this example, wiring handlers to the current WebContext at design time would throw an exception. &lt;/li&gt;

  &lt;li&gt;The use of WebContextBase – the prevents the need to include the RIA services web project that will generate the concrete WebContext class. &lt;/li&gt;

  &lt;li&gt;Marking the UpdateAssociatedObject method as abstract allows each inheriting behavior to handle the authentication events as needed. &lt;/li&gt;
&lt;/ol&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 662px; padding-right: 5px; height: 62px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UpdateAssociatedObject(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, AuthenticationEventArgs e);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Another example of using the DesignTime helper is when checking the current user’s membership to a role. In this case, the helper prevents the designer from calling a method on the User object that would be null at design time. This method is included to simplify checks for all of the behaviors that will inherit from this base class.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 662px; padding-right: 5px; height: 357px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsInRole(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; roleName)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (DesignTimeHelper.IsRuntime)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; WebContextBase.Current.Authentication.User.IsInRole(roleName);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;As with all behaviors, the OnAttached and OnDetaching methods are implemented:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 662px; padding-right: 5px; height: 314px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnAttached()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnAttached();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.UpdateAssociatedObject(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnDetaching()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnDetaching();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Notice that the UpdateAssociatedObject is called from the OnAttached method to ensure that the UI is updated when the behavior is applied as well as when the user logs in or out. With that our base class is completed. Now to implement a role based behavior we simply need to inherit from this class and implement the UpdateAssociatedObject method.&lt;/p&gt;

&lt;p&gt;Here is an example of a behavior that disables a control if the current user is not in one of the allowed roles:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 662px; padding-right: 5px; height: 354px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; RoleBasedEnabledBehavior
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	 : BaseRoleBasedBehavior&lt;Control&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UpdateAssociatedObject(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, AuthenticationEventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AssociatedObject.IsEnabled =
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;			(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AllowedRoles.Where(r =&gt; IsInRole(r)).Count() &gt; 0);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;By using the Control type for the generic parameter we gain access to the enabled property of the AssociatedObject property. All that is left to do is check to see if the user is a member of any of the roles specified in the AllowedRoles property of the base class. By using LINQ and the IsInRole method of the base class, this becomes a single line of code to implement the functionality of this behavior.&lt;/p&gt;

&lt;p&gt;It is now simple to disable a control based on the current user’s role membership, like so:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Button"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;i&lt;/span&gt;:&lt;span style="color: #800000"&gt;Interaction.Behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;behaviors&lt;/span&gt;:&lt;span style="color: #800000"&gt;RoleBasedEnabledBehavior&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;			&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;behaviors&lt;/span&gt;:&lt;span style="color: #800000"&gt;RoleBasedEnabledBehavior.AllowedRoles&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;				&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;System&lt;/span&gt;:&lt;span style="color: #800000"&gt;String&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;string&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;System&lt;/span&gt;:&lt;span style="color: #800000"&gt;String&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;			&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;behaviors&lt;/span&gt;:&lt;span style="color: #800000"&gt;RoleBasedEnabledBehavior.AllowedRoles&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;behaviors&lt;/span&gt;:&lt;span style="color: #800000"&gt;RoleBasedEnabledBehavior&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;i&lt;/span&gt;:&lt;span style="color: #800000"&gt;Interaction.Behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note: Make sure that the interactivity, system and behaviors namespaces are imported:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 662px; padding-right: 5px; height: 151px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;xmlns:behaviors="clr-namespace:OpenLightGroup.Common.Behaviors;assembly=OpenLightGroup.Common"
&lt;/p&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;xmlns:System="clr-namespace:System;assembly=mscorlib"
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Again both the base class and the implementing behavior are available in the OpenLight Common Library here: &lt;a title="http://olgcommon.codeplex.com/" href="http://olgcommon.codeplex.com/" target="_blank"&gt;http://olgcommon.codeplex.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this sparks some innovation… or at the very least helps shave off some time spent coding for someone ;)&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/101/Role-Based-Silverlight-Behaviors.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/101/Role-Based-Silverlight-Behaviors.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/101/Role-Based-Silverlight-Behaviors.aspx</guid>
      <pubDate>Thu, 27 May 2010 06:13:47 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=101</trackback:ping>
    </item>
    <item>
      <title>RIA Services - IIS6 Virtual Directory Deployment</title>
      <description>&lt;p&gt;A while back I made a post about using &lt;a href="http://openlightgroup.net/Blog/tabid/58/EntryId/55/RIA-Services-Windows-Authentication-amp-GetUser-Error.aspx"&gt;Windows Authentication with RIA Services&lt;/a&gt; and this post builds upon the topics discussed there. To further complicate the situation I needed to deploy a RIA services app to a Virtual Directory inside of a sub-folder in the IIS web root. To illustrate consider this URL pattern: &lt;a href="https://intranet.companyname.com/division/applicationname"&gt;https://intranet.companyname.com/division/applicationname&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In this setup division is simply a file system folder inside of the root folder used by the IIS6 web site. Application name is an IIS6 Virtual Directory created under the division folder. For example: &lt;a href="https://intranet.mycompany.com/accounting/costcalculator"&gt;https://intranet.mycompany.com/accounting/costcalculator&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;When deploying to the virtual directory the Silverlight application spits out several 404 errors when looking for the auto-generated domain service .svc files.  After missing with the serviceModel configuration section for a while and getting nowhere, I decided to take a different approach based on some information found in &lt;a title="Understanding the WCF in ‘WCF RIA Services’" href="http://blogs.msdn.com/saurabh/archive/2009/11/23/understanding-the-wcf-in-wcf-ria-services.aspx" target="_blank"&gt;this article&lt;/a&gt; about the WCF aspects of RIA services. In the article it states that if you create a  physical .svc file with the right name no virtual file with be created. It also talks about how URL rewriting is used to allow the virtual .svc file to appear to be in any folder in the site. This is were things break down in the configuration exampled above (or any virtual directory in IIS6 for that matter).&lt;/p&gt;  &lt;p&gt;The work around I finally came to was create a physical file and drop it in the ClientBin folder with the .xap files. Because URL rewriting is not working, the .svc files and .xap files need to be in the same folder. In order to create the files you need to keep a few things in mind. The file needs to be named in this pattern: DomainServiceFullname.svc (be sure to replace all of the “.” with “-“ between namespaces and class name). Inside of the file needs to contain something similar to this:&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;%@ ServiceHost 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt; Service="ApplicationName.AnyAdditionalNamespaces.DomainService" 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt; Factory="System.Web.Ria.Services.DomainServiceHostFactory"
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;%&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now that you have the files name correctly, placed in the same folder and the xap and containing the correct service host information, you should now be able to deploy the application to the virtual directory.&lt;/p&gt;

&lt;p&gt;If you continue to have problems please make sure you have read the article(s) mentioned above and use fiddler to help zero in on the issue. As always, please post your feedback or issues that you have and I will be happy to help anyway I can.&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/90/RIA-Services-IIS6-Virtual-Directory-Deployment.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/90/RIA-Services-IIS6-Virtual-Directory-Deployment.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/90/RIA-Services-IIS6-Virtual-Directory-Deployment.aspx</guid>
      <pubDate>Thu, 08 Apr 2010 21:59:57 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=90</trackback:ping>
    </item>
    <item>
      <title>DotNetNuke 5 Book Has Been Published!</title>
      <description>&lt;p&gt;After months of work by Michael and myself, I am happy to announce that Building Websites with DotNetNuke 5 has been published! They have also published a snippet from chapter 6 – Understanding the DotNetNuke Core Architecture: &lt;a href="https://www.packtpub.com/article/understanding-dotnetnuke-core-architecture-1"&gt;https://www.packtpub.com/article/understanding-dotnetnuke-core-architecture-1&lt;/a&gt; (Somehow Michael convinced them to give him all the credit for the chapter I wrote, but I won’t hold it against him. :P)&lt;/p&gt;  &lt;p&gt;The book covers DNN from installation, management, development and deployment. Michael provides some excellent information on how to use Silverlight with DotNetNuke that makes this book worth reading just for that! Anyway, this is not meant to be an advertisement, just an excited post that the book is officially completed and now available! Writing the book was a neat experience and the fact that both of the authors are OpenLight Group founders made it that much better. &lt;/p&gt;  &lt;p&gt;If you are interested the book is available from Packt’s site here: &lt;a href="https://www.packtpub.com/building-websites-with-dotnetnuke-5/book"&gt;https://www.packtpub.com/building-websites-with-dotnetnuke-5/book&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/88/DotNetNuke-5-Book-Has-Been-Published.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/88/DotNetNuke-5-Book-Has-Been-Published.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/88/DotNetNuke-5-Book-Has-Been-Published.aspx</guid>
      <pubDate>Wed, 07 Apr 2010 16:15:45 GMT</pubDate>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=88</trackback:ping>
    </item>
    <item>
      <title>Silverlight SEO at the St. Louis .Net Users Group</title>
      <description>&lt;p&gt;I just wanted to post a thank you to all that attended the talk Monday night and ask for any feedback that you might have. That was my first time speaking at the user group and am sure there is a lot of room for improvement. So please feel free to add comments to this article with suggestions on how I can improve or email them to me directly (ian at openlightgroup dot net).&lt;/p&gt;  &lt;p&gt;Also, I was hoping to provide a quick summary of links to some of the resource I mentioned.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Project Resources:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;CodePlex Project for Silverlight SEO: &lt;a href="http://silverlightseo.codeplex.com/"&gt;http://silverlightseo.codeplex.com/&lt;/a&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Use the discussions and issues on CodePlex for questions / bugs etc.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Example site: &lt;a href="http://silverlightseo.openlightgroup.net"&gt;http://silverlightseo.openlightgroup.net&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Helpful SEO Tools&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;SEO Toolkit: &lt;a title="http://www.iis.net/expand/SEOToolkit" href="http://www.iis.net/expand/SEOToolkit"&gt;http://www.iis.net/expand/SEOToolkit&lt;/a&gt; &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;This requires IIS7&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Lynx Browser (Text based browser): &lt;a title="http://home.pacific.net.sg/~kennethkwok/lynx/" href="http://home.pacific.net.sg/~kennethkwok/lynx/"&gt;http://home.pacific.net.sg/~kennethkwok/lynx/&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Google Tools: &lt;a title="http://www.google.com/webmasters/" href="http://www.google.com/webmasters/"&gt;http://www.google.com/webmasters/&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Bing Tools: &lt;a title="http://www.bing.com/webmaster" href="http://www.bing.com/webmaster"&gt;http://www.bing.com/webmaster&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Analytics Tools&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Google Analytics: &lt;a href="http://www.google.com/analytics/"&gt;http://www.google.com/analytics/&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Silverlight Analytics Framework: &lt;a href="http://msaf.codeplex.com/"&gt;http://msaf.codeplex.com/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Articles &amp; Webcasts&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Analytics Framework Video: &lt;a href="http://live.visitmix.com/MIX10/Sessions/CL24"&gt;http://live.visitmix.com/MIX10/Sessions/CL24&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;SEO for Silverlight Video: &lt;a href="http://live.visitmix.com/MIX10/Sessions/CL50"&gt;http://live.visitmix.com/MIX10/Sessions/CL50&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Original Article by Brad Abrams on SEO and Silverlight: &lt;a title="http://blogs.msdn.com/brada/archive/2009/07/14/business-apps-example-for-silverlight-3-rtm-and-net-ria-services-july-update-part-4-seo-export-to-excel-and-out-of-browser.aspx" href="http://blogs.msdn.com/brada/archive/2009/07/14/business-apps-example-for-silverlight-3-rtm-and-net-ria-services-july-update-part-4-seo-export-to-excel-and-out-of-browser.aspx"&gt;Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 4: SEO, Export to Excel and Out of Browser&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;If I missed something or you find things that should be added to the list please leave a comment or email me at the email above.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Again, I really appreciate everyone coming out Monday night! It was great to have the opportunity to present this information and to speak with a few of you afterwards. &lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/85/Silverlight-SEO-at-the-St-Louis-Net-Users-Group.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/85/Silverlight-SEO-at-the-St-Louis-Net-Users-Group.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/85/Silverlight-SEO-at-the-St-Louis-Net-Users-Group.aspx</guid>
      <pubDate>Wed, 31 Mar 2010 16:43:02 GMT</pubDate>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=85</trackback:ping>
    </item>
    <item>
      <title>Silverlight, SEO &amp; ASP.Net – Part 4 (Preview)</title>
      <description>&lt;p&gt;So this is not a full post (hence the Preview suffix to the title), but wanted to put something out there to let everyone know that I will be posting an update to the Silverlight SEO stuff sometime next week. Monday I am speaking at the St. Louis .Net user group meeting on this topic. After the talk I will be posting my notes and code used for the demo. The code provided will approach this topic from the standpoint of building a new site as opposed to the previous posts, which focused more on upgrading a current site. Currently you can view the demo online here: &lt;a href="http://silverlightseo.openlightgroup.net"&gt;http://silverlightseo.openlightgroup.net&lt;/a&gt; . This site is all data driven content that is shared between Silverlight and ASP.Net. In the near future the site will be filled with all of the details of how it is built and how to incorporate the same strategies in your sites to improve search engine indexing for sites using Silverlight. Keep an eye out over the next few days as the content will start filling out between now and Monday.&lt;/p&gt;  &lt;p&gt;As always thanks for reading!&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/83/Silverlight-SEO-amp-ASP-Net-ndash-Part-4-Preview.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/83/Silverlight-SEO-amp-ASP-Net-ndash-Part-4-Preview.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/83/Silverlight-SEO-amp-ASP-Net-ndash-Part-4-Preview.aspx</guid>
      <pubDate>Fri, 26 Mar 2010 18:33:09 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=83</trackback:ping>
    </item>
    <item>
      <title>Dynamic ListBox Item Templates</title>
      <description>&lt;p&gt;This is a very short and sweet post about dynamically switching the ItemTemplate property of a Silverlight ListBox at runtime. First we will start with a little background of what led to this article.&lt;/p&gt;  &lt;p&gt;I am currently working on an application that contains a list of pediatric patients and their parents. I was recently given a requirement to display a parent name to one group of medical professional and the patient name to another group. However, either group should be able to toggle this display to allow searching on either the parent or patient.&lt;/p&gt;  &lt;p&gt;Knowing that in Silverlight, simple is usually the correct answer, I figured this should in fact be simple. Thankfully, I was correct and after only a few minutes I had the following solution working.&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.SearchByParent.IsChecked &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.PatientListBox.SetValue(ListBox.ItemTemplateProperty, _
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                       &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Resources("&lt;span style="color: #8b0000"&gt;PatientParentListBoxTemplate&lt;/span&gt;"))
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt; &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.PatientListBox.SetValue(ListBox.ItemTemplateProperty, _
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                       &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Resources("&lt;span style="color: #8b0000"&gt;PatientListBoxTemplate&lt;/span&gt;"))
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;I have created two different DataTemplates to display the appropriate information for either the parent or the patient. These are added to the UserControl.Resources and then used when dynamically setting the ItemTemplateProperty DependencyProperty of the ListBox instance. The reason the DependencyProperty is used is to avoid an InvalidCastException that is thrown if setting the ItemTemplate instance property directly.&lt;/p&gt;

&lt;p&gt;I did not come up with much on this in the brief searching I did online, so I thought I would get it out there for others.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/81/Dynamic-ListBox-Item-Templates.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/81/Dynamic-ListBox-Item-Templates.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/81/Dynamic-ListBox-Item-Templates.aspx</guid>
      <pubDate>Mon, 08 Mar 2010 21:38:11 GMT</pubDate>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=81</trackback:ping>
    </item>
    <item>
      <title>RIA Services, Windows Authentication &amp; GetUser Error</title>
      <description>&lt;p&gt;Like many other developers I have been excited to see that WCF RIA Services has gone beta and now comes with a Go-Live license. After this release my team at &lt;a href="http://peds.wustl.edu" target="_blank"&gt;Wash U&lt;/a&gt; began developing a few applications using the new RIA Services bits. We have been very impressed with the productivity increase as well as several other features that RIA provides over the previous straight up WCF services have offered in the past.&lt;/p&gt;  &lt;p&gt;All was going well, until it came time to publish the first application to the staging (user testing) server. Upon deployment the application started displaying the “Initializing Application” progress control for close to a minute.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/2/55/WLW-RIAServicesWindowsAuthenticationGetUserE_907-image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/55/WLW-RIAServicesWindowsAuthenticationGetUserE_907-image_thumb.png" width="183" height="71" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After which the application would throw an error: “Load operation failed for query ‘GetUser’. Unable to connect to SQL Server Database.“&lt;/p&gt;  &lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/2/55/WLW-RIAServicesWindowsAuthenticationGetUserE_907-image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/55/WLW-RIAServicesWindowsAuthenticationGetUserE_907-image_thumb_1.png" width="300" height="167" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This was a very strange error since we had configured the application to use Windows authentication and where not connecting to the application’s database on the initial screen. While the application was running on our local development machines everything worked fine, the application fired up and displayed the currently logged in username in the upper right of the application. So we looked at the configuration again to see if there was anything that we missed. By default RIA is configured to use Forms authentication. (As a side note, I found this post by Brad Abrams concerning the decision on which authentication method was more common: &lt;a href="http://blogs.msdn.com/brada/archive/2009/06/04/forms-auth-windows-auth-what-is-more-common.aspx" target="_blank"&gt;Forms Auth\Windows Auth – what is more common?&lt;/a&gt; ) Given this, the default configuration looks like this (Please note this is trimmed to display only the configuration elements used by the Authentication Service): &lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;roleManager&lt;/span&gt; &lt;span style="color: #ff0000"&gt;enabled&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"true"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;authentication&lt;/span&gt; &lt;span style="color: #ff0000"&gt;mode&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Forms"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;forms&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;".RiaWinAuthExample_ASPXAUTH"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;authentication&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;profile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;properties&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"FriendlyName"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;properties&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;profile&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;To get RIA to use Windows authentication on the local developer workstations we simply had to change the authentication element to the following:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;authentication&lt;/span&gt; &lt;span style="color: #ff0000"&gt;mode&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Windows"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;After verifying that the configuration published to the server did in fact contain this change we went on a hunt to find out why this would not work outside of localhost. One of the first articles we found was Tim Heuer’s post &lt;a href="http://timheuer.com/blog/archive/2009/12/10/tips-to-deploy-ria-services-troubleshoot.aspx" target="_blank"&gt;Deploying your Silverlight and WCF RIA Services application&lt;/a&gt;. This post shed a lot of light on possible details that may have been overlooked. After double checking the items mentioned in Tim’s article we continued to have the issue. (BTW: You may also need to add the System.ComponentModel.DataAnnotations.dll assembly to the list of items to set to “Copy Local” in addition to the items listed in the bin or not to bin section of the article.)&lt;/p&gt;

&lt;p&gt;After digging some more and not finding much help on &lt;Insert your favorite search engine here&gt;, I decided to do some ground up debugging. This lead to several hours of starting new RIA projects, changing something, deploying it to a server and zeroing in on the problem. Eventually I came up with the following list of issues that were causing the error.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The System.ComponentModel.DataAnnotations.dll was not included in the bin folder on the server.&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;This was fixed by setting the Copy Local property of the reference to true.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;We had neglected to enable impersonation in the configuration for the site. This was simply a silly mistake as we do this for all of our internal web applications.&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;Love it or hate it, we are pretty much required to use impersonation due to auditing requirements we have because of HIPAA regulations. I realize that there are other ways; however, this is the most straightforward way for us to be in compliance today. Going forward we are looking into possibly implementing other solutions.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;There are some additional configuration changes that are required when deploying to a non-developer workstation.&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;Specify the defaultProvider for the roleManager as: AspNetWindowsTokenRoleProvider&lt;/li&gt;

    &lt;li&gt;Set the enabled attribute on the profile element to false! &lt;/li&gt;

    &lt;ul&gt;
      &lt;li&gt;If you are using profiles the instead of setting this to false, the provider needs to be configured to use the proper database. If you need more information about profile providers, this article should get you started: &lt;a href="http://msdn.microsoft.com/en-us/library/014bec1k.aspx" target="_blank"&gt;ASP.NET Profile Providers&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
&lt;/ol&gt;

&lt;p&gt;I realize that some of this may be the result of trying to rush the application out for demo; however, with the exception of Tim’s article there was not much on the web about deployment. Information about deploying using windows authentication is even more scarce. My hope is that this article will document all of the information in one place to save others the trouble of piecing this together for the many source I had to use.&lt;/p&gt;

&lt;h3&gt;Summary \ Solution&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Check out Tim’s article to cover the RIA deployment bases.&lt;/li&gt;

  &lt;li&gt;Make sure IIS is properly configured to use Windows authentication. This is the same configuration for any other ASP.Net application that uses Windows authentication, nothing special here.&lt;/li&gt;

  &lt;li&gt;Ensure that System.ComponentModel.DataAnnotations.dll and all other referenced RIA assemblies are deployed to the bin folder on the server or RIA is installed on the server.&lt;/li&gt;

  &lt;li&gt;If you need impersonation, make sure it is specified in the configuration! (man, this one make me feel sloppy in my case)&lt;/li&gt;

  &lt;li&gt;Set the corresponding configuration elements as follows:&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;Again, this is trimmed to only show the sections the authentication service is concerned with, and the impersonation configuration is included. You may or may not need the identity element for your application. Like IIS impersonation settings are the same as any ASP.Net site, so follow the same rules regarding it.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;identity&lt;/span&gt; &lt;span style="color: #ff0000"&gt;impersonate&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"true"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;authentication&lt;/span&gt; &lt;span style="color: #ff0000"&gt;mode&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Windows"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;roleManager&lt;/span&gt; &lt;span style="color: #ff0000"&gt;enabled&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"true"&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;             &lt;span style="color: #ff0000"&gt;defaultProvider&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"AspNetWindowsTokenRoleProvider"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;profile&lt;/span&gt; &lt;span style="color: #ff0000"&gt;enabled&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"false"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;To summarize, the issues we encountered were related to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ASP.Net’s default configuration attempting to use a local SQL Express database for membership, roles and providers. This was solved by using the proper configuration. For us, that meant disabling profiles altogether and changing the default role provider.&lt;/li&gt;

  &lt;li&gt;RIA assemblies are not deployed with the site by default and needed to be configured to be copied to the bin folder of the site or the RIA bits needed to be installed on the server.&lt;/li&gt;

  &lt;li&gt;Impersonation needed to be set to allow access to server side resources. (database connections, file system resources etc.)&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;I cannot stress enough that this may not apply to your application and needs to be considered based on your environment before enabling it. There are security philosophies that say this is an “evil” configuration.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;I sure hope this saves other RIA developers some time and hair loss. Due to the voodoo that is RIA services, this was not necessarily an easy issue to figure out. I had to use Fiddler, Reflector and read several articles before it finally became clear. Once all of the pieces were exposed to the light it all made since, but brining it out of the “black magic” proved to be more challenging that it “should” have been. I guess that is the trade off for having such an easy development “story.”&lt;/p&gt;

&lt;p&gt;Either way, I must say I am really digging the power of RIA and I have to recommend it to anyone want to build stunning LOB applications. So if you haven’t already, dig in and be amazed.&lt;/p&gt;

&lt;p&gt;Happy Coding… err… Designing … umm … RIA Using. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;As always, feedback is encouraged and appreciated!&lt;/em&gt;&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/55/RIA-Services-Windows-Authentication-amp-GetUser-Error.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/55/RIA-Services-Windows-Authentication-amp-GetUser-Error.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/55/RIA-Services-Windows-Authentication-amp-GetUser-Error.aspx</guid>
      <pubDate>Thu, 17 Dec 2009 06:38:42 GMT</pubDate>
      <slash:comments>13</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=55</trackback:ping>
    </item>
    <item>
      <title>Helpful Developer Resources</title>
      <description>&lt;p&gt;In college my instructor taught us that it is not always knowing the answer but knowing where to find it. In the mindset, this post is simply a list of other blogs, twitter accounts \ lists and books that I have found helpful in the recent past. Hopefully these will point you to information that you need to build great software, enjoy your work (or at least experience less stress), and keep up on the latest news regarding development.&lt;/p&gt;  &lt;p&gt;Admittedly I have been almost 100% focused on Silverlight development, so most of these resources will reflect this. However, there are a few in the list are are more general. Also, for some of the more experienced developers, I realized that a few of these links are may have you wondering why they are including. Like the MSDN site, doesn’t everyone know about that? Well, maybe, but necessarily. So I included them for the new developers or people looking to get started.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;(…these resources are in no particular order…)&lt;/em&gt;&lt;/p&gt;  &lt;h3&gt;Favorite Blogs (other than the OpenLight Members of course :) )&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;ScottGu’s Blog: Scott is a Corporate VP in the Microsoft Developer Division, and is considered the grandfather of .Net.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Blog: &lt;a title="http://weblogs.asp.net/scottgu/" href="http://weblogs.asp.net/scottgu/"&gt;http://weblogs.asp.net/scottgu/&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;Twitter: &lt;a href="http://www.twitter.com/scottgu" target="_blank"&gt;@scottgu&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Tim Heuer’s Blog: Tim is a program manager on the Microsoft Silverlight team.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Blog: &lt;a title="http://timheuer.com/blog/" href="http://timheuer.com/blog/"&gt;http://timheuer.com/blog/&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;Twitter: &lt;a href="http://www.twitter.com/timheuer" target="_blank"&gt;@timheuer&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;John Papa’s Blog: John is a Senior Technical Evangelist for Microsoft and former Silverlight MVP.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Blog: &lt;a title="http://johnpapa.net/" href="http://johnpapa.net/"&gt;http://johnpapa.net/&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;Twitter: &lt;a href="http://www.twitter.com/John_Papa" target="_blank"&gt;@John_Papa&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Brad Abrams’ Blog: &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Blog: &lt;a title="http://blogs.msdn.com/BradA/" href="http://blogs.msdn.com/BradA/"&gt;http://blogs.msdn.com/BradA/&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;Twitter: &lt;a href="http://twitter.com/brada" target="_blank"&gt;@brada&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Nikhilk Kothari’s Blog: Nikhil is a software architect in the .NET Developer Platform group within the Developer Division at Microsoft.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Blog: &lt;a title="http://www.nikhilk.net" href="http://www.nikhilk.net"&gt;http://www.nikhilk.net&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;Twitter: &lt;a href="http://twitter.com/nikhilk" target="_blank"&gt;@nikhilk&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;h3&gt;Twitter&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;Silverlight MVPs: &lt;a title="http://twitter.com/John_Papa/silverlightmvp" href="http://twitter.com/John_Papa/silverlightmvp"&gt;http://twitter.com/John_Papa/silverlightmvp&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Microsoft Silverlight Developers: &lt;a title="http://twitter.com/John_Papa/msftsilverlight" href="http://twitter.com/John_Papa/msftsilverlight"&gt;http://twitter.com/John_Papa/msftsilverlight&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Michael Washington: @adefwebserver&lt;/li&gt;    &lt;li&gt;Me: @itlackey&lt;/li&gt;    &lt;li&gt;Devin Rader: @devinrader&lt;/li&gt;    &lt;li&gt;Colin Blair: @SLColinBlair&lt;/li&gt;    &lt;li&gt;Kevin Grossnicklaus: @kvgros&lt;/li&gt;    &lt;li&gt;Bill Evjen: @billevjen&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Misc. Developer Sites:&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;MSDN: Should be every .Net developers homepage (or at least one of them…). Be sure and checkout the “Learn” section for some great videos.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;URL: &lt;a title="http://msdn.microsoft.com/en-us/default.aspx" href="http://msdn.microsoft.com/en-us/default.aspx"&gt;http://msdn.microsoft.com/en-us/default.aspx&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Silverlight.Net: Everything Silverlight. Videos, Hands-On labs, tutorials and forums.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://www.silverlight.net"&gt;http://www.silverlight.net&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Silverlight Cream: Actually an aggregate of many Silverlight focused blogs. Be sure to checkout the “Skim” page to see the most popular posts.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;URL: &lt;a href="http://www.silverlightcream.com"&gt;http://www.silverlightcream.com&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;DotNetNuke’s Blogs: A link to the articles posted by the developer’s involved in the DotNetNuke project.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;URL: &lt;a title="http://www.dotnetnuke.com/tabid/825/default.aspx" href="http://www.dotnetnuke.com/tabid/825/default.aspx"&gt;http://www.dotnetnuke.com/tabid/825/default.aspx&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Channel 9: “Channel 9 is all about the conversation.”  Great videos by some of the heavy hitters&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;URL: &lt;a title="http://channel9.msdn.com/" href="http://channel9.msdn.com/"&gt;http://channel9.msdn.com/&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Chopsticks: Growing list of great videos, mainly from conferences.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;URL: &lt;a title="http://www.microsoft.com/belux/msdn/nl/chopsticks/default.aspx" href="http://www.microsoft.com/belux/msdn/nl/chopsticks/default.aspx"&gt;http://www.microsoft.com/belux/msdn/nl/chopsticks/default.aspx&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;This is just a small list of resource you can find online to stay informed and learn the latest tricks from some great developers. Please feel free to suggest additions to this list in the comments section. I will be updating this post from time to time with new information and your suggestions are appreciated and may be included.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/53/Helpful-Developer-Resources.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/53/Helpful-Developer-Resources.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/53/Helpful-Developer-Resources.aspx</guid>
      <pubDate>Thu, 10 Dec 2009 06:29:32 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=53</trackback:ping>
    </item>
    <item>
      <title>DotNetNuke, jQuery and Microsoft CDN</title>
      <description>&lt;p&gt;As you may have heard, Microsoft has created their on &lt;a href="http://www.asp.net/ajaxlibrary/cdn.ashx" target="_blank"&gt;CDN&lt;/a&gt; for delivering JavaScript libraries. Beginning in ASP.Net 4 the ability to use scripts hosted on the CDN will be built into the ScriptManager control. ScottGu demonstrated how this will work in one of his &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/09/15/announcing-the-microsoft-ajax-cdn.aspx" target="_blank"&gt;blog entries&lt;/a&gt;. In addition to hosting their own AJAX library, Microsoft is also providing the jQuery library for download.&lt;/p&gt;  &lt;p&gt;I am assuming that many of us have not jumped on this bandwagon as of yet This, I’m sure, is partly due to the fact that the MS AJAX libraries that are available are all beta editions slated for release with ASP.Net 4. However, the jQuery script that is currently provide is the current production release of the library and can be used today. When the next version of ASP.Net is released the number of users with cached copies of jQuery from Microsoft’s CDN will steadily rise. This will increase the benefit of using the scripts hosted there.&lt;/p&gt;  &lt;p&gt;So in an effort to ready DotNetNuke to gain from this coming event, you can configure DNN to start pulling its jQuery script from the Microsoft CDN. Thanks to some relatively new features in DotNetNuke, this is a very simple process.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Log into the portal using a SuperUser account.&lt;/li&gt;    &lt;li&gt;Navigate to the&lt;strong&gt; Host Settings&lt;/strong&gt; page located on the &lt;strong&gt;Host&lt;/strong&gt; menu.&lt;/li&gt;    &lt;li&gt;Scroll down to the &lt;strong&gt;jQuery Settings&lt;/strong&gt; section located under Advanced Settings.&lt;/li&gt;    &lt;li&gt;Check the &lt;strong&gt;Use Hosted jQuery Version&lt;/strong&gt; checkbox.&lt;/li&gt;    &lt;li&gt;Enter the following URL into the &lt;strong&gt;Hosted jQuery URL&lt;/strong&gt; textbox. &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.min.js&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Click &lt;strong&gt;Update&lt;/strong&gt;.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/2/50/WLW-DotNetNukejQueryandMicrosoftCDN_DCB-image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/50/WLW-DotNetNukejQueryandMicrosoftCDN_DCB-image_thumb.png" width="420" height="288" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;That is all there is to it. Now your DotNetNuke site will use the jQuery script on the Microsoft CDN. In the interest of full disclosure, I should state that not everyone will see a benefit from this change and each site should be evaluated independently. There is an ongoing debate on whether Microsoft developers should use Google’s CDN, Microsoft’s CDN or other hosting options when referencing the jQuery library. Be sure you do your homework to determine which is the best solution for your site(s).&lt;/p&gt;  &lt;p&gt;Happy coding… err… configuring. ;)&lt;/p&gt;  &lt;p&gt;P.S. I made a forum post here seeing what the interest of the Silverlight community is in having the Silverlight.js file hosted on the CDN. Please take a moment and post your thoughts. If enough of us support the idea, maybe Microsoft will consider adding it. &lt;a title="http://forums.silverlight.net/forums/t/147867.aspx" href="http://forums.silverlight.net/forums/t/147867.aspx"&gt;http://forums.silverlight.net/forums/t/147867.aspx&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/50/DotNetNuke-jQuery-and-Microsoft-CDN.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/50/DotNetNuke-jQuery-and-Microsoft-CDN.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/50/DotNetNuke-jQuery-and-Microsoft-CDN.aspx</guid>
      <pubDate>Thu, 03 Dec 2009 06:59:12 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=50</trackback:ping>
    </item>
    <item>
      <title>Silverlight Metronome</title>
      <description>&lt;p&gt;I have recently been practicing playing the bass again and during one of the practicing session my friend had suggested some features for a digital metronome. We had used a few JavaScript based ones; however none of them had a few helpful features. These features included: Adjustable tempo, support for different beats per measures, a visual counter displaying the current count of the measure, the ability to allow for multiple measures, the ability to have two different volumes for the tick sound that plays for each beat, the ability to mute the tick for specified beats of a measure and allow the metronome to be run from the computer without being connected to the internet.So since we could not find a single metronome that supported these features, I decided to build one using Silverlight, figuring that it would be a pretty simple exercise. It turns out I was right, well for the most part.&lt;/p&gt;  &lt;p&gt;Obviously the most important feature of a metronome is to keep time, this turned out to be so easy it was almost ridiculous. All that needed to be done was to create an empty storyboard with a duration of one second.&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;UserControl.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Storyboard&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Tick"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #ff0000"&gt;Duration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"00:01:00"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;UserControl.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The an event handler was wired up to restart the story board each time it was completed, like this:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Tick.Completed += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler(Tick_Completed);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;//Inside the event handler:&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Tick.Begin();&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now to allow for tempos other than 60 beats per minute, I created a slider control and wired the value to the SpeedRatio of the storyboard. Unfortunately, element to element binding would not work in this case because the storyboard is a resource. So I had to wire up an event handler to the slider’s ValueChanged event that would update the SpeedRatio of the storyboard. I also needed to ensure that the value was a whole number.  A custom behavior I found here: &lt;a title="http://blogs.veracitysolutions.com/tag/behaviors/" href="http://blogs.veracitysolutions.com/tag/behaviors/"&gt;http://blogs.veracitysolutions.com/tag/behaviors/&lt;/a&gt; was all it took to snap the slider to whole number.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Slider&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"BeatsPerMinute"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #ff0000"&gt;Minimum&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #ff0000"&gt;Maximum&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"200"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"60"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Vertical"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #ff0000"&gt;SmallChange&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #ff0000"&gt;HorizontalAlignment&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Center"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"180"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;i&lt;/span&gt;:&lt;span style="color: #800000"&gt;Interaction.Behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;OpenLightGroup&lt;/span&gt;&lt;span style="color: #ff0000"&gt;_AgMetronome&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;SnappingSliderBehavior&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;i&lt;/span&gt;:&lt;span style="color: #800000"&gt;Interaction.Behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Slider&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;With that I had the foundation laid for a metronome with an adjustable tempo. I then wired up a toggle button to control starting and stopping the metronome to allow for a different look while the metronome is running. So now we need to be able to set the number of beats per measure so we know what to count to. For this, I simply used a combobox to allow you to select from 3/4, 4/4 and 5/4 times and wired up an event handler to set a field that holds the count for each measure. Then I added some code to the tick completed event handler to track the current beat and reset it to one once the maximum count is reached based on the beats per measure that is currently selected. I also set the content of the toggle button to show what the current count is.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._count++;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._count &gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._maxCount)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._count = 1;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayButton.Content = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._count.ToString();&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;At this point, if you click the play button the metronome will count the number of beats selected pre measure and display them in the button. You can also adjust the tempo to count faster or slower. Next, I added the ability to have multiple measure displayed so the metronome would count to the max count of the measure and below show which count it was on in all of the measures. To do this I added a wrap panel with a number of beats added to it based on the beats per measure and the number of measures selected. To allow for the feature of stressing certain beats I decided to create a beat user control that would have three states: Normal, Medium and High. These states are shown by changing the color of the text that shows the number of the beat. The state of the beat is selected by click on the beat to cycle through the options. All beats start in the normal state, but change to medium upon the first click and high on the second click. Clicking the beat a third time cycles it back to the normal state.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.StressLevel++;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.StressLevel &gt; 3)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.StressLevel = 1;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.StressLevel == 1)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MeasureNumberText.Foreground = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NormalStressCountBrush;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.StressLevel == 2)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MeasureNumberText.Foreground = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MediumStressCountBrush;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.StressLevel == 3)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MeasureNumberText.Foreground = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.HighStressCountBrush;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;When the metronome loads, it defaults to four beats per measure and only one measure which then adds four beats set to the normal state to the beats wrap panel. By clicking the up arrow on the number of measures control the proper number of beats will be added to the wrap panel. Clicking the down arrow will remove the appropriate number of beats from the wrap panel. To prevent issues with the count, the metronome is paused and then restarted once the correct number of beats are added.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt; NumberOfMeasures_ValueChanged(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, RoutedPropertyChangedEventArgs&lt;&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&gt; e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayButton.IsChecked.HasValue &amp;&amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayButton.IsChecked.Value)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Tick.Stop();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; difference;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.NewValue &gt; e.OldValue)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        difference = (e.NewValue - e.OldValue) * &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._maxCount;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &lt; difference; i++)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddBeat();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        difference = (e.OldValue - e.NewValue) * &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._maxCount;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &lt; difference; i++)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Beats.Children.Count &gt; 0)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                UIElement child = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Beats.Children.Last&lt;UIElement&gt;();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Beats.Children.Remove(child);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayButton.IsChecked.HasValue &amp;&amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayButton.IsChecked.Value)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Tick.Begin();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;To show which beat the metronome is currently on within the measures I increase the border thickness and scale the beat to 1.1. This means I also need to reset the style of the previous beat each time the count is increased. I also set the color of the text of the play button equal to the color of the font of the current beat. This is done to show the current stress level inside of both the beat in the measures and the current count within the beats per measure. All of this is done inside of the tick completed event handler.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ResetPreviousBeat();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.StyleCurrentBeat();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;Beat currentBeat = (Beat)&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Beats.Children[&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._currentBeat];
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayButton.Foreground = currentBeat.MeasureNumberText.Foreground;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Up until this point everything has been pretty standard coding and went fairly smoothly. Well with the exception of some silly math/logic issues with looping and adding/removing the proper number of beats when changing the number of measures. This leaves us with two features left to implement, playing the tick sound at the correct volume based on the current beats stress level and the ability to run the application “out of browser.”&lt;/p&gt;

&lt;p&gt;I will started by creating the sound file that will be used to play the “tick” sound for selected beats. To do this I used the “Generate Click Track” feature of the &lt;a href="http://audacity.sourceforge.net/" target="_blank"&gt;Audacity&lt;/a&gt; sound editor program.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/2/49/WLW-SilverlightMetronome_9ADC-image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/49/WLW-SilverlightMetronome_9ADC-image_thumb.png" width="240" height="119" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;After exporting the track as an mp3, I imported the mp3 into Expression Encoder to clip it to a single tick and encode it as a wma file. Once I had encoded a suitable sound file, I added a resource file to the project and added the sound file as a resource. This allows the sound file to be played when the application cannot access the hosting site. With the sound file in place, I added a media element control to the metronome control to allow the sound to be played programmatically. However, since the sound file is now compiled into the application the source has to be set during the loaded event instead of in the xaml.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;_soundStream = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MemoryStream(SourdResource.TickSound);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TickPlayer.SetSource(_soundStream);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;We are finally ready to use the stress level of the current beat to determine if the sound should be played and if so at what volume level. This too is done inside of the tick completed event handler. To make the code in the tick completed event handler easier to read I made the PlayTick method to handle setting the volume and playing the sound. Notice that the position of the media element must be set to zero each time it is played.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; PlayTick(&lt;span style="color: #0000ff"&gt;double&lt;/span&gt; volume)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TickPlayer.Volume = volume;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TickPlayer.Position = TimeSpan.FromSeconds(0.0);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TickPlayer.Play();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The finished tick completed event handler now looks like this:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Tick_Completed(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._count++;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._count &gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._maxCount)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._count = 1;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayButton.Content = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._count.ToString();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ResetPreviousBeat();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.StyleCurrentBeat();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    Beat currentBeat = (Beat)&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Beats.Children[&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._currentBeat];
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayButton.Foreground = currentBeat.MeasureNumberText.Foreground;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (currentBeat.StressLevel)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; 2:
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayTick(0.75);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; 3:
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.PlayTick(1.0);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;:
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._currentBeat++;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._currentBeat &gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Beats.Children.Count - 1)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._currentBeat = 0;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Tick.Begin();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The final feature to implement is by far the easiest one. To enable the application to be run from a disconnected computer all that need to be done is to open the properties of the Silverlight application and check the “Enable running application out of the browser” checkbox.&lt;/p&gt;

&lt;p&gt;You can view the finished product at the following link: &lt;a href="http://itlackey.net/silverlight/agmetronome/default.html" target="_blank"&gt;AgMetronome&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The source code for the Silverlight project can be downloaded here: &lt;a href="http://itlackey.net/silverlight/agmetronome/agmetronome.zip" target="_blank"&gt;AgMetronome Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope the tutorial or the application itself proves to be useful for you. As always I appreciate any feedback, questions or comments regarding this post.&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/49/Silverlight-Metronome.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/49/Silverlight-Metronome.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/49/Silverlight-Metronome.aspx</guid>
      <pubDate>Sun, 29 Nov 2009 17:01:05 GMT</pubDate>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=49</trackback:ping>
    </item>
  </channel>
</rss>