﻿<?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>Michael Washington (ADefWebserver)</title>
    <description>All Open Source - All The Time</description>
    <link>http://openlightgroup.net/Blog/tabid/58/BlogId/1/Default.aspx</link>
    <language>en-US</language>
    <managingEditor>webmaster@openlightgroup.net</managingEditor>
    <webMaster>webmaster@adefwebserver.com</webMaster>
    <pubDate>Wed, 10 Mar 2010 07:12:16 GMT</pubDate>
    <lastBuildDate>Wed, 10 Mar 2010 07:12:16 GMT</lastBuildDate>
    <docs>http://backend.userland.com/rss</docs>
    <generator>Blog RSS Generator Version 3.5.1.19887</generator>
    <item>
      <title>DotNetNuke® Silverlight Traffic Module</title>
      <description>&lt;p&gt;&lt;img alt="" width="634" height="172" src="http://www.adefwebserver.com/DotNetNukeHELP/Silverlight/SilverlightTraffic/images/img11.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;At the last Microsoft MVP summit, I was eating lunch with &lt;a href="http://designwithsilverlight.com/"&gt;&lt;u&gt;&lt;font color="#800080"&gt;Jeff Paries&lt;/font&gt;&lt;/u&gt;&lt;/a&gt; who I had collaborated with on previous Silverlight projects, but had not met in person until that week. I commented that I had not used the &lt;a href="http://dnnsilverlight.adefwebserver.com/Silverlight20/SilverlightDashboard/tabid/70/Default.aspx"&gt;&lt;u&gt;&lt;font color="#800080"&gt;Silverlight gauge he created about a year ago&lt;/font&gt;&lt;/u&gt;&lt;/a&gt; because it was too big...&lt;/p&gt;&lt;a href=http://openlightgroup.net/Blog/tabid/58/EntryId/79/DotNetNuke-reg-Silverlight-Traffic-Module.aspx&gt;More...&lt;/a&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/79/DotNetNuke-reg-Silverlight-Traffic-Module.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/79/DotNetNuke-reg-Silverlight-Traffic-Module.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/79/DotNetNuke-reg-Silverlight-Traffic-Module.aspx</guid>
      <pubDate>Sun, 07 Mar 2010 19:50:47 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=79</trackback:ping>
    </item>
    <item>
      <title>Yet Another Silverlight File Uploader</title>
      <description>&lt;p&gt;&lt;img src="http://www.adefwebserver.com/DotNetNukeHELP/Silverlight/SilverlightFileUploader/img11.gif" width="190" height="116" /&gt;&lt;/p&gt;  &lt;p&gt;You are probably thinking “Didn’t he already post a free DotNetNuke Silverlight file Uploader ?”. Well yeah I did, but this one is different. &lt;/p&gt;  &lt;p&gt;This one allows a DotNetNuke portal administrator to place an instance of the module on a page and upload files. Each file has the ModuleID saved in its database record. The module will only show files for that module instance.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.adefwebserver.com/DotNetNukeHELP/Silverlight/SilverlightFileUploader/img10.jpg" width="572" height="272" /&gt;&lt;/p&gt;  &lt;p&gt;Each module instance has it’s own set of files, so you can set different visibility and permissions. It uses a Silverlight upload control so you can upload large files and select multiple files to be uploaded at one time.&lt;/p&gt;  &lt;p&gt;You can download the module and the source &lt;a href="http://dnnsilverlight.adefwebserver.com/Silverlight30/SilverlightModuleInstanceFileUploader/tabid/84/Default.aspx"&gt;at this link&lt;/a&gt;.&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/78/Yet-Another-Silverlight-File-Uploader.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/78/Yet-Another-Silverlight-File-Uploader.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/78/Yet-Another-Silverlight-File-Uploader.aspx</guid>
      <pubDate>Sun, 21 Feb 2010 02:16:48 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=78</trackback:ping>
    </item>
    <item>
      <title>Silverlight Keep Logged In: Prevent pages from timing out</title>
      <description>&lt;p&gt;If you have a page that contains a lot of information for users to enter, you can run into a problem where their authentication will “time out”. Usually this authentication is set to expire after 20 minutes of “inactivity” (the user has not submitted a request to the web server). The problem is that if they, for example, click the Save button after their authentication has expired, their content is not saved and they are logged out of the site instead.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/77/WLW-SilverlightKeepLoggedInPreventpagesfromt_56A7-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/1/77/WLW-SilverlightKeepLoggedInPreventpagesfromt_56A7-image_thumb.png" width="376" height="77" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;To prevent this, you can install the &lt;strong&gt;Silverlight Keep Logged In&lt;/strong&gt; module. When you place it on a page, there is no UI just a Title. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/77/WLW-SilverlightKeepLoggedInPreventpagesfromt_56A7-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/1/77/WLW-SilverlightKeepLoggedInPreventpagesfromt_56A7-image_thumb_1.png" width="378" height="76" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You can go into &lt;strong&gt;Settings&lt;/strong&gt; for the module and change them so that nothing appears at all on the page but the module will still work.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/77/WLW-SilverlightKeepLoggedInPreventpagesfromt_56A7-image_8.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/1/77/WLW-SilverlightKeepLoggedInPreventpagesfromt_56A7-image_thumb_3.png" width="244" height="83" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Note, it has to be set so that &lt;strong&gt;Registered Users&lt;/strong&gt; have &lt;strong&gt;View Module&lt;/strong&gt; permission.&lt;/p&gt;  &lt;p&gt;Any page that the module is on will not “time out” for the user. The module works by making a “call” to a web service in the website every 10 minutes. It uses a hidden Silverlight application to do this. &lt;/p&gt;  &lt;p&gt;Silverlight runs in the “context of the user’s web browser”, so if the user is logged in, the Silverlight application running on the web page is “logged in”. When it makes a request of the website, the website detects that the user is making a request and it refreshes the the users “authentication token”.&lt;/p&gt;  &lt;h4&gt;The Problem&lt;/h4&gt;  &lt;p&gt;When a DotNetNuke module displays it’s first page, or it’s “default page”, all other modules on the page are also displayed. If the &lt;strong&gt;Silverlight Keep Logged In&lt;/strong&gt; module is on the page, the user will not “time out”. However, if any other page in a module is displayed, all other modules are not displayed. In this case, the &lt;strong&gt;Silverlight Keep Logged In&lt;/strong&gt; module will not work.&lt;/p&gt;  &lt;p&gt;In this case, it would be necessary to incorporate the &lt;strong&gt;Silverlight Keep Logged In&lt;/strong&gt; module code into the code of the custom module. The module structure is simple:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/77/WLW-SilverlightKeepLoggedInPreventpagesfromt_56A7-image_6.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/1/77/WLW-SilverlightKeepLoggedInPreventpagesfromt_56A7-image_thumb_2.png" width="240" height="130" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;There is a &lt;strong&gt;View.ascx&lt;/strong&gt; control to launch the hidden Silverlight application (&lt;strong&gt;SilverlightKeepLoggedIn.xap&lt;/strong&gt;), with a supporting &lt;strong&gt;Silverlight.js&lt;/strong&gt; file. There is also a web service that contains this code:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;%@ WebService Language="&lt;span style="color: #8b0000"&gt;C#&lt;/span&gt;" &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;="&lt;span style="color: #8b0000"&gt;SilverlightKeepLoggedIn.WebService&lt;/span&gt;" %&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web.Services;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; DotNetNuke.Entities.Users;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; SilverlightKeepLoggedIn
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    [WebService(&lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt; = "&lt;span style="color: #8b0000"&gt;http://ADefWebserver.com/&lt;/span&gt;")]
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; WebService : System.Web.Services.WebService
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        [WebMethod]
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; void KeepAlive()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            // Calling this web method keeps the user active
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The Silverlight application uses the following code:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Controls;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; SilverlightKeepLoggedIn.wsKeepLoggedIn;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ServiceModel;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; SilverlightKeepLoggedIn
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MainPage : UserControl
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; MainPage()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            InitializeComponent();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            // &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; up timer
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            System.Windows.Threading.DispatcherTimer dt = 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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.Windows.Threading.DispatcherTimer();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            // &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; &lt;span style="color: #0000ff"&gt;to&lt;/span&gt; &lt;span style="color: #0000ff"&gt;call&lt;/span&gt; every 10 minutes
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            dt.Interval = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeSpan(0, 0, 10, 0, 0);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            // &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; up &lt;span style="color: #0000ff"&gt;event&lt;/span&gt; handler
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            dt.Tick += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler(dt_Tick);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            // Start timer
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            dt.Start();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        void dt_Tick(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            // &lt;span style="color: #0000ff"&gt;Call&lt;/span&gt; web service
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            CallWebService();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;string&lt;/span&gt; GetWebserviceAddress()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; strXapFile = @"&lt;span style="color: #8b0000"&gt;/ClientBin/SilverlightKeepLoggedIn.xap&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; strBaseWebAddress = 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                App.Current.Host.Source.AbsoluteUri.Replace(strXapFile, "&lt;span style="color: #8b0000"&gt;&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;string&lt;/span&gt;.Format(@"&lt;span style="color: #8b0000"&gt;{0}/{1}&lt;/span&gt;", strBaseWebAddress, "&lt;span style="color: #8b0000"&gt;WebService.asmx&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; void CallWebService()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            // &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; up web service &lt;span style="color: #0000ff"&gt;call&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            WebServiceSoapClient objWebServiceSoapClient = 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; WebServiceSoapClient();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            EndpointAddress MyEndpointAddress = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                EndpointAddress(GetWebserviceAddress());
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            // &lt;span style="color: #0000ff"&gt;Call&lt;/span&gt; web method
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            objWebServiceSoapClient.KeepAliveAsync();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;h4&gt;Download the DotNetNuke module&lt;/h4&gt;

&lt;p&gt;You can download the DotNetNuke 4+ module &lt;a href="http://www.adefwebserver.com/DotNetNukeHELP/files/SilverlightKeepLogged In_01.00.00_Install.zip"&gt;at this link&lt;/a&gt;.&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/77/Silverlight-Keep-Logged-In-Prevent-pages-from-timing-out.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/77/Silverlight-Keep-Logged-In-Prevent-pages-from-timing-out.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/77/Silverlight-Keep-Logged-In-Prevent-pages-from-timing-out.aspx</guid>
      <pubDate>Fri, 12 Feb 2010 14:51:08 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=77</trackback:ping>
    </item>
    <item>
      <title>Easy Simple &lt;strike&gt;Unit&lt;/strike&gt; umm Business Rule Testing (for DotNetNuke and Linq to SQL)</title>
      <description>&lt;p&gt;&lt;img src="http://www.adefwebserver.com/DotNetNukeHELP/Misc/UnitTesting/images/img4.jpg" width="412" height="110" /&gt;&lt;/p&gt;  &lt;p&gt;At my day job we have an advanced developer who was given a difficult project where he has to implement a dozen business rules. I’m talking “ask for a blessing before you go in” and “ask for forgiveness when you come out” complicated code.&lt;/p&gt;  &lt;p&gt;I watched him work on the code, and he is methodical at writing down the rules and writing a test case to make sure he properly implemented it.  This usually involves creating a “test case” by setting up data in the database just right and then clicking buttons and links and checking the expected output. I have worked with him over a year, and I can assure you he has probably deleted more good code than I have ever written. Everything is properly structured and segmented and the overall design will bring tears to you eyes with the beauty of it’s implementation.&lt;/p&gt;  &lt;p&gt;But management keeps asking for major changes.&lt;/p&gt;  &lt;p&gt;So I see this developer re-think his design and carefully re-factor his code to accommodate huge changes in requirements. He carefully retests all the existing business rules as he implements the new ones. Sometimes it takes hours for him to properly test everything. The guy is a total pro and he gets the job done. &lt;/p&gt;  &lt;p&gt;But, here is the problem. He is a contract programmer, and when he moves on to his next job guess who has to maintain the code… me!  &lt;/p&gt;  &lt;p&gt;I had a nightmare where management came up to me and they wanted to “enhance” that code “one more time”. How can I make management understand that it could take me 6 hours to make just one small change to the code? Yes the code is well designed but it simply cannot anticipate all the requirements that are being demanded of it. It constantly has to be re-factored and each re-factoring brings a very real risk of breaking existing code.&lt;/p&gt;  &lt;h4&gt;Unit Testing&lt;/h4&gt;  &lt;p&gt;I am sure we have all read blogs on “getting started with unit testing”. They show a simple test that calls a method that returns some prime number. First the test fails because the code has not been written, next, they write the code and the test passes. “Wow this is great” you say, and then look for some examples where they connect to the database. &lt;/p&gt;  &lt;p&gt;Now you are wading through a lot of complicated examples to Initialize() and Cleanup() to get the data just right. You are actually spending considerable time to “set-up a valid test” and then return the data to the previous state so the test is repeatable.  When you realize that there is more code to “properly Unit Test” than there is in the project it’s self you come to the conclusion that  it is not worth it. Just fix the bugs as they come, it will take less time.&lt;/p&gt;  &lt;p&gt;However, in this case I needed Unit Tests to manage the complexity of the business rules. I really don’t care about “proper code coverage” and “proper isolation”, I just want something to help me so I don’t lie awake at 2:00 am thinking about accidently breaking some very important code.&lt;/p&gt;  &lt;h4&gt;Easy &lt;strike&gt;Unit&lt;/strike&gt; Business Rule Testing&lt;/h4&gt;  &lt;p&gt;There is wonderful stuff out there on Unit Testing but I needed something simple and easy. A Unit Test purist would pass out from shock at the manner I butcher the normal Unit Testing paradigm. &lt;/p&gt;  &lt;p&gt;The main thing I did was only test the specific methods I cared about, and only for business rule adherence. I load up a bunch of sample data and then toss it into a business object and check the expected result. Since I am using Linq to SQL, it is easy to implement the ‘Repository Pattern” and substitute my sample tables for real ones. The code doesn’t realize that it is not connecting to a real database and produces the same output for the same input every time.&lt;/p&gt;  &lt;p&gt;But understand, when others talk about Unit testing, this is not what they mean. You should be testing each method inside the business object. If all tests pass you then know that the any re-factoring “should” not have broken anything.&lt;/p&gt;  &lt;p&gt;This is Unit Testing for the guy who buys Life Insurance only if he plans to travel. I just call the methods on the “outside” of the business object and ask for an expected result. If I need to, I can test specific methods “on the inside” (methods that are called by the primary methods).&lt;/p&gt;  &lt;p&gt;So it isn’t really Unit Testing, I guess it’s “Business Rule Testing”.&lt;/p&gt;  &lt;p&gt;You can read the article here:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.adefwebserver.com/DotNetNukeHELP/Misc/UnitTesting/" href="http://www.adefwebserver.com/DotNetNukeHELP/Misc/UnitTesting/"&gt;http://www.adefwebserver.com/DotNetNukeHELP/Misc/UnitTesting/&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/76/Easy-Simple-lt-strike-gt-Unit-lt-strike-gt-umm-Business-Rule-Testing-for-DotNetNuke-and-Linq-to-SQL.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/76/Easy-Simple-lt-strike-gt-Unit-lt-strike-gt-umm-Business-Rule-Testing-for-DotNetNuke-and-Linq-to-SQL.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/76/Easy-Simple-lt-strike-gt-Unit-lt-strike-gt-umm-Business-Rule-Testing-for-DotNetNuke-and-Linq-to-SQL.aspx</guid>
      <pubDate>Sun, 07 Feb 2010 00:34:29 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=76</trackback:ping>
    </item>
    <item>
      <title>ADefSignUp: Email Sign-Up and Verification Module</title>
      <description>&lt;p&gt;&lt;img src="http://www.adefwebserver.com/DotNetNukeHELP/Misc/SignUp/images/img9.jpg" width="346" height="167" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;I just posted a module that allows you to easily create a sign-up list of verified email addresses.&lt;/p&gt;  &lt;p&gt;A DotNetNuke portal administrator can place an instance of the module on a page and customize the sign-up message and the email verification message. The captured data can also be exported to Excel.&lt;/p&gt;  &lt;p&gt;The module and code are posted here:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.adefwebserver.com/DotNetNukeHELP/Misc/SignUp/" href="http://www.adefwebserver.com/DotNetNukeHELP/Misc/SignUp/"&gt;http://www.adefwebserver.com/DotNetNukeHELP/Misc/SignUp/&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/74/ADefSignUp-Email-Sign-Up-and-Verification-Module.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/74/ADefSignUp-Email-Sign-Up-and-Verification-Module.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/74/ADefSignUp-Email-Sign-Up-and-Verification-Module.aspx</guid>
      <pubDate>Wed, 03 Feb 2010 14:44:52 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=74</trackback:ping>
    </item>
    <item>
      <title>DotNetNuke 5 Hello World II (Using a Database)</title>
      <description>&lt;h3&gt;How to make a simple Module using DotNetNuke 5 that connects to the Database&lt;/h3&gt;
&lt;p&gt;Use the following tutorial to create a simple &lt;strong&gt;Hello World DotNetNuke 5 Module&lt;/strong&gt;. it will be used as the starting point for this tutorial:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://www.adefwebserver.com/DotNetNukeHELP/DNN5_HelloWorld/Default.htm"&gt;&lt;u&gt;&lt;font color="#800080"&gt;DotNetNuke 5 Hello World&lt;/font&gt;&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img width="179" height="253" alt="" src="http://www.adefwebserver.com/DotNetNukeHELP/DNN5_HelloWorld/images/img16.jpg" /&gt;&lt;/p&gt;&lt;a href=http://openlightgroup.net/Blog/tabid/58/EntryId/72/DotNetNuke-5-Hello-World-II-Using-a-Database.aspx&gt;More...&lt;/a&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/72/DotNetNuke-5-Hello-World-II-Using-a-Database.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/72/DotNetNuke-5-Hello-World-II-Using-a-Database.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/72/DotNetNuke-5-Hello-World-II-Using-a-Database.aspx</guid>
      <pubDate>Sun, 17 Jan 2010 19:27:16 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=72</trackback:ping>
    </item>
    <item>
      <title>DotNetNuke 5 Hello World</title>
      <description>&lt;p&gt;&lt;img width="301" height="132" alt="" src="http://www.adefwebserver.com/DotNetNukeHELP/DNN5_HelloWorld/images/img2B.gif" /&gt;&lt;/p&gt;
&lt;p&gt;How to make a simple Hello World Module using DotNetNuke 5...&lt;/p&gt;&lt;a href=http://openlightgroup.net/Blog/tabid/58/EntryId/71/DotNetNuke-5-Hello-World.aspx&gt;More...&lt;/a&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/71/DotNetNuke-5-Hello-World.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/71/DotNetNuke-5-Hello-World.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/71/DotNetNuke-5-Hello-World.aspx</guid>
      <pubDate>Sun, 17 Jan 2010 15:01:45 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=71</trackback:ping>
    </item>
    <item>
      <title>Silverlight Message Board using the CloudDB.com “cloud” database</title>
      <description>&lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/67/WLW-CloudDB.comASP.NETSilverlight_57D1-image_16.png"&gt;&lt;img title="image" border="0" alt="image" width="308" height="262" style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" src="/Portals/0/Blog/Files/1/67/WLW-CloudDB.comASP.NETSilverlight_57D1-image_thumb_7.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click here for the live example:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.adefwebserver.com/silverlight/CloudDBSilverlight/Default.aspx" href="http://www.adefwebserver.com/silverlight/CloudDBSilverlight/Default.aspx"&gt;&lt;u&gt;&lt;font color="#800080"&gt;http://www.adefwebserver.com/silverlight/CloudDBSilverlight/Default.aspx&lt;/font&gt;&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/67/WLW-CloudDB.comASP.NETSilverlight_57D1-image_2.png"&gt;&lt;u&gt;&lt;font color="#800080"&gt;&lt;img title="image" border="0" alt="image" width="361" height="60" style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" src="/Portals/0/Blog/Files/1/67/WLW-CloudDB.comASP.NETSilverlight_57D1-image_thumb.png" /&gt;&lt;/font&gt;&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I checked Twitter yesterday and saw a post about &lt;a href="http://clouddb.com/"&gt;&lt;u&gt;&lt;font color="#800080"&gt;CloudDB.com&lt;/font&gt;&lt;/u&gt;&lt;/a&gt; giving away free invites...&lt;/p&gt;&lt;a href=http://openlightgroup.net/Blog/tabid/58/EntryId/67/Silverlight-Message-Board-using-the-CloudDB-com-ldquo-cloud-rdquo-database.aspx&gt;More...&lt;/a&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/67/Silverlight-Message-Board-using-the-CloudDB-com-ldquo-cloud-rdquo-database.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/67/Silverlight-Message-Board-using-the-CloudDB-com-ldquo-cloud-rdquo-database.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/67/Silverlight-Message-Board-using-the-CloudDB-com-ldquo-cloud-rdquo-database.aspx</guid>
      <pubDate>Sat, 09 Jan 2010 22:47:51 GMT</pubDate>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=67</trackback:ping>
    </item>
    <item>
      <title>Closed Captioning with Silverlight (using MVVM)</title>
      <description>&lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/65/WLW-ClosedCaptioningwithSilverlight_13096-image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/1/65/WLW-ClosedCaptioningwithSilverlight_13096-image_thumb.png" width="244" height="238" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Live example: &lt;a title="http://www.adefwebserver.com/silverlight/SilverlightCaptioning/SilverlightDynamicMediaMarkers/" href="http://www.adefwebserver.com/silverlight/SilverlightCaptioning/SilverlightDynamicMediaMarkers/"&gt;http://www.adefwebserver.com/silverlight/SilverlightCaptioning/SilverlightDynamicMediaMarkers/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is another one of my “this blog post is not really about what this blog post is about”. Yes, I will deliver on what the title promises, but creating closed captaining with Silverlight is actually very easy. The thing that took me so much time to put together, was implementing a “MVVM like” pattern and have a code behind that has no application logic and looks like this:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Controls;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; SilverlightDynamicMediaMarkers
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MainPage : UserControl
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; MainPage()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            InitializeComponent();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;       }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;From what I understand, it means that each layer is de-coupled and independently testable. When you change a caption and restart the video, it picks up the changes through bindings to dependency properties that are automatically updated.&lt;/p&gt;

&lt;p&gt;But, first…&lt;/p&gt;

&lt;h2&gt;Creating Closed Captioning with Silverlight 3.0&lt;/h2&gt;

&lt;p&gt;The Silverlight 3 &lt;strong&gt;MediaElement&lt;/strong&gt; allows you to create a collection of &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.timelinemarker(VS.95).aspx"&gt;TimelineMarkers&lt;/a&gt; like this:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;TimelineMarker objTimelineMarker1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimelineMarker();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;objTimelineMarker1.Text = Caption1;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;objTimelineMarker1.Time = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeSpan(0, 0, 5);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;objTimelineMarker1.Type = "&lt;span style="color: #8b0000"&gt;Start&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;TimelineMarker objTimelineMarker2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimelineMarker();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;objTimelineMarker2.Text = "&lt;span style="color: #8b0000"&gt;&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;objTimelineMarker2.Time = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeSpan(0, 0, 10);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;objTimelineMarker2.Type = "&lt;span style="color: #8b0000"&gt;Stop&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;TimelineMarkerCollection colTimelineMarkerCollection =
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; TimelineMarkerCollection();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;colTimelineMarkerCollection.Add(objTimelineMarker1);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;colTimelineMarkerCollection.Add(objTimelineMarker2);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;And attach them to the media like this:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; 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;void&lt;/span&gt; UpdateTimelineMarkers()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// Clear existing Markers&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;.media.Markers.Clear();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; (MediaTimelineMarkerCollection != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #008000"&gt;// Add Markers&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var Marker &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; MediaTimelineMarkerCollection)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            TimelineMarker objTimelineMarker = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimelineMarker();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            objTimelineMarker.Text = Marker.Text;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            objTimelineMarker.Time = Marker.Time;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            objTimelineMarker.Type = Marker.Type;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;.media.Markers.Add(objTimelineMarker);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;As the media is playing (this can be a video or even a Mp3 file) the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.markerreached(VS.95).aspx"&gt;MarkerReached Event&lt;/a&gt; will fire, passing an instance of the marker as an argument. It can then be used to display subtitles in a text box that is overlain on top of the video.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; 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; media_MarkerReached(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    TimelineMarkerRoutedEventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ClosedCaption.Visibility = (e.Marker.Type == "&lt;span style="color: #8b0000"&gt;Start&lt;/span&gt;") 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        ? Visibility.Visible : 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        Visibility.Collapsed;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ClosedCaption.Text = e.Marker.Text.ToString();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;Note, that you could use the media markers for a lot of other things such as triggering a JavaScript method on the hosting .html page that causes other things on the page to change.&lt;/p&gt;

&lt;p&gt;You can also create media markers and embed them in the media using a product such as Microsoft Expression Blend.&lt;/p&gt;

&lt;h2&gt;The Closed Captioning Program&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/65/WLW-ClosedCaptioningwithSilverlight_13096-image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/1/65/WLW-ClosedCaptioningwithSilverlight_13096-image_thumb_1.png" width="244" height="237" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Implementing closed captaining will take you about 5 minutes. However, my desire was to create a program that would allow you to enter captions on the fly and when you re-start the video, you would see them. Note, you have to stop, rewind a bit, and restart the video to get new captions to show up. You hover over the video to get the play control to show so you can stop the video.&lt;/p&gt;

&lt;p&gt;I could have simply put a button on the page that would reload the video, but I wanted to use bindings to tie everything together in a “MVVM like” architecture &lt;/p&gt;

&lt;p&gt;&lt;em&gt;I say “MVVM like” because it is hard to get two people to agree on what MVVM is in Silverlight means because apparently Silverlight 3 does not allow “true MVVM” because it is missing things like commanding and triggers. There are &lt;a href="http://www.galasoft-lb.ch/mvvm/getstarted/"&gt;frameworks&lt;/a&gt; available that get past these limitations.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;The Captions&lt;/h4&gt;

&lt;p&gt;First, I created 3 &lt;strong&gt;TextBoxes&lt;/strong&gt; to hold the Captions.&lt;/p&gt;

&lt;p&gt;I set bindings on each of the controls:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; 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;TextBox&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;"txtCaption1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding Caption1, Mode=TwoWay, UpdateSourceTrigger=Default}"&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #ff0000"&gt;TextWrapping&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Wrap"&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;The bindings work because I set a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.datacontext(VS.95).aspx"&gt;DataContext&lt;/a&gt; on the Parent object that they are contained in, to a class called &lt;strong&gt;ViewModel&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;xmlns:local="clr-namespace:SilverlightDynamicMediaMarkers"&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;Canvas&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;"LayoutRoot"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;Canvas.DataContext&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;local&lt;/span&gt;:&lt;span style="color: #800000"&gt;ViewModel&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;Canvas.DataContext&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;In the &lt;strong&gt;ViewModel&lt;/strong&gt; class I created a &lt;strong&gt;ObservableCollection&lt;/strong&gt; of TimeLineMarkers property and set the &lt;strong&gt;TimelineMarkers&lt;/strong&gt; property to rebuild each time one of the captions is changed. This happens because the binding is set to TwoWay and the &lt;strong&gt;ViewModel&lt;/strong&gt; class implements the &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(VS.95).aspx"&gt;INotifyPropertyChanged interface&lt;/a&gt;&lt;/strong&gt; and the Caption properties trigger &lt;strong&gt;NotifyPropertyChanged&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;#region Caption1
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;string&lt;/span&gt; Caption1
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;this&lt;/span&gt;._Caption1;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;value&lt;/span&gt; != &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._Caption1)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;._Caption1 = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            NotifyPropertyChanged("&lt;span style="color: #8b0000"&gt;Caption1&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            TimelineMarkers = BuildTimelineMarkers();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;#endregion&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h4&gt;The Video Player&lt;/h4&gt;

&lt;p&gt;The &lt;a href="http://www.codeplex.com/blacklight"&gt;Blacklight Codeplex project&lt;/a&gt; has a great set of controls with full source code. I took the video player from that project and added a &lt;strong&gt;TextBlock&lt;/strong&gt; over the video player to display the captions.&lt;/p&gt;

&lt;p&gt;I now have a &lt;strong&gt;ViewModel&lt;/strong&gt; class that is bound to the user interface. When you change a caption and move focus from the &lt;strong&gt;TextBox&lt;/strong&gt;, the &lt;strong&gt;TimelineMarkers&lt;/strong&gt; property will be rebuilt. You can set a break point in the code and see this for yourself.&lt;/p&gt;

&lt;p&gt;Now, I need to bind the video player in the &lt;strong&gt;MediaPlayer&lt;/strong&gt; control to the collection of &lt;strong&gt;TimelineMarkers&lt;/strong&gt; in &lt;strong&gt;ViewModel&lt;/strong&gt;. To do this, I created &lt;a href="http://www.kirupa.com/blend_silverlight/dependency_properties_pg1.htm"&gt;dependency property&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;UpdateTimelineMarkers()&lt;/strong&gt; method in the &lt;strong&gt;MediaPlayer&lt;/strong&gt; control, (listed above) gets the TimelineMarkers from the collection contained in the &lt;strong&gt;MediaTimelineMarkers&lt;/strong&gt; property of the &lt;strong&gt;MediaPlayer&lt;/strong&gt; control. Here is the code for that property:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; 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; ObservableCollection&lt;TimelineMarker&gt; MediaTimelineMarkerCollection
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    { 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        (ObservableCollection&lt;TimelineMarker&gt;)GetValue(MediaTimelineMarkerProperty); 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; { SetValue(MediaTimelineMarkerProperty, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;); }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;This property reads and sets the MediaTimelineMarkerProperty dependency property. here is the declaration for that property:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; 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;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; DependencyProperty MediaTimelineMarkerProperty =
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    DependencyProperty.Register("&lt;span style="color: #8b0000"&gt;MediaTimelineMarkerCollection&lt;/span&gt;", 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ObservableCollection&lt;TimelineMarker&gt;), &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(MediaPlayer), 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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; PropertyMetadata(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PropertyChangedCallback(MediaTimelineMarker_Changed)));&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;This declaration contains a pointer to &lt;strong&gt;MediaTimelineMarker_Changed&lt;/strong&gt; that will fire whenever it is changed. Here is the code for that method:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; 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;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; MediaTimelineMarker_Changed(DependencyObject 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    MediaPlayer mediaPlayer = (MediaPlayer)dependencyObject;            
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    mediaPlayer.MediaTimelineMarkerCollection = 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        (ObservableCollection&lt;TimelineMarker&gt;)eventArgs.NewValue;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; 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;This allows us to bind the &lt;strong&gt;TimelineMarkers&lt;/strong&gt; collection in &lt;strong&gt;ViewModel,&lt;/strong&gt; to the &lt;strong&gt;MediaTimelineMarkerCollection&lt;/strong&gt; in the  MediaPlayer control, by using simple binding code (in MainPage.xaml) like this:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; 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;controls&lt;/span&gt;:&lt;span style="color: #800000"&gt;MediaPlayer&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;"myMediaPlayer"&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #ff0000"&gt;MediaTimelineMarkerCollection&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding TimelineMarkers, Mode=TwoWay, UpdateSourceTrigger=Default}"&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #ff0000"&gt;MediaSource&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Media/niceday.wmv"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"27"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"32"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"248"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"365"&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;h2&gt;MVVM The good and the Bad&lt;/h2&gt;

&lt;p&gt;A lot of time was lost in creating this program when I had a typo in my Dependency property declaration. Also, when you make a mistake with a binding in XAML you wont always get a compile-time error, you will get a run-time error.&lt;/p&gt;

&lt;p&gt;However, consuming the video player and binding to it’s properties using declarative binding and collections that automatically update does require less code. &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Download the code here:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.adefwebserver.com/silverlight/SilverlightCaptioning/SilverlightDynamicMediaMarkers.zip" href="http://www.adefwebserver.com/silverlight/SilverlightCaptioning/SilverlightDynamicMediaMarkers.zip"&gt;http://www.adefwebserver.com/silverlight/SilverlightCaptioning/SilverlightDynamicMediaMarkers.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="460" height="430" autoupdate="true"&gt;
&lt;param name="source" value="http://www.adefwebserver.com/silverlight/SilverlightCaptioning/SilverlightDynamicMediaMarkers/ClientBin/SilverlightDynamicMediaMarkers.xap" /&gt;
&lt;param name="minRuntimeVersion" value="3.0.40624.0" /&gt;
&lt;param name="background" value="White" /&gt;
&lt;param name="autoUpgrade" value="true" /&gt;
&lt;a href="http://go.microsoft.com/fwlink/?LinkID=149156&amp;v=3.0.40624.0" style="text-decoration:none"&gt;
         			  &lt;img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none" /&gt; &lt;/a&gt;
&lt;/object&gt;&lt;/p&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/65/Closed-Captioning-with-Silverlight-using-MVVM.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/65/Closed-Captioning-with-Silverlight-using-MVVM.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/65/Closed-Captioning-with-Silverlight-using-MVVM.aspx</guid>
      <pubDate>Sat, 02 Jan 2010 18:03:25 GMT</pubDate>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=65</trackback:ping>
    </item>
    <item>
      <title>Crossing Silverlight Objects</title>
      <description>&lt;p&gt;&lt;a href="http://openlightgroup.net/Portals/0/Blog/Files/1/64/WLW-CrossingSilverlightObjects_60F8-image_2.png"&gt;&lt;img title="image" border="0" alt="image" width="431" height="180" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" src="/Portals/0/Blog/Files/1/64/WLW-CrossingSilverlightObjects_60F8-image_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Live Example:&lt;/strong&gt; &lt;a title="http://www.adefwebserver.com/silverlight/SilverlightOrb/SilverlightOrbv1/" href="http://www.adefwebserver.com/silverlight/SilverlightOrb/SilverlightOrbv1/"&gt;&lt;u&gt;&lt;font color="#800080"&gt;http://www.adefwebserver.com/silverlight/SilverlightOrb/SilverlightOrbv1/&lt;/font&gt;&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is actually a failed experiment. The theory was that XAMl contains all the visual elements you need to “cross” two Silverlight objects to create child objects that resemble the parents.&lt;/p&gt;
&lt;p&gt;However, a failed experiment is no reason to let code go to waste!&lt;/p&gt;
&lt;p&gt;Along the way I learned some things:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;How to display XAML elements in a drop down&lt;/li&gt;
    &lt;li&gt;How to zoom in on elements using a Viewbox and a ScrollViewer&lt;/li&gt;
&lt;/ul&gt;&lt;a href=http://openlightgroup.net/Blog/tabid/58/EntryId/64/Crossing-Silverlight-Objects.aspx&gt;More...&lt;/a&gt;</description>
      <link>http://openlightgroup.net/Blog/tabid/58/EntryId/64/Crossing-Silverlight-Objects.aspx</link>
      <author>webmaster@openlightgroup.net</author>
      <comments>http://openlightgroup.net/Blog/tabid/58/EntryId/64/Crossing-Silverlight-Objects.aspx#Comments</comments>
      <guid isPermaLink="true">http://openlightgroup.net/Blog/tabid/58/EntryId/64/Crossing-Silverlight-Objects.aspx</guid>
      <pubDate>Sun, 27 Dec 2009 15:51:26 GMT</pubDate>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://openlightgroup.net/DesktopModules/Blog/Trackback.aspx?id=64</trackback:ping>
    </item>
  </channel>
</rss>