<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.11.5 (http://www.squarespace.com/) on Fri, 03 Sep 2010 14:08:14 GMT--><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rss="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:cc="http://web.resource.org/cc/"><rss:channel rdf:about="http://johnliu.net/blog/"><rss:title>John Liu .NET: Time for Fun in .NET</rss:title><rss:link>http://johnliu.net/blog/</rss:link><rss:description></rss:description><dc:language>en-US</dc:language><dc:date>2010-09-03T14:08:14Z</dc:date><admin:generatorAgent rdf:resource="http://www.squarespace.com/">Squarespace Site Server v5.11.5 (http://www.squarespace.com/)</admin:generatorAgent><rss:items><rdf:Seq><rdf:li rdf:resource="http://johnliu.net/blog/2010/8/30/silverlight-radscheduler-and-required-field-data-validation.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/8/13/sharepoint-enable-ifilter-for-tiff-ocr.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/8/12/sharepoint-saturday-sydney.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/8/6/sharepoint-2010-globalnavigationnodes-moved.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/22/sharepoint-2010-with-iis-url-rewrite-20.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/20/sydney-sharepoint-user-group-20-july-2010.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/19/silverlight-code-behind-back-to-mvvm.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/15/sharepoint-clientcontextlist-is-missing.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/16/sharepoint-2010-and-silverlight-40-webcam.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/15/sharepoint-2010-update-all-list-items-sharepoint-designer-wo.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/13/silverlight-merging-detached-object-back-to-the-attached-dat.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/13/sharepoint-2010-configuring-list-item-permissions-with-workf.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/12/windows-live-messenger-wave-4-redirus-freaks-me-out.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/10/silverlight-pivotviewer-and-sharepoint.html"/><rdf:li rdf:resource="http://johnliu.net/blog/2010/7/7/silverlight-unit-testing-adding-a-timeout-to-enqueueconditio.html"/></rdf:Seq></rss:items></rss:channel><rss:item rdf:about="http://johnliu.net/blog/2010/8/30/silverlight-radscheduler-and-required-field-data-validation.html"><rss:title>Silverlight - RadScheduler and required field data validation</rss:title><rss:link>http://johnliu.net/blog/2010/8/30/silverlight-radscheduler-and-required-field-data-validation.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-08-30T14:11:52Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>In my current project I'm having the pleasure of working with the Silverlight RadScheduler control.&#160; While you may read and feel it is a very bloated control, I argue otherwise, it is highly extensible for such a complex control.&#160; I really think the Telerik guys did a very good job.</p>  <p>My particular scenario is interesting.&#160; I need to:</p>  <ol>   <li>Extend the appointment dialog to support addresses</li>    <li>The addresses aren't always required (so I can't just use RequiredAttribute)</li>    <li>When fields are required, I'd like the validation to kick off and prevent me from saving that appointment</li> </ol>  <p>Here we go:</p>  <h2>Updating the RadScheduler template:</h2>  <p>This is pretty simple - find the EditAppointmentTemplate</p>  <pre class="csharpcode">  <span class="kwrd">&lt;</span><span class="html">ControlTemplate</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;EditAppointmentTemplate&quot;</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;telerik:AppointmentDialogWindow&quot;</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<ol>
  <li>Customize the control template, we added additional fields</li>

  <li>NotifyOnValidationError and ValidatesOnException are important.</li>
</ol>

<pre class="csharpcode">..snip

          <span class="kwrd">&lt;</span><span class="html">input:ValidationSummary</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;ValidationSummary&quot;</span> <span class="kwrd">/&gt;</span>

          <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;Suburb&quot;</span> <span class="attr">Style</span><span class="kwrd">=&quot;{StaticResource FormElementTextBlockStyle}&quot;</span><span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">TextBox</span> <span class="attr">Text</span><span class="kwrd">=&quot;{Binding Suburb, Mode=TwoWay, NotifyOnValidationError=True, <br /></span><span class="kwrd">ValidatesOnExceptions=True}&quot;</span>  <span class="kwrd">/&gt;</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<h2>Extend the Appointment class:</h2>

<ol>
  <li>Create a ValidationEnabled property - sometimes you need to &quot;not validate&quot;</li>

  <li>Create a ValidateProperty method - this takes a property name and triggers all validate attributes on that property - Validator.ValidateProperty is the method that will trigger all kinds of fun validation exceptions for us.</li>

  <li>Set the appropriate validation attributes on the property e.g. Suburb - I'm using a custom validation property that I've created based on the RequiredAttribute</li>

  <li>In the setter, call ValidateProperty.</li>
</ol>

<pre class="csharpcode">    <span class="kwrd">public</span> <span class="kwrd">class</span> JobAppointment : Appointment
    {
        <span class="kwrd">private</span> <span class="kwrd">string</span> _suburb;

        <span class="kwrd">public</span> ObservableCollection&lt;ValidationError&gt; Errors { get; set; }

        <span class="kwrd">public</span> <span class="kwrd">bool</span> ValidationEnabled
        {
            get;
            set;
        }

        <span class="kwrd">private</span> <span class="kwrd">void</span> ValidateProperty(<span class="kwrd">string</span> propertyName, <span class="kwrd">object</span> <span class="kwrd">value</span>)
        {
            <span class="kwrd">if</span> (ValidationEnabled)
            {
                var context = <span class="kwrd">new</span> ValidationContext(<span class="kwrd">this</span>, <span class="kwrd">null</span>, <span class="kwrd">null</span>);
                context.MemberName = propertyName;

                Validator.ValidateProperty(<span class="kwrd">value</span>, context);
            }
        }

        [ValidationRequired]
        <span class="kwrd">public</span> <span class="kwrd">string</span> Suburb
        {
            get
            {
                <span class="kwrd">return</span> _suburb;
            }
            set
            {
                ValidateProperty(<span class="str">&quot;Suburb&quot;</span>, <span class="kwrd">value</span>);

                <span class="kwrd">if</span> (_suburb != <span class="kwrd">value</span>)
                {
                    _suburb = <span class="kwrd">value</span>;
                    OnPropertyChanged(<span class="str">&quot;Suburb&quot;</span>);
                }
            }
        }</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<h2>Add our own Validation attributes</h2>

<ol>
  <li>This Required attribute checks against our settings to see if &quot;Suburb&quot; happens to be a required field.&#160; If not, then skip the validation and just return success.</li>
</ol>

<pre class="csharpcode"> <span class="kwrd">public</span> <span class="kwrd">class</span> ValidationRequiredAttribute : RequiredAttribute
    {
        <span class="kwrd">protected</span> <span class="kwrd">override</span> ValidationResult IsValid(<span class="kwrd">object</span> <span class="kwrd">value</span>, ValidationContext validationContext)
        {
            <span class="kwrd">if</span> (SettingsLifeTimeService.Current != <span class="kwrd">null</span> )
            {
                <span class="kwrd">if</span> (SettingsLifeTimeService.Current.RequiredFields.Contains(validationContext.MemberName))
                {
                    <span class="rem">// RequiredAttribute validation</span>
                    <span class="kwrd">return</span> <span class="kwrd">base</span>.IsValid(<span class="kwrd">value</span>, validationContext);
                }
            }
            <span class="kwrd">return</span> ValidationResult.Success;
        }
    }</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>&#160;</p>

<h2>Stop validation on Scheduler's Appointment_Saving event</h2>

<ol>
  <li>In the AppointmentSaving event, grab all the children framework elements from the appointment dialog window</li>

  <li>Find their binding expression (e.g., for TextBox I want the binding expression for Textbox.Text)</li>

  <li>If exists, I want it to push the values back into the datasource (our customized Appointment class) - this triggers the property setter (which triggers our ValidateProperty, which triggers the custom Required attribute)</li>

  <li>Finally, check the validation summary to see if we have any binding errors, if we do, cancel the save.</li>
</ol>

<pre class="csharpcode"><span class="kwrd">void</span> _scheduler_AppointmentSaving(<span class="kwrd">object</span> sender, AppointmentSavingEventArgs e)
        {
            JobAppointment jobApp = e.Appointment <span class="kwrd">as</span> JobAppointment;
            AppointmentDialogWindow window = e.OriginalSource <span class="kwrd">as</span> AppointmentDialogWindow;
            var children = window.ChildrenOfType&lt;FrameworkElement&gt;();

            <span class="kwrd">if</span> (children != <span class="kwrd">null</span>)
            {
                <span class="kwrd">foreach</span> (var element <span class="kwrd">in</span> children)
                {
                    BindingExpression binding = <span class="kwrd">null</span>;
                    <span class="kwrd">if</span> (element <span class="kwrd">is</span> TextBox)
                    {
                        binding = element.GetBindingExpression(TextBox.TextProperty);
                    }

                    <span class="kwrd">if</span> (binding != <span class="kwrd">null</span>)
                    {
                        <span class="rem">// force control to update databound VM.  This triggers the validation.</span>
                        binding.UpdateSource();
                    }
                }
            }

            ValidationSummary summary = window.FindChildByType&lt;ValidationSummary&gt;();

            <span class="kwrd">if</span> (summary != <span class="kwrd">null</span>)
            {
                <span class="kwrd">if</span> (summary.HasErrors)
                {
                    e.Cancel = <span class="kwrd">true</span>;
                    <span class="kwrd">return</span>;
                }
            }
        }</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<h2>Finished!</h2>

<p>&#160;</p>

<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SilverlightRadScheduleranddatavalidation_14E5D-?fileId=8340392"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/WindowsLiveWriter-SilverlightRadScheduleranddatavalidation_14E5D-?fileId=8340393" width="650" height="155" /></a></p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/8/13/sharepoint-enable-ifilter-for-tiff-ocr.html"><rss:title>SharePoint enable iFilter for TIFF OCR</rss:title><rss:link>http://johnliu.net/blog/2010/8/13/sharepoint-enable-ifilter-for-tiff-ocr.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-08-13T11:23:56Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>In some companies, paper documents are scanned into TIFF formats and stored electronically.&#160; To search for them, you'll need to enable the TIFF OCR iFilter to allow SharePoint to index TIFF documents.</p>  <p>1. Install Windows Server feature <strong>Windows TIFF IFilter</strong>:</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePointimplementiFilterforTIFFOCR_12AC9-?fileId=8114683"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://johnliu.net/resource/WindowsLiveWriter-SharePointimplementiFilterforTIFFOCR_12AC9-?fileId=8114684" width="580" height="429" /></a></p>  <p>&#160;</p>  <p>2. <strong>Enable OCR filter</strong></p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePointimplementiFilterforTIFFOCR_12AC9-?fileId=8114685"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002[7]" border="0" alt="clip_image002[7]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePointimplementiFilterforTIFFOCR_12AC9-?fileId=8114686" width="580" height="407" /></a></p>  <br />    <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePointimplementiFilterforTIFFOCR_12AC9-?fileId=8114687"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002[10]" border="0" alt="clip_image002[10]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePointimplementiFilterforTIFFOCR_12AC9-?fileId=8114688" width="580" height="531" /></a></p>  <p>&#160;</p>  <p>3. You may need to restart the machine</p>  <p>4. Force SharePoint to perform a full crawl from Search Administration</p>  <p>5. Search for your file - here, I'm searching for &quot;Therefore&quot;</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePointimplementiFilterforTIFFOCR_12AC9-?fileId=8114689"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="tiff-ifilter2" border="0" alt="tiff-ifilter2" src="http://johnliu.net/resource/WindowsLiveWriter-SharePointimplementiFilterforTIFFOCR_12AC9-?fileId=8114691" width="793" height="726" /></a></p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/8/12/sharepoint-saturday-sydney.html"><rss:title>SharePoint Saturday Sydney</rss:title><rss:link>http://johnliu.net/blog/2010/8/12/sharepoint-saturday-sydney.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-08-12T20:04:06Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>Hi again.&#160; This is a rather delayed blog post summarizing SharePoint Saturday Sydney #SPSSydney that was held last weekend on 7th August 2010.&#160; This was organized by @BrianFarnhill and Lewis</p>  <p><strong>SILVERLIGHT AND SHAREPOINT APPLICATIONS</strong></p>  <p>Again, I brought along my little demo on <a href="http://johnliu.net/blog/2010/6/18/develop-and-deploy-silverlight-sharepoint-2010-solutions.html">Silverlight and SharePoint applications</a>, again heavily tweaked from my previous presentation in the <a href="http://johnliu.net/blog/2010/7/20/sydney-sharepoint-user-group-20-july-2010.html">SharePoint user group</a>.</p>  <p>The new agenda was:</p>  <ol>   <li>SharePoint + Silverlight Application</li>    <li>XAP Deployment and Sandbox Solutions</li>    <li>Debugging</li>    <li>Light up SharePoint - Out of Browser</li> </ol>  <p>I never did have enough time - it all finished so fast at 50minutes.&#160; And I didn't get to show my really awesome <a href="http://johnliu.net/blog/2010/7/15/sharepoint-2010-and-silverlight-40-webcam.html">Silverlight Camera</a> demo.&#160; </p>  <p>The strict timing was actually great - gave me good ideas about re-organizing the content.&#160; I should start quickly onto the demos, and then switch back to the PowerPoint summary points at the end as a summary, after people have seen the demo.&#160; That would have worked really well, and consolidated my time, as well as giving the talk a suitable finishing touch.</p>  <h3><strong>SHAREPOINT SATURDAY SYDNEY</strong></h3>  <p>With my talk out of the way I juggled the rest of the day between: helping out people wandering around looking slightly lost, or wanted to catch up on some examples of Silverlight applications.&#160; Ducking into sessions (usually at the 10minute mark where there's no one wandering outside anymore), to either learn something new, see how others present, or just to heckle another speaker and cheer them on!&#160; <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://johnliu.net/resource/WindowsLiveWriter-SharePointSaturdaySydney_4B03-?fileId=8103396" /></p>  <ul>   <li><a href="http://laneyvb.blogspot.com/">@laneyvb</a> - Workflow in SharePoint 2010</li>    <li><a href="http://www.sharingminds.com.au/rogercarran/Lists/Posts/Post.aspx?ID=9">Roger Carran</a> - The Managed Metadata Service - Exposed!</li>    <li><a href="http://www.sharepoint-tips.com/">Ishai Sagi</a> - New SharePoint 2010 features for End Users</li>    <li><a href="http://blog.brianfarnhill.com/">Brian Farnhill</a> - Exploring Office Web Applications and Services</li>    <li><a href="http://guru-web.blogspot.com/">Ivan Wilson</a> - Building a public blog on SharePoint 2010</li>    <li>Eric Cheng - Developing and Deploying SharePoint Customisations Using Visual Studio 2010     <br /></li> </ul>  <p>Between different sessions most people managed to stayed on until the very end (to win some prizes), and from the guys that I've talked to most of them are heading home with new ideas of using their SharePoint 2010.</p>  <p>All in all a day full of lots of fun and laughter.&#160; Thanks for organising this.</p>  <p>I took some panorama pictures with my iPhone and stitched them.</p>  <h3><strong>MORNING INTRODUCTION</strong></h3>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePointSaturdaySydney_4B03-?fileId=8103420"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="IMG_3206 Stitch" border="0" alt="IMG_3206 Stitch" src="http://johnliu.net/resource/WindowsLiveWriter-SharePointSaturdaySydney_4B03-?fileId=8103421" width="644" height="191" /></a></p>  <p>&#160;</p>  <h3><strong>AFTERNOON PANEL</strong></h3>  <p>   <br /><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePointSaturdaySydney_4B03-?fileId=8103422"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="IMG_3212 Stitch" border="0" alt="IMG_3212 Stitch" src="http://johnliu.net/resource/WindowsLiveWriter-SharePointSaturdaySydney_4B03-?fileId=8103423" width="644" height="238" /></a></p>   More pictures for <a href="http://www.facebook.com/album.php?aid=473161&amp;id=888000127">SharePoint Saturday Sydney 2010</a>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/8/6/sharepoint-2010-globalnavigationnodes-moved.html"><rss:title>SharePoint 2010 GlobalNavigationNodes Moved</rss:title><rss:link>http://johnliu.net/blog/2010/8/6/sharepoint-2010-globalnavigationnodes-moved.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-08-06T02:00:17Z</dc:date><dc:subject>SharePoint code</dc:subject><content:encoded><![CDATA[<p>This is a very short blog, but it appears that the GlobalNavigationNodes member on the PublishingWeb class has moved in SharePoint 2010.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.publishingweb.globalnavigationnodes%28office.12%29.aspx">http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.publishingweb.globalnavigationnodes(office.12).aspx</a></p>
<p>In SharePoint 2007, this was under Microsoft.SharePoint.Publishing.PublishingWeb.GlobalNavigationNodes</p>
<p><a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalnavigation.globalnavigationnodes.aspx ">http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalnavigation.globalnavigationnodes.aspx </a></p>
<p>In SP2010, this has moved under Microsoft.SharePoint.Publishing.PublishingWeb.Navigation.PortalNavigation.GlobalNavigationNodes</p>
<p>&nbsp;</p>
<p>This particular property is used to read a publishing site's navigation settings - I've used this to export site navigation as XML to accompany a site export.&nbsp; Since site exports doesn't seem to include any customized site navigation information.&nbsp; (It still doesn't in SP2010).</p>
<p>&nbsp;</p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/22/sharepoint-2010-with-iis-url-rewrite-20.html"><rss:title>SharePoint 2010 with IIS URL Rewrite 2.0</rss:title><rss:link>http://johnliu.net/blog/2010/7/22/sharepoint-2010-with-iis-url-rewrite-20.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-22T17:11:44Z</dc:date><dc:subject>code</dc:subject><content:encoded><![CDATA[<p>Or, how do you remove /Pages/ from SharePoint URL.</p>  <p>Almost all the hard work is done by <a href="http://blog.mastykarz.nl/">Waldek Mastykarz</a> (@waldekm)    <br /><a href="http://blog.mastykarz.nl/friendly-urls-sharepoint-site-4-steps-iis7-url-rewrite-module/">http://blog.mastykarz.nl/friendly-urls-sharepoint-site-4-steps-iis7-url-rewrite-module/</a></p>  <p>These are just my extra notes for SharePoint 2010, I'm going to assume you are reading Waldek's article with this blog as a supplement.</p>  <p><b>How to install IIS URL Rewrite</b></p>  <p>The easiest way is via the <a href="http://www.microsoft.com/web/downloads/platform.aspx">MS Web Platform Installer</a></p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821663"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821664" width="628" height="463" /></a></p>  <p>On a good connection you are good to go within 30 seconds - faster if you already have MS Web Platform Installer on the server.</p>  <p>Installed, IIS URL Rewrite 2.0 lives here</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821665"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821671" width="628" height="361" /></a></p>  <p><b>IIS URL Rewrite 2.0</b></p>  <p>I seriously think there's a bug with IIS Url Rewrite 2.0's Regex</p>  <p>Waldek's regex pattern for step 3 is perfect:</p>  <p>^(.*/)?Pages/([^/]+)\.aspx$</p>  <p>and so is step 4:</p>  <p>^(.*/)?Pages/default.aspx$</p>  <p>BUG: IIS URL Rewrite matches badly - see screenshot:</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821675"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821678" width="418" height="449" /></a></p>  <p>Regex will try to maximize to match as many characters as it can. But this simply does not explain why group 1 match includes Pages/ - Why was Pages/ included in the match? This doesn't make any sense.</p>  <p>You can test the pattern with any other regex library, including .NET (via PowerShell), and you still won't get the stupid buggy match that is IIS URL Rewrite's regex…</p>  <p>(Sorry I'm annoyed that this caused a lot of problem for something that shouldn't have existed...)</p>  <p>$pattern = [regex] &quot;^(.*/)?Pages/default.aspx$&quot;</p>  <p>$result = $pattern.match(&quot;Publishing/Pages/default.aspx&quot;)</p>  <p>$result.Groups[1]</p>  <p>Success : True</p>  <p><font style="background-color: #ffff00">Captures : {Publishing/}</font></p>  <p>Index : 0</p>  <p>Length : 11</p>  <p>Value : Publishing/</p>  <p>Anyway, to fix this we need to tweak the pattern</p>  <p>^(.*<font style="background-color: #ffff00">?</font>/)?Pages/([^/]+)\.aspx$</p>  <p>^(.*<font style="background-color: #ffff00">?</font>/)?Pages/default.aspx$</p>  <p>This will finally force IIS URL Rewrite to work properly. </p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821681"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821685" width="418" height="449" /></a></p>  <p>the extra ? tells regex to try to match as little as it can, while still making a match.</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821690"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821693" width="628" height="142" /></a></p>  <p>Final result – the order is important – see Waldek’s article</p>  <p>&#160;</p>  <p><b>TRICKS: Debugging URL Rewrite by enabling trace</b></p>  <p>When things don't work - this is your only hope. Read trace logs.</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821696"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821697" width="413" height="210" /></a></p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821700"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821701" width="380" height="219" /></a></p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821702"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image016" border="0" alt="clip_image016" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821703" width="580" height="443" /></a></p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821704"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image018" border="0" alt="clip_image018" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821705" width="580" height="443" /></a></p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821706"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image020" border="0" alt="clip_image020" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821708" width="580" height="443" /></a></p>  <p>Fortunately it's not very hard to read, I mean we read SharePoint logs and survived. It's just tedious to read logs in general.</p>  <p>Open the log in Internet Explorer - which picks up the XSL and gives you a nicer looking UI. Head over to the compact view tab, and look for URL_REWRITE_START</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821712"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image022" border="0" alt="clip_image022" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821714" width="628" height="389" /></a></p>  <p><b></b></p>  <p><b>HORRIBLE PITFALL: URL Rewrite Cache</b></p>  <p>I've noticed that when you reshuffle a rule (or add a condition to a rule), it doesn't force the cache to bugger off. So you thought you tweaked the rule but it doesn't seem to have any effect. The trace log will tell you that it actually is ignoring your rule reshuffle because it is listening to the &quot;Url Rewrite Cache&quot;.</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821716"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image024" border="0" alt="clip_image024" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821718" width="628" height="186" /></a></p>  <p>This is OK, until you have a bad URL cached, then suddenly it's annoying. IIS Reset doesn't cut it.&#160; My tip that I ended up with is to toggle a rule's disable/enable state to trigger the URL Rewrite cache to refresh. </p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821719"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image026" border="0" alt="clip_image026" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821721" width="326" height="139" /></a></p>  <p><b></b></p>  <p><b>SharePoint Authenticated</b></p>  <p>WARNING: I've had SharePoint on various unknown occasions suddenly raise a login dialogue. I can't reproduce this on demand, but it happens frequent enough that I think it's no accident. It also sometimes goes away when I hit F5 refresh and Windows Authentication just works and I don't see any login prompt at all.</p>  <p>The experience reminded me highly of the days in 2007 where sometimes SharePoint will mysteriously ask you to sign in when you are supposedly browsing the site anonymous.</p>  <p>Please test thoroughly.</p>  <p><b></b></p>  <p><b>SharePoint Anonymous </b></p>  <p>For a public anonymous website, this works absolutely great - no authentication to worry about either.</p>  <p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821724"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image028" border="0" alt="clip_image028" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010withURLRewrite_1258-?fileId=7821725" width="628" height="389" /></a></p>  <p>I didn't do much testing with the postbacks and the ribbon. They do work, but I think I'll need a lot more testing to work out if everything is still OK.</p>  <p>My gut feeling is that SharePoint 2010 relies a lot more on AJAX-based client side calls without a full page postback. While the URL rewrite would have affected the postback somewhat, AJAX calls would be largely immune to this problem.</p>  <p><b>Summary</b></p>  <p>Definitely try this out on your SharePoint site and I think you'll be surprised how well it worked (once you get it to work). Thanks <a href="http://blog.mastykarz.nl/">Waldek</a> for sharing!</p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/20/sydney-sharepoint-user-group-20-july-2010.html"><rss:title>Sydney SharePoint User Group 20 July 2010</rss:title><rss:link>http://johnliu.net/blog/2010/7/20/sydney-sharepoint-user-group-20-july-2010.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-20T12:47:03Z</dc:date><dc:subject>code</dc:subject><content:encoded><![CDATA[<p>Presented an updated version of my <a href="http://johnliu.net/blog/2010/6/17/develop-and-deploy-silverlight-sharepoint-2010-solutions.html">Silverlight and SharePoint solutions</a> talk in the <a href="http://sharepointusers.org.au/Sydney/default.aspx">Sydney user group</a> tonight.&nbsp; I don't think I timed the presentation well and lost way too much time in the beginning in XAML - which made everything seemed harder, and getting to the fun part much later.</p>
<ul>
<li>Will improve - won't type XAML again, will highlight what's interesting but avoid fiddling live.</li>
</ul>
<p>Honestly lots of room to improve but I think it was still interesting to a lot of people.&nbsp; If you were there tonight and feels otherwise please let me know!</p>
<p>Feedback I've received:</p>
<ol>
<li>Demo at least "worked" even though really slow going in the beginning 
<ul>
<li>Will improve, in fact given 1hr I don't think I'll type out the XAML again in the future - this will give me far more time to spend in the code, as well as getting to the fun part a lot quicker</li>
</ul>
</li>
<li>Need more time spend to show end-user Silverlight debugging (no modification to the server required)  
<ul>
<li>Which I think would be a lot better use of the time</li>
</ul>
</li>
<li>Need more time to show some nice integration examples 
<ul>
<li>Such as my <a href="http://johnliu.net/blog/2010/7/15/sharepoint-2010-and-silverlight-40-webcam.html">Silverlight Camera</a> which definitely raised eyebrows.</li>
<li>And if I can ever get my <a href="http://johnliu.net/blog/2010/7/9/silverlight-pivotviewer-and-sharepoint.html">Silverlight PivotViewer</a> to a decent, presentable state&hellip;</li>
<li>But basically, people need to see the features that Silverlight and SharePoint brings to the table separately, and why they are suddenly super awesome <strong>together</strong>.&nbsp; Have an idea to draw a chart that'll blow everyone away - wait for it on <a href="http://www.sharepointsaturday.org/sydney/Pages/meetings.aspx">SharePoint Saturday</a>.</li>
</ul>
</li>
<li>Something went wrong at the one-hour mark, where my IE decided to go offline, which made further demo really difficult.&nbsp; My suspicion is that Fiddler2 died somehow and IE thinks everything has gone funny and offline.&nbsp;  
<ul>
<li>Might have fixed itself by restarting IE.</li>
</ul>
</li>
<li>Definitely need more question time, and end with more links</li>
</ol>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>Lots of links for news:</strong></p>
<p>A bunch of links I promised Brad Saide, to add to the SharePoint news for the past month:</p>
<p>Productivity Hub 2010   <br /><a href="http://www.microsoft.com/downloads/details.aspx?familyid=4AAA9862-E420-4331-8BC3-469D7BAE0FF1&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?familyid=4AAA9862-E420-4331-8BC3-469D7BAE0FF1&amp;displaylang=en</a></p>
<p>SPF2010 Update via @dougleung <a href="http://sharepointsix.blogspot.com/2010/07/sharepoint-2010-sharepoint-2010-just.html">http://sharepointsix.blogspot.com/2010/07/sharepoint-2010-sharepoint-2010-just.html</a>&nbsp; <br /><a href="http://support.microsoft.com/kb/2032588">http://support.microsoft.com/kb/2032588</a></p>
<p>Windows Update broke WSS3 (with Windows Internal Database)   <br /><a href="http://blogs.msdn.com/b/sharepoint/archive/2010/06/22/installing-kb938444.aspx">http://blogs.msdn.com/b/sharepoint/archive/2010/06/22/installing-kb938444.aspx</a>&nbsp; <br />Lesson - <a href="http://sharepoint.ssw.com.au/Standards/SoftwareDevelopment/RulesToBetterSharePoint/Pages/Do-You-Turn-Off-Auto-Update-On-SharePoint-Servers.aspx">don't use automatic windows update on your production SharePoint farm</a></p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/19/silverlight-code-behind-back-to-mvvm.html"><rss:title>Silverlight - code behind back to MVVM</rss:title><rss:link>http://johnliu.net/blog/2010/7/19/silverlight-code-behind-back-to-mvvm.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-19T09:50:32Z</dc:date><dc:subject>code</dc:subject><content:encoded><![CDATA[<p><strong>Philosophical difference between code-behind and the ViewModel</strong></p>  <p>Because VS.NET is firstly a visual tool, it tries very hard to give developers an easy starting point where you can create your layout and easily add code to various events.</p>  <p>The problem this creates, is that the end result code in the events is a mixture of two type of code:</p>  <ul>   <li>Data access, relating to service calls, maintaining in memory state of the object.</li>    <li>Updates to the UI.</li> </ul>  <p>The former is what we’re trying to test, whereas the UI is always difficult to test, especially if compounded with animation or frequent changes to the UI.</p>  <p>&#160;</p>  <p><strong>Why do we need to do this?</strong></p>  <ul>   <li>Code-behind is part of the View, application logic doesn't belong here</li>    <li>Prolonged mixing of application logic WITH UI login in the code-behind leads to spaghetti code, the main issue is maintenance cost</li>    <li>Unable to easily separate and test functionality </li> </ul>  <p>&#160;</p>  <p><strong>Refactor and take control - bring Code Behind back into MVVM</strong></p>  <p>I tackle this problem in stages, without stages the problem is too big and you may not be able to stop halfway.</p>  <p><strong>Stage 1 - creating a ViewModel</strong></p>  <p>A ViewModel is a model for a view.&#160; So in your ViewModel you should have any information that is necessary for the UI (view) to render properly.&#160; Remember to implement INotifyPropertyChanged</p>  <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> MainViewModel : INotifyPropertyChanged
{
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>&#160;</p>

<p>Add the ViewModel to your View - this can be done in the XAML</p>

<pre class="csharpcode"> <span class="kwrd">&lt;</span><span class="html">UserControl.Resources</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ViewModel:MainViewModel</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;MainViewModelInstance&quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">UserControl.Resources</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>You can reference the ViewModel in your code behind this way:</p>

<pre class="csharpcode">var resourceMainViewModel = <span class="kwrd">this</span>.Resources[<span class="str">&quot;MainViewModelInstance&quot;</span>];
_mainViewModel = resourceMainViewModel <span class="kwrd">as</span> MainViewModel;</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>&#160;</p>

<p><strong>Stage 2 - moving application state variables to ViewModel</strong></p>

<p>A typical sign of a lot of code-behind is when we have a lot of member variables in the View.</p>

<ol>
  <li>A majority of them can be moved directly into the ViewModel.</li>

  <li>Provide property get/set on the ViewModel and re-wire the Code-behind logic to use the ViewModel for now.</li>
</ol>

<p>Exercise some judgement here - not all variables should go to the ViewModel, references to UI elements for example, should remain in the code-behind (view).</p>

<p>&#160;</p>

<p><strong>Stage 3 - moving application methods to ViewModel, hooking UI events</strong></p>

<p>Once you've moved your variables to the ViewModel - then you can start looking at moving the methods to the ViewModel.</p>

<p>The trickiest part here, if you have started with code-behind, is that there will be methods that have a mixture of application logic along with UI update calls.</p>

<p>An easy, intermediate way to handle these UI calls is to have the VM raise an event at the specific time, and have the View bind to those events and make the UI updates.</p>

<p>Change any UI update code to UI binding syntax - this should be the normal for most VM entity or collections.</p>

<p>&#160;</p>

<p><strong>Stage 4 - you can start creating Silverlight Unit Tests</strong></p>

<p>By stage 3 - you should have more and more application logic moved back to the ViewModel.&#160; Add a Silverlight Unit Testing project and start instantiating the ViewModel and test the collections and entities can be populated correctly.</p>

<p>From this point onwards because you have the unit tests available you can start to do a lot more refactoring with the methods without worrying that you'll be breaking stuff.&#160; </p>

<p>&#160;</p>

<p><strong>Stage 5 - calling application methods via Commands</strong></p>

<p>Create a DelegateCommand class - unfortunately one isn't provided with Silverlight (I don't know why)</p>

<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> DelegateCommand : ICommand
{
    Func&lt;<span class="kwrd">object</span>, <span class="kwrd">bool</span>&gt; canExecute;
    Action&lt;<span class="kwrd">object</span>&gt; executeAction;
    <span class="kwrd">bool</span> _canExecuteCache;

    <span class="kwrd">public</span> DelegateCommand(Action&lt;<span class="kwrd">object</span>&gt; executeAction, Func&lt;<span class="kwrd">object</span>, <span class="kwrd">bool</span>&gt; canExecute)
    {
        <span class="kwrd">this</span>.executeAction = executeAction;
        <span class="kwrd">this</span>.canExecute = canExecute;
    }

    <span class="kwrd">public</span> DelegateCommand(Action&lt;<span class="kwrd">object</span>&gt; executeAction)
        : <span class="kwrd">this</span>(executeAction, <span class="kwrd">null</span>)
    {
    }
    <span class="preproc">#region</span> ICommand Members

    <span class="kwrd">public</span> <span class="kwrd">bool</span> CanExecute(<span class="kwrd">object</span> parameter)
    {
        <span class="kwrd">if</span> (canExecute == <span class="kwrd">null</span>)
        {
            <span class="kwrd">return</span> <span class="kwrd">true</span>;
        }

        <span class="kwrd">bool</span> temp = canExecute(parameter);
        <span class="kwrd">if</span> (_canExecuteCache != temp)
        {
            _canExecuteCache = temp;
            <span class="kwrd">if</span> (CanExecuteChanged != <span class="kwrd">null</span>)
            {
                CanExecuteChanged(<span class="kwrd">this</span>, <span class="kwrd">new</span> EventArgs());
            }
        }
        <span class="kwrd">return</span> _canExecuteCache;
    }

    <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler CanExecuteChanged;

    <span class="kwrd">public</span> <span class="kwrd">void</span> Execute(<span class="kwrd">object</span> parameter)
    {
        executeAction(parameter);
    }

    <span class="preproc">#endregion</span>
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>In the ViewModel - change the direct method call from the view into a property DelegateCommand, then in the View, change the Click event handler to Command property via Binding to the ViewModel.DelegateCommand</p>

<p>&#160;</p>

<p>&#160;</p>

<p><strong>Stage 6 - break UI event hooks by binding storyboards via triggers</strong></p>

<p>This is by far the most trickiest - depending on what sort of UI updates you had in the code-behind, it may be very tricky to convert them into storyboards.</p>

<p>Do your best, but don't go overboard on this one - I don't have a good all-round-fix for this one yet.</p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/15/sharepoint-clientcontextlist-is-missing.html"><rss:title>SharePoint ClientContext.List is missing?</rss:title><rss:link>http://johnliu.net/blog/2010/7/15/sharepoint-clientcontextlist-is-missing.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-15T23:19:01Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>The SharePoint Object Model has:</p>  <ul>   <li><a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spcontext_members.aspx">SPContext Members</a></li>    <li>SPContext.Current (static)</li>    <li>SPContext.Site </li>    <li>SPContext.Web</li>    <li>SPContext.List </li> </ul>  <p>By comparison, the SharePoint Client Object Model only has:</p>  <ul>   <li><a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.clientcontext_members.aspx">ClientContext Members</a></li>    <li>ClientContext.Current (static)</li>    <li>ClientContext.Site</li>    <li>ClientContext.Web</li>    <li>ClientContext.List <font style="background-color: #ffff00">(AWOL missing!)</font></li> </ul>  <p>Here's one trick I've started using - the current list exists on the page in javascript (ctx.listName)</p>  <p>So using Silverlight's Javascript bridge I'm able to test and pull that value back into Silverlight - without any looping through the ClientContext.Web.Lists.</p>  <pre class="csharpcode"><span class="kwrd">string</span> listName = <span class="kwrd">string</span>.Format(<span class="str">&quot;{0}&quot;</span>, HtmlPage.Window.Eval(<span class="str">&quot;ctx.listName&quot;</span>));
<span class="rem">// using string.Format to take care of null problems</span>
<span class="rem">// the ctx.listName looks like a guid</span>

List list = _clientContext.Web.Lists.GetById(<span class="kwrd">new</span> Guid(listName));</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>&#160;</p>

<p>So taking a step back, this would be the first time I wrote something that uses both client object model at once!</p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/16/sharepoint-2010-and-silverlight-40-webcam.html"><rss:title>SharePoint 2010 and Silverlight 4.0 Webcam</rss:title><rss:link>http://johnliu.net/blog/2010/7/16/sharepoint-2010-and-silverlight-40-webcam.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-15T16:15:25Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>Tonight's Silverlight <em>play </em>involves Silverlight 4 Web Cam API, and SharePoint 2010 Client Object Model.</p>
<p><strong>SILVERLIGHT 4 WEBCAM API</strong></p>
<p>Silverlight 4's WebCam API is relatively simple:</p>
<pre class="csharpcode">_captureVideoDevice = <span style="background-color: #ffff00;">CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice</span>();
_captureSource = <span class="kwrd">new</span> CaptureSource();
VideoBrush brush = <span class="kwrd">new</span> VideoBrush();
brush.SetSource(_captureSource);

WebCameraCapture.Fill = brush; <span class="rem">// fill rectangle "render" area</span>

var device = _captureVideoDevice.FriendlyName; <span class="rem">// check device name during debug</span>
<span class="kwrd">if</span> (CaptureDeviceConfiguration.AllowedDeviceAccess || <span style="background-color: #ffff00;">CaptureDeviceConfiguration.RequestDeviceAccess</span>())
{
    _captureSource.Start();
}</pre>
<!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } -->
<p>The most interesting part is probably the RequestDeviceAccess call. This call must be initiated in an UI event (click) and will raise the following dialog</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010andSilverlight4.0Webcam_1C6C-?fileId=7732048"><img style="display: inline; border: 0px;" title="clip_image002" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010andSilverlight4.0Webcam_1C6C-?fileId=7732049" border="0" alt="clip_image002" width="558" height="208" /></a></p>
<p>&nbsp;</p>
<p><strong>TAKING SNAPSHOTS</strong></p>
<p>Once the camera is rolling, clicking the button takes a snapshot and saves it back to the document library.</p>
<pre class="csharpcode">WriteableBitmap bmp = <span class="kwrd">new</span> WriteableBitmap(WebCameraCapture, <span class="kwrd">null</span>);
MemoryStream stream = <span class="kwrd">new</span> MemoryStream();
<span class="rem">// didn't want to save as bitmap - convert to JPEG first</span>
EncodeJpeg(bmp, stream);

var fileCreationInfo = <span class="kwrd">new</span> FileCreationInformation();
<span style="background-color: #ffff00;">fileCreationInfo.Content</span> = stream.ToArray();
fileCreationInfo.Url = <span class="kwrd">string</span>.Format(<span class="str">"pic_{0}.jpg"</span>, DateTime.Now.Ticks);
var _documentLibrary = _clientContext.Web.Lists.GetByTitle("ListName");
var uploadFile = _documentLibrary.RootFolder.Files.Add(fileCreationInfo);
_clientContext.Load(uploadFile);
_clientContext.ExecuteQueryAsync(<span class="kwrd">delegate</span>{}, <span class="kwrd">delegate</span>{});</pre>
<!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } -->
<p>In this screenshot I've added the Silverlight web part on top of the asset library list.</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010andSilverlight4.0Webcam_1C6C-?fileId=7732050"><img style="display: inline; border: 0px;" title="clip_image004" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010andSilverlight4.0Webcam_1C6C-?fileId=7732052" border="0" alt="clip_image004" width="580" height="386" /></a></p>
<p>&nbsp;</p>
<p><strong>WHAT ABOUT VIDEO?</strong></p>
<p>This is where we'll probably get stuck. Silverlight 4 has API to access camera, and we're able to save bitmap data from the camera, but Silverlight 4 lacks the client side encoding libraries capable of saving the bitmap stream back into any meaningful format such as MPEG.</p>
<p>Until Microsoft provides one, or some 3rd party writes one, saving video back to SharePoint document library is going to get put on hold.</p>
<p><strong>REFERENCE</strong></p>
<p>The code for converting to JPEG I copied from <a href="http://stackoverflow.com/questions/1139200/using-fjcore-to-encode-silverlight-writeablebitmap">http://stackoverflow.com/questions/1139200/using-fjcore-to-encode-silverlight-writeablebitmap</a>.</p>
<p><strong>DOWNLOAD</strong></p>
<p>The Silverlight Camera XAP binaries are in this <a href="http://johnliu.net/storage/SilverlightCamera.xap">XAP file&nbsp;</a></p>
<p>The Silverlight Camera <a href="http://johnliu.net/storage/SilverlightCameraSolution.wsp">Sandbox Solution</a> and <a href="http://johnliu.net/storage/SilverlightCamera_ReadMe.docx">read me file</a>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>INSTALLATION</strong></p>
<ol>
<li>Upload the XAP file to a document library, copy the URL to this XAP file.</li>
<li>Create a document library to host all the pictures, open the web part zones on the view page and insert a Silverlight Web Part - use the URL to XAP from step 1.</li>
<li>Remember to refresh the page to see new pictures - the list doesn't refresh automatically.&nbsp; You can switch on async properties in the web part editor for the pictures and it will update itself on a timer basis.</li>
</ol>
<p><strong>UPDATE</strong></p>
<p>20 July - Added sandbox solution WSP and a simple read-me file</p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/15/sharepoint-2010-update-all-list-items-sharepoint-designer-wo.html"><rss:title>SharePoint 2010 - Update All List Items SharePoint Designer Workflow Action</rss:title><rss:link>http://johnliu.net/blog/2010/7/15/sharepoint-2010-update-all-list-items-sharepoint-designer-wo.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-15T03:52:41Z</dc:date><dc:subject>SharePoint code</dc:subject><content:encoded><![CDATA[<p>Out of the box - SharePoint provides quite a few different Workflow Actions, but strangely missing was a Workflow action that can loop through and update all items within a list.</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726573"><img style="display: inline; border-width: 0px;" title="clip_image002" src="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726574" border="0" alt="clip_image002" width="324" height="513" /></a></p>
<p>Figure: Update List Item (but only works with one item)</p>
<p>Further to my shock was that someone out there (cough Codeplex) hasn't written one yet. So last night I sat down and start to code.&nbsp; There will be another article about coding and packaging a SharePoint Workflow Activity, but right now, I need to shove my baby out the door.</p>
<p><strong>UPDATE LIST ITEMS v1.0 INSTALLATION</strong></p>
<p>Everything in one WSP file: grab it <a href="http://johnliu.net/storage/WorkflowActivity.wsp">here</a></p>
<p>The package includes 3 objects:</p>
<ul>
<li>WorkflowActivity.dll - goes in the GAC </li>
<li>WorkflowActivity.ACTIONS - goes into &lt;SharePointRoot&gt;\TEMPLATE\1033\Workflow\WorkflowActivity.ACTIONS </li>
<li>&lt;authorizedType&gt; entry needed in Web.Config - I've included a Web Application feature that will do this </li>
</ul>
<p>To activate the web application feature</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726576"><img style="display: inline; border-width: 0px;" title="clip_image004" src="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726577" border="0" alt="clip_image004" width="580" height="288" /></a></p>
<p><strong>&nbsp;</strong></p>
<p><strong>UPDATE LIST ITEMS v1.0 USERS GUIDE</strong></p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726578"><img style="display: inline; border-width: 0px;" title="clip_image006" src="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726579" border="0" alt="clip_image006" width="326" height="537" /></a></p>
<p>In SharePoint Designer, select the "Update All List Items" action from the menu</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726580"><img style="display: inline; border-width: 0px;" title="clip_image008" src="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726581" border="0" alt="clip_image008" width="580" height="113" /></a></p>
<p>Or just do the inline typing</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726582"><img style="display: inline; border-width: 0px;" title="clip_image010" src="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726583" border="0" alt="clip_image010" width="580" height="93" /></a></p>
<p>There is only 1 dialog for this action - I cheated and reuse the dialog from Update Item Workflow Action</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726584"><img style="display: inline; border-width: 0px;" title="clip_image012" src="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726588" border="0" alt="clip_image012" width="389" height="438" /></a></p>
<p>Unfortunately, because I cheated and use Microsoft's dialog - it won't let us finish without specifying a List Item - hence I use the sentence "Update all items in this list <strong><span style="background-color: #ffff00;">(ignore list item)</span></strong>" - sorry - hope that was clear.</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726589"><img style="display: inline; border-width: 0px;" title="clip_image014" src="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726590" border="0" alt="clip_image014" width="382" height="433" /></a></p>
<p>OK and trigger the workflow</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726591"><img style="display: inline; border-width: 0px;" title="clip_image016" src="http://johnliu.net/resource/WindowsLiveWriter-01e80ce93bd1_C0A6-?fileId=7726592" border="0" alt="clip_image016" width="580" height="214" /></a></p>
<p><strong>&nbsp;</strong></p>
<p><strong>SUMMARY NOTES</strong></p>
<ol>
<li>In SharePoint, a workflow can not trigger itself. So even though I have the workflow set against this list - it is only run on the last item. </li>
<li>And because this is version 1 (v1.0) there's some really complex looking code for setting "People or Group" values. So I'm not sure if this works 100% in my implementation. </li>
<li>Obviously, if your list is extremely large you are on your own :-) </li>
<li>One other scenario this opens up is the facility to have a site workflow "trigger" a second workflow set on a particular list (remember - workflow can't trigger itself).</li>
</ol>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/13/silverlight-merging-detached-object-back-to-the-attached-dat.html"><rss:title>Silverlight - merging detached object back to the attached data context</rss:title><rss:link>http://johnliu.net/blog/2010/7/13/silverlight-merging-detached-object-back-to-the-attached-dat.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-13T13:57:40Z</dc:date><dc:subject>Silverlight code</dc:subject><content:encoded><![CDATA[<p>This is a short post on something that we did in the days of Silverlight 2~3, before we have RIA services.</p>
<p>Consider two method signatures on the service:</p>
<ol>
<li>public EntityPerson GetPerson(object key);</li>
<li>public void SavePerson(EntityPerson person);</li>
</ol>
<p>Silverlight gets an EntityPerson object, exposes it via the ViewModel for databinding.&nbsp; The user hits the save button, and the data is coming back through the wire.</p>
<p>It comes back to SavePerson, but the object is disconnected.</p>
<p>The way we've always done this is this way:</p>
<pre class="csharpcode"><span class="rem">//Update or Insert person:</span>
<span class="kwrd">if</span> (entityPerson.PersonID &gt; 0) <span class="rem">//update </span>
{
    EntityKey key = entities.CreateEntityKey(<span class="str">"tblPerson"</span>, entityPerson);
    <span class="kwrd">object</span> originalItem;
    <span class="kwrd">if</span> (entities.TryGetObjectByKey(key, <span class="kwrd">out</span> originalItem))
    {
        <span class="rem">// merge changes from the client back to the dataset</span>
        entities.ApplyPropertyChanges(key.EntitySetName, entityPerson);
    }
}
<span class="kwrd">else</span><span class="rem">//insert new </span>
{
    entities.AddObject(<span class="str">"tblPerson"</span>, entityPerson);
}</pre>
<p><!-- .csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } --></p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.applypropertychanges.aspx">ApplyPropertyChanges</a> works very well and takes a lot of the work out of our hands.&nbsp; You can attach a very simple conflict detection if you have a Timestamp field, and by setting the ConcurrencyMode=Fixed.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/bb738618.aspx">Saving Changes and Managing Concurrency</a> <br /><a href="http://msdn.microsoft.com/en-us/library/bb399228.aspx">How to: Manage Data Concurrency in the Object Context</a> <br /><a href="http://msdn.microsoft.com/en-us/magazine/dd263098.aspx">Flexible Data Access With LINQ To SQL And The Entity Framework</a></p>
<p>I was recently involved in a short discussion on this topic, and was intrigued to go digging and get to the bottom of it all.&nbsp; Hope these links help someone :-)</p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/13/sharepoint-2010-configuring-list-item-permissions-with-workf.html"><rss:title>SharePoint 2010 - Configuring List Item Permissions with Workflow</rss:title><rss:link>http://johnliu.net/blog/2010/7/13/sharepoint-2010-configuring-list-item-permissions-with-workf.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-13T12:36:09Z</dc:date><dc:subject>SharePoint</dc:subject><content:encoded><![CDATA[<p>The client had a pretty <em>"simple"</em> situation where:</p>
<ol>
<li>We want to create a Request list where different people in the company can add requests, but assign it to a department.</li>
<li>Once created, only members in that department has access to this request item</li>
</ol>
<p><strong>PERMISSION GROUPS</strong></p>
<p>You can use Active Directory groups here as well.&nbsp; Here are my four security groups</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700753"><img class="wlDisabledImage" style="display: inline; border: 0px;" title="image" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700754" border="0" alt="image" width="384" height="425" /></a></p>
<p>&nbsp;</p>
<p><strong>DEPARTMENT LIST</strong></p>
<p>I plan to use re-usable workflows later to configure the list item permissions.&nbsp; So I need to create a few site columns, here's the first one DepartmentGroup.&nbsp; This is basically a People or Groups field.</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700755"><img style="display: inline; border: 0px;" title="clip_image002" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700756" border="0" alt="clip_image002" width="425" height="350" /></a></p>
<p>I create a list for the department, thus:</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700757"><img style="display: inline; border: 0px;" title="clip_image002[7]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700758" border="0" alt="clip_image002[7]" width="558" height="148" /></a></p>
<p>&nbsp;</p>
<p><strong>REQUEST LIST</strong></p>
<p>Here's the second site column.&nbsp; This is a lookup column to the Department list.&nbsp; I'm bringing over the ID field as an additional field.</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700759"><img style="display: inline; border: 0px;" title="clip_image002[9]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700760" border="0" alt="clip_image002[9]" width="308" height="397" /></a></p>
<p>Add a few records:</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700761"><img style="display: inline; border: 0px;" title="clip_image002[11]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700763" border="0" alt="clip_image002[11]" width="558" height="301" /></a></p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700764"><img style="display: inline; border: 0px;" title="clip_image002[13]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700765" border="0" alt="clip_image002[13]" width="558" height="82" /></a> <br /></p>
<p><strong>REMOVE LIST PERMISSIONS</strong></p>
<p>Stop inheriting permissions from parent (site), and do a bit of house cleaning and remove the unnecessary groups.</p>
<p><strong>&nbsp;</strong></p>
<p><strong>LET'S WORK ON THAT WORKFLOW</strong></p>
<p>The idea of the workflow is that:</p>
<ol>
<li>Whenever an item is updated</li>
<li>Look up the group based on the selected Department (via the additional ID field)</li>
<li>Assign item-level security to the list item</li>
<li>Remove permissions to modify the item, and grant the department group permission to view and modify that request.</li>
</ol>
<p>Create a re-usable workflow.&nbsp; Target any content type.</p>
<p>We'll need the lookup site column, so associate that</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700766"><img style="display: inline; border: 0px;" title="clip_image002[15]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700767" border="0" alt="clip_image002[15]" width="509" height="269" /></a></p>
<p>The permissions steps need to be run as impersonated steps.&nbsp; The impersonated steps can not be mixed with the normal steps (such as Step 1)</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700769"><img style="display: inline; border: 0px;" title="clip_image002[17]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700770" border="0" alt="clip_image002[17]" width="558" height="292" /></a></p>
<p>Remove (unused) Step 1, and add "Replace permission" action</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700771"><img style="display: inline; border: 0px;" title="clip_image002[19]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700772" border="0" alt="clip_image002[19]" width="558" height="177" /></a></p>
<p>Start with the second parameter which is the easier one.&nbsp; Click on "this list" and select Current Item</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700775"><img style="display: inline; border: 0px;" title="clip_image002[21]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700776" border="0" alt="clip_image002[21]" width="382" height="100" /></a></p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700778"><img style="display: inline; border: 0px;" title="clip_image002[23]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700779" border="0" alt="clip_image002[23]" width="558" height="117" /></a></p>
<p>Click on "these permissions" and we want Contribute and Read permissions</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700780"><img style="display: inline; border: 0px;" title="clip_image002[25]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700781" border="0" alt="clip_image002[25]" width="558" height="453" /></a></p>
<p>Click on "Choose" and set who we'll be granting Contribute/Read to</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700782"><img style="display: inline; border: 0px;" title="clip_image002[29]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700784" border="0" alt="clip_image002[29]" width="503" height="328" /></a></p>
<p>Select "Workflow Lookup for a User&hellip;" and click Add   <br />We want to do a look up on the Department list.</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700785"><img style="display: inline; border: 0px;" title="clip_image002[31]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700786" border="0" alt="clip_image002[31]" width="382" height="307" /></a></p>
<p>The field we want is DepartmentGroup (our Person and Group site column).&nbsp; Return the field as Login Name   <br />Set the filter Field below to ID</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700788"><img style="display: inline; border: 0px;" title="clip_image002[33]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700789" border="0" alt="clip_image002[33]" width="382" height="307" /></a> <br /></p>
<p>Set the filter Value field to Current Item.Department:ID</p>
<p>(You can also use the DepartmentLookup field here, just return it as Integer)</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700791"><img style="display: inline; border: 0px;" title="clip_image002[35]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700793" border="0" alt="clip_image002[35]" width="382" height="199" /></a></p>
<p>Final result:</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700795"><img style="display: inline; border: 0px;" title="clip_image002[37]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700796" border="0" alt="clip_image002[37]" width="382" height="307" /></a></p>
<p>OK everything.&nbsp; Remember to save and publish</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700798"><img style="display: inline; border: 0px;" title="clip_image002[39]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700799" border="0" alt="clip_image002[39]" width="150" height="141" /></a></p>
<p>&nbsp;</p>
<p>Go back to SharePoint list</p>
<p>Configure the workflow and make sure it runs when a list item is created or modified</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700800"><img style="display: inline; border: 0px;" title="clip_image002[41]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700802" border="0" alt="clip_image002[41]" width="558" height="526" /></a></p>
<p><strong>VERIFY RESULTS   <br /></strong> Check the permission of our first request (before the workflow)</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700804"><img style="display: inline; border: 0px;" title="clip_image002[43]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700807" border="0" alt="clip_image002[43]" width="484" height="216" /></a></p>
<p>It is inheriting from list.&nbsp; Nothing special.</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700810"><img style="display: inline; border: 0px;" title="clip_image002[45]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700815" border="0" alt="clip_image002[45]" width="558" height="218" /></a></p>
<p>&nbsp;</p>
<p>Create a new request for our Network department - see the workflow has completed</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700817"><img style="display: inline; border: 0px;" title="clip_image002[47]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700820" border="0" alt="clip_image002[47]" width="558" height="170" /></a></p>
<p>Check its permissions</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700822"><img style="display: inline; border: 0px;" title="clip_image002[49]" src="http://johnliu.net/resource/WindowsLiveWriter-SharePoint2010ConfiguringListItemPermiss_136A6-?fileId=7700824" border="0" alt="clip_image002[49]" width="558" height="199" /></a></p>
<p>"NetworkHeroes" has been assigned "Contribute" and "Read" permissions to the list item - everyone else has been stripped out.   <br />The List Item has also stopped inheriting permissions from the parent list.</p>
<p>&nbsp;</p>
<p><strong>SUMMARY</strong></p>
<p>So the solution works and is relatively elegant.&nbsp; Though the client mocks me and says it was so much more easier in Lotus Notes :-(</p>
<p>The following features in SharePoint 2010 makes this example a little bit cleaner than with SharePoint 2007:</p>
<ul>
<li>"Additional Fields"</li>
<li>Impersonation Step</li>
<li>Re-usable Workflows</li>
<li>Replace Permissions Action </li>
</ul>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/12/windows-live-messenger-wave-4-redirus-freaks-me-out.html"><rss:title>Windows Live Messenger wave 4 - redir.us freaks me out</rss:title><rss:link>http://johnliu.net/blog/2010/7/12/windows-live-messenger-wave-4-redirus-freaks-me-out.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-12T02:33:38Z</dc:date><dc:subject>rant</dc:subject><content:encoded><![CDATA[<p>Colleagues send me links via MSN to a web page, and I see</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-redir.usfreaksmeout_A8AF-?fileId=7681920"><img class="wlDisabledImage" style="display: inline; border: 0px;" title="image" src="http://johnliu.net/resource/WindowsLiveWriter-redir.usfreaksmeout_A8AF-?fileId=7681921" border="0" alt="image" width="787" height="54" /></a></p>
<p>Immediately started freaking out - what is rdir.us?   <br />Not many people have written about this - the best I've found is Rafael's post here:</p>
<p><a title="Live Messenger and the &ldquo;link harvesting black box in the sky&rdquo;" href="http://www.withinwindows.com/2010/06/17/live-messenger-and-the-link-harvesting-black-box-in-the-sky/">Live Messenger and the &ldquo;link harvesting black box in the sky&rdquo;</a></p>
<p>Short story:</p>
<ul>
<li>rdir.us is Microsoft Internet SmartScreen Filter</li>
<li>It looks safe, but there's no way to turn this off.</li>
<li>If the URL was <a href="http://link.smartscreen.live.com/?l=http://digg.com">http://link.smartscreen.live.com/?l=http://digg.com</a> it wouldn't have looked as scary.</li>
<li>I really wish it didn't give me such a fright</li>
<li>Oh <a href="http://rdir.us">http://rdir.us</a> doesn't have any explanation page</li>
</ul>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/10/silverlight-pivotviewer-and-sharepoint.html"><rss:title>Silverlight PivotViewer and SharePoint</rss:title><rss:link>http://johnliu.net/blog/2010/7/10/silverlight-pivotviewer-and-sharepoint.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-09T16:53:26Z</dc:date><dc:subject>SharePoint Silverlight</dc:subject><content:encoded><![CDATA[<p>&nbsp;</p>
<p>Microsoft just released a new control PivotViewer for Silverlight.&nbsp;</p>
<p><a href="http://www.microsoft.com/silverlight/pivotviewer/">http://www.microsoft.com/silverlight/pivotviewer/</a></p>
<p>If you haven't seen this yet - go check out the video then come back, I'll wait here.</p>
<p>&nbsp;</p>
<p>It's a web-based control to provide pivot functionality for datasets.&nbsp; For fixed data - you can pre-generate the data set. For dynamic data, the collection could be generated dynamically and served.</p>
<p>So what would happen if you throw it at SharePoint, I ask?</p>
<p>The initial results are astounding!&nbsp; Check these out:</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SLSP_1BF8-?fileId=7657053"><img class="wlDisabledImage" style="display: inline; border-width: 0px;" title="image" src="http://johnliu.net/resource/WindowsLiveWriter-SLSP_1BF8-?fileId=7657054" border="0" alt="image" width="644" height="326" /></a></p>
<p>Figure: Connecting it to listdata.svc OData service</p>
<p>At the root level it really is quite boring.</p>
<p>&nbsp;</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SLSP_1BF8-?fileId=7657056"><img class="wlDisabledImage" style="display: inline; border-width: 0px;" title="image" src="http://johnliu.net/resource/WindowsLiveWriter-SLSP_1BF8-?fileId=7657057" border="0" alt="image" width="622" height="484" /></a></p>
<p>Figure: Connecting to a document library OData service</p>
<p>OK this is getting fun.&nbsp; Facets!&nbsp; Sort/Display/Zoom</p>
<p><a href="http://johnliu.net/resource/WindowsLiveWriter-SLSP_1BF8-?fileId=7657059"><img class="wlDisabledImage" style="display: inline; border-width: 0px;" title="image" src="http://johnliu.net/resource/WindowsLiveWriter-SLSP_1BF8-?fileId=7657061" border="0" alt="image" width="608" height="484" /></a></p>
<p>Figure: Sorting the document library by Modified date</p>
<p>You probably can see I've uploaded a bunch of documents in the last hour :-)</p>
<p>&nbsp;</p>
<p>The screenshots don't do this justice - when you filter down, change sort&hellip; the boxes fly all over the place it's as if I'm literally shaking SharePoint apart to zoom in on my data.</p>
<p>&nbsp;</p>
<p>So it looks like I'll be extremely busy next couple of weekends and evenings:</p>
<ul>
<li>Generate collection data across site - this will let me filter the "Path" facet to select which list/document library I'm after      
<ul>
<li>What does this mean for big sites? </li>
</ul>
</li>
<li>Add more visualizers, use Word/PPT thumbnails </li>
<li>Create configurable background colours for different content types </li>
<li>Add a contextual menu and hook it back through SharePoint actions </li>
<li>And the Holy Grail - is it possible to make this work as a Sandbox Solution?      
<ul>
<li>The current sample reference application requires IIS HttpHandlers to serve dynamic collection data consumed from OData.&nbsp; </li>
<li><span style="color: #ff0000;">Sandbox solution problem may be tricky.</span> </li>
</ul>
</li>
</ul>
<p>&nbsp;</p>
<p>It's times like this I stood back and appreciate what Microsoft does.&nbsp; You guys are awesome.&nbsp; Different teams produce different software and they just magically work together.&nbsp; Makes us look like heroes.</p>
<p>/Salute</p>]]></content:encoded></rss:item><rss:item rdf:about="http://johnliu.net/blog/2010/7/7/silverlight-unit-testing-adding-a-timeout-to-enqueueconditio.html"><rss:title>Silverlight Unit Testing - adding a timeout to EnqueueConditional</rss:title><rss:link>http://johnliu.net/blog/2010/7/7/silverlight-unit-testing-adding-a-timeout-to-enqueueconditio.html</rss:link><dc:creator>JohnLiu.NET</dc:creator><dc:date>2010-07-07T00:22:30Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>Since a lot of Silverlight work is asynchronous in nature, the Silverlight testing framework has many helper functions to essentially do &quot;non blocking wait until something happens&quot;</p>  <p>The curious one to me is EnqueueConditional(Func&lt;bool&gt; conditionalDelegate</p>  <p>This one essentially waits until the condition is true - so you can call a method to populate your view model with data, and then wait until data.Count &gt; 0</p>  <p>But the method has no support for timeout.&#160; It can, and will, hold the unit testing framework in progress forever.</p>  <p>Here's my little tweak to the method.</p>  <pre class="csharpcode">        <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> EnqueueConditional(Func&lt;<span class="kwrd">bool</span>&gt; conditionalDelegate)
        {
            DispatcherTimer timer = <span class="kwrd">new</span> DispatcherTimer();
            timer.Interval = <span class="kwrd">new</span> TimeSpan(<font style="background-color: #ffff00">0, 0, 5</font>);
            timer.Tick += <span class="kwrd">delegate</span>
            {
                <span class="rem">// remember to stop timer or it'll tick again</span>
                timer.Stop();
                <span class="kwrd">throw</span> <span class="kwrd">new</span> TimeoutException();
            };
            EnqueueCallback(<span class="kwrd">delegate</span>
            {
                timer.Start();
            });
            <span class="kwrd">base</span>.EnqueueConditional(conditionalDelegate);
            EnqueueCallback(<span class="kwrd">delegate</span>
            {
                timer.Stop();
            });
        }</pre>
<style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style><style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>Here's the unit test to go with it</p>

<pre class="csharpcode">        [TestMethod]
        [TestProperty(<span class="str">&quot;TestCategory&quot;</span>, <span class="str">&quot;Silverlight&quot;</span>)]
        [Asynchronous]
        [ExpectedException(<span class="kwrd">typeof</span>(TimeoutException))]
        <span class="kwrd">public</span> <span class="kwrd">void</span> Test_Timeout()
        {
            EnqueueConditional(<span class="kwrd">delegate</span>
            {
                <span class="rem">// return?  never!</span>
                <span class="kwrd">return</span> <span class="kwrd">false</span>;
            });

            EnqueueTestComplete();
        }</pre>
<style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>And one more tweak in the App.xaml.cs</p>

<pre class="csharpcode">        <span class="kwrd">private</span> <span class="kwrd">void</span> Application_UnhandledException(<span class="kwrd">object</span> sender, ApplicationUnhandledExceptionEventArgs e)
        {
            <span class="kwrd">if</span> (e.ExceptionObject <span class="kwrd">is</span> TimeoutException)
            {
                e.Handled = <span class="kwrd">true</span>;
                <span class="rem">// stop any timeoutexception here or it'll bubble to the DOM</span>
                <span class="kwrd">return</span>;
            }

            ...
        }</pre>
<style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>Here's the result picture:&#160; Running just slightly over 5 seconds.</p>

<p><a href="http://johnliu.net/resource/WindowsLiveWriter-0c2e68154812_8FB3-?fileId=7619350"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://johnliu.net/resource/WindowsLiveWriter-0c2e68154812_8FB3-?fileId=7619351" width="639" height="270" /></a></p>

<br />

<p>Updated: added a result picture.</p>]]></content:encoded></rss:item></rdf:RDF>