<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Notes on Code</title>
  <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/" />
  <link rel="self" href="http://www.notesoncode.com/articles/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2012-01-24T16:34:59.0519264-07:00</updated>
  <author>
    <name>Keith Rimington</name>
  </author>
  <subtitle>Some in C#, none will B flat</subtitle>
  <id>http://www.notesoncode.com/articles/</id>
  <generator uri="http://dasblog.info/" version="2.1.8102.813">DasBlog</generator>
  <entry>
    <title>How to Delete a Page Layout When Nothing Else Works</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2012/01/24/HowToDeleteAPageLayoutWhenNothingElseWorks.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,183cb5dd-57d1-4f8f-b76f-279d51c01054.aspx</id>
    <published>2012-01-24T16:34:59.051-07:00</published>
    <updated>2012-01-24T16:34:59.0519264-07:00</updated>
    <category term="PowerShell" label="PowerShell" scheme="http://www.notesoncode.com/articles/CategoryView,category,PowerShell.aspx" />
    <category term="SharePoint" label="SharePoint" scheme="http://www.notesoncode.com/articles/CategoryView,category,SharePoint.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been working on a new internal portal for <a href="http://www.nuskin.com" target="_blank">my
employer</a> using SharePoint 2010. As the project progressed, we experimented
with several custom page layouts and, at length, settled on our two favorites.
</p>
        <p>
With the decision final, we reassigned all the pages to the authorized page layouts
and proceeded to delete the extras... all except one.
</p>
        <p>
This page layout didn't want to get deleted. I was persistent, but the file was more
so.
</p>
        <p>
 
</p>
        <ul>
          <li>
Deleting the file in SharePoint Designer yielded the error "Server error: This item
cannot be deleted because it is still referenced by other pages." Mind you, it wasn't,
but SharePoint thought it was.</li>
          <li>
Several online sources indicated that moving it to a sub-folder should allow deletion
of the folder. However, in my case, doing so in SharePoint Designer yielded the error
"Server error: This folder cannot be deleted because it contains the following page
layout that is still in use: LayoutPage01.aspx."</li>
          <li>
I could open the master page gallery in Windows Explorer, attempt to delete the file,
or move it to a folder and delete the folder, and yet the file remained.</li>
          <li>
I fired up PowerShell and attempted to delete the file with code, and received the
same error.</li>
        </ul>
        <div>At this point I didn't quite know what to do. As a matter of fact, poking around
the code with PowerShell didn't help me root out the source of the error; or, at least,
not at first.
</div>
        <div>
          <br />
        </div>
        <div>I was working on another task--one related to event receivers--when I noticed
the following event receiver attached to the master page gallery:
</div>
        <pre>
          <code>Type : ItemDeleting SequenceNumber : 1000 Assembly : Microsoft.SharePoint.Publishing,
Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Class : Microsoft.SharePoint.Publishing.Internal.BlockDeletionOfInUseItemsEventReceiver </code>
        </pre>
        <div>"Well, well," I thought. This must be the source of the error.
</div>
        <div>
          <br />
        </div>
        <div>Upon inspection, I learned about the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfile.backwardlinks.aspx" target="_blank">BackwardLinks</a> property
of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfile.aspx" target="_blank">SPFile</a> class.
This collection provides information as to *which* files still lay claim on the page
layout.
</div>
        <div>
          <br />
        </div>
        <div>I took a look at the BackwardLinks collection on my particular page layout in
PowerShell, and discovered four backward links, <strong><span style="text-decoration: underline;">all
from files that didn't exist anymore!</span></strong></div>
        <div>
          <strong>
            <span style="text-decoration: underline;">
              <br />
            </span>
          </strong>
        </div>
        <div>Well, enough story. Here is the PowerShell I used to resolve the problem. <span style="font-weight: bold; text-decoration: underline;">It
will probably break your system and destroy all that you love</span>... Don't say
I didn't warn you, if you try to use it. The steps are simple:
</div>
        <div>
          <ol>
            <li>
Find the layout in the gallery.</li>
            <li>
Check to see if any of the BackwardLinks are to files that <em>really</em> exist.</li>
            <li>
If non of the files exist, remove the event receiver that prevents deletion, delete
the file, and then re-register the event receiver.</li>
          </ol>
          <div>Happy Coding!
</div>
        </div>
        <div>
          <br />
        </div>
        <pre>
          <code>
            <span style="color: #0000FF;">function</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #5F9EA0;">Remove-PageLayout</span>
            <span style="color: #000000;">(</span>
            <span style="color: #800080;">$siteUrl</span>
            <span style="color: #000000;">, </span>
            <span style="color: #800080;">$layoutName</span>
            <span style="color: #000000;">)
{ </span>
            <span style="color: #800080;">$site </span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;"> Get-SPSite </span>
            <span style="color: #800080;">$siteUrl</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$web </span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$site</span>
            <span style="color: #000000;">.RootWeb </span>
            <span style="color: #800080;">$gallery </span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$web</span>
            <span style="color: #000000;">.lists[</span>
            <span style="color: #800000;">"</span>
            <span style="color: #800000;">Master
Page Gallery</span>
            <span style="color: #800000;">"</span>
            <span style="color: #000000;">] </span>
            <span style="color: #800080;">$layoutItem</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$gallery</span>
            <span style="color: #000000;">.Items
|? { </span>
            <span style="color: #800080;">$_</span>
            <span style="color: #000000;">.Name </span>
            <span style="color: #FF0000;">-eq</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$layoutName</span>
            <span style="color: #000000;"> } </span>
            <span style="color: #0000FF;">if</span>
            <span style="color: #000000;">(</span>
            <span style="color: #FF0000;">!</span>
            <span style="color: #800080;">$layoutItem</span>
            <span style="color: #000000;">)
{ </span>
            <span style="color: #0000FF;">throw</span>
            <span style="color: #000000;"> (</span>
            <span style="color: #5F9EA0; font-weight: bold;">new-object</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800000;">IO.FileNotFoundException</span>
            <span style="color: #000000;">)
} </span>
            <span style="color: #800080;">$layoutFile</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$layoutItem</span>
            <span style="color: #000000;">.File </span>
            <span style="color: #800080;">$layoutFile</span>
            <span style="color: #000000;">.BackwardLinks
|</span>
            <span style="color: #5F9EA0; font-weight: bold;">%</span>
            <span style="color: #000000;"> { </span>
            <span style="color: #0000FF;">if</span>
            <span style="color: #000000;">(Test-Page </span>
            <span style="color: #800080;">$_</span>
            <span style="color: #000000;">.Url)
{ </span>
            <span style="color: #0000FF;">throw</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800000;">"</span>
            <span style="color: #800000;">Cannot
delete page because it is referenced by $($_.Url).</span>
            <span style="color: #800000;">"</span>
            <span style="color: #000000;"> }
} </span>
            <span style="color: #800080;">$receiverType</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;"> [Microsoft.SharePoint.Publishing.Internal.BlockDeletionOfInUseItemsEventReceiver] </span>
            <span style="color: #800080;">$unregisterMethod</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$receiverType</span>
            <span style="color: #000000;">.GetMethod(</span>
            <span style="color: #800000;">"</span>
            <span style="color: #800000;">Unregister</span>
            <span style="color: #800000;">"</span>
            <span style="color: #000000;">,
[</span>
            <span style="color: #008080;">reflection.bindingflags</span>
            <span style="color: #000000;">]</span>
            <span style="color: #800000;">"</span>
            <span style="color: #800000;">Static,NonPublic</span>
            <span style="color: #800000;">"</span>
            <span style="color: #000000;">) </span>
            <span style="color: #800080;">$registerMethod</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$receiverType</span>
            <span style="color: #000000;">.GetMethod(</span>
            <span style="color: #800000;">"</span>
            <span style="color: #800000;">RegisterIfNeeded</span>
            <span style="color: #800000;">"</span>
            <span style="color: #000000;">,
[</span>
            <span style="color: #008080;">reflection.bindingflags</span>
            <span style="color: #000000;">]</span>
            <span style="color: #800000;">"</span>
            <span style="color: #800000;">Static,NonPublic</span>
            <span style="color: #800000;">"</span>
            <span style="color: #000000;">) </span>
            <span style="color: #800080;">$unregisterMethod</span>
            <span style="color: #000000;">.Invoke(</span>
            <span style="color: #800080;">$null</span>
            <span style="color: #000000;">, </span>
            <span style="color: #800080;">$gallery</span>
            <span style="color: #000000;">) </span>
            <span style="color: #800080;">$layoutItem</span>
            <span style="color: #000000;">.Delete() </span>
            <span style="color: #800080;">$registerMethod</span>
            <span style="color: #000000;">.Invoke(</span>
            <span style="color: #800080;">$null</span>
            <span style="color: #000000;">, </span>
            <span style="color: #800080;">$gallery</span>
            <span style="color: #000000;">) </span>
            <span style="color: #800080;">$site</span>
            <span style="color: #000000;">.Dispose();
} </span>
            <span style="color: #0000FF;">function</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #5F9EA0;">Test-Page</span>
            <span style="color: #000000;">(</span>
            <span style="color: #800080;">$url</span>
            <span style="color: #000000;">)
{ </span>
            <span style="color: #800080;">$site</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$web</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$null</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #0000FF;">trap</span>
            <span style="color: #000000;"> [</span>
            <span style="color: #008080;">exception</span>
            <span style="color: #000000;">]
{ </span>
            <span style="color: #0000FF;">if</span>
            <span style="color: #000000;">(</span>
            <span style="color: #800080;">$web</span>
            <span style="color: #000000;">)
{ </span>
            <span style="color: #800080;">$web</span>
            <span style="color: #000000;">.dispose()
} </span>
            <span style="color: #0000FF;">if</span>
            <span style="color: #000000;">(</span>
            <span style="color: #800080;">$site</span>
            <span style="color: #000000;">)
{ </span>
            <span style="color: #800080;">$site</span>
            <span style="color: #000000;">.dispose()
} </span>
            <span style="color: #0000FF;">return</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$false</span>
            <span style="color: #000000;"> } </span>
            <span style="color: #800080;">$site</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #5F9EA0; font-weight: bold;">new-object</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800000;">Microsoft.SharePoint.SPSite</span>
            <span style="color: #000000;">(</span>
            <span style="color: #800080;">$url</span>
            <span style="color: #000000;">) </span>
            <span style="color: #800080;">$web</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$site</span>
            <span style="color: #000000;">.openweb() </span>
            <span style="color: #800080;">$file</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$web</span>
            <span style="color: #000000;">.GetFile(</span>
            <span style="color: #800080;">$url</span>
            <span style="color: #000000;">) </span>
            <span style="color: #800080;">$result</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #FF0000;">=</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$file</span>
            <span style="color: #000000;">.exists </span>
            <span style="color: #800080;">$web</span>
            <span style="color: #000000;">.dispose() </span>
            <span style="color: #800080;">$site</span>
            <span style="color: #000000;">.dispose() </span>
            <span style="color: #0000FF;">return</span>
            <span style="color: #000000;">
            </span>
            <span style="color: #800080;">$result</span>
            <span style="color: #000000;"> }</span>
          </code>
        </pre>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=183cb5dd-57d1-4f8f-b76f-279d51c01054" />
      </div>
    </content>
  </entry>
  <entry>
    <title>How to Resolve $SharePoint.Project.AssemblyFullName$</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2011/11/22/HowToResolveSharePointProjectAssemblyFullName.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,1e2560f7-0051-4e5a-8695-01febf644296.aspx</id>
    <published>2011-11-21T18:27:01.076-07:00</published>
    <updated>2011-11-21T18:27:01.0764684-07:00</updated>
    <category term="SharePoint" label="SharePoint" scheme="http://www.notesoncode.com/articles/CategoryView,category,SharePoint.aspx" />
    <category term="Workflow" label="Workflow" scheme="http://www.notesoncode.com/articles/CategoryView,category,Workflow.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I ran into quite the mystery while building custom workflow activities for SharePoint
2010. It seemed that, no matter what I tried, the new activities would not appear
in SharePoint Designer.
</p>
        <p>
At length, I realized that the assembly name did not get resolved in the .actions
file. Visual studio left the token <span class="code">$SharePoint.Project.AssemblyFullName$</span> as-is.
</p>
        <p>
I found a solution on <a href="http://msdn.microsoft.com/en-us/library/ee231545.aspx" target="_blank">MSDN</a>,
which indicated the Visual Studio tools only replace SharePoint tokens on a few file
extensions. To register additional file extensions, such as .actions, edit the project
file and add the following at the end of the first <span style="font-family: __;">&lt;PropertyGroup&gt;</span> element.
</p>
        <p>
          <span style="font-family: __;">&lt;TokenReplacementFileExtensions&gt;myextension;yourextension&lt;/TokenReplacementFileExtensions&gt;</span>
        </p>
        <p>
That did it for me. From that point forward, my workflow activity appeared in SharePoint
Designer 2010 as expected.
</p>
        <p>
Cheers!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=1e2560f7-0051-4e5a-8695-01febf644296" />
      </div>
    </content>
  </entry>
  <entry>
    <title>A "One Size Fits All" IValueConverter Implementation</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2011/03/05/AOneSizeFitsAllIValueConverterImplementation.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,75c71e15-a638-4f2b-a620-a2922f1559ce.aspx</id>
    <published>2011-03-05T08:41:47.238-07:00</published>
    <updated>2011-03-05T08:52:29.181992-07:00</updated>
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <category term="Silverlight" label="Silverlight" scheme="http://www.notesoncode.com/articles/CategoryView,category,Silverlight.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
While working on a Silverlight business application, I was startled at the proliferation
of value converters within my project. It started out innocent enough. One class named <strong>BooleanToVisibilityConverter</strong>,
and its cousin <strong>BooleanInverseToVisibilityConverter</strong>. Eventually, there
were <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx" target="_blank">IValueConverters</a> implementations
for entirely non-reuable situations, such as <strong>MyEntityCollectionToBrushBasedOnSomeDetailedCriteraConverter</strong>.
</p>
        <p>
That's when this idea struck me. To avoid the need to manage a limitless library of
value converters, why not create an event-driven value converter that delegates the
conversion to a listener, such as a user control or page. Implementing the solution
turned out to be fairly simple.
</p>
        <hr />
        <p>
First, I created an EventArgs derivative to carry the converter's method arguments
and collect the result, like so:
</p>
        <div id="wmd-preview">
          <pre class="default prettyprint">
            <code>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">class</span>
              <span class="pln">
              </span>
              <span class="typ">ValueConvertingEventArgs</span>
              <span class="pln">
              </span>
              <span class="pun">:</span>
              <span class="pln">
              </span>
              <span class="typ">EventArgs</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="typ">ValueConvertingEventArgs</span>
              <span class="pun">(</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">object</span>
              <span class="pln"> value</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">Type</span>
              <span class="pln"> targetType</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">object</span>
              <span class="pln"> parameter</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">CultureInfo</span>
              <span class="pln"> culture</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">this</span>
              <span class="pun">.</span>
              <span class="typ">Value</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln"> value</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">this</span>
              <span class="pun">.</span>
              <span class="typ">TargetType</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln"> targetType</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">this</span>
              <span class="pun">.</span>
              <span class="typ">Parameter</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln"> parameter</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">this</span>
              <span class="pun">.</span>
              <span class="typ">Culture</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln"> culture</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">object</span>
              <span class="pln">
              </span>
              <span class="typ">Value</span>
              <span class="pln">
              </span>
              <span class="pun">{</span>
              <span class="pln">
              </span>
              <span class="kwd">get</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="kwd">private</span>
              <span class="pln">
              </span>
              <span class="kwd">set</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="typ">Type</span>
              <span class="pln">
              </span>
              <span class="typ">TargetType</span>
              <span class="pln">
              </span>
              <span class="pun">{</span>
              <span class="pln">
              </span>
              <span class="kwd">get</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="kwd">private</span>
              <span class="pln">
              </span>
              <span class="kwd">set</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">object</span>
              <span class="pln">
              </span>
              <span class="typ">Parameter</span>
              <span class="pln">
              </span>
              <span class="pun">{</span>
              <span class="pln">
              </span>
              <span class="kwd">get</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="kwd">private</span>
              <span class="pln">
              </span>
              <span class="kwd">set</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="typ">CultureInfo</span>
              <span class="pln">
              </span>
              <span class="typ">Culture</span>
              <span class="pln">
              </span>
              <span class="pun">{</span>
              <span class="pln">
              </span>
              <span class="kwd">get</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="kwd">private</span>
              <span class="pln">
              </span>
              <span class="kwd">set</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">object</span>
              <span class="pln">
              </span>
              <span class="typ">Result</span>
              <span class="pln">
              </span>
              <span class="pun">{</span>
              <span class="pln">
              </span>
              <span class="kwd">get</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="kwd">set</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <p>
Next, I implemented an <strong>IValueConverter</strong> that "forwards" the <strong>Convert</strong> and <strong>ConvertBack</strong> handling
to event listeners, as shown below:
</p>
        <div id="wmd-preview">
          <pre class="default prettyprint">
            <code>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">class</span>
              <span class="pln">
              </span>
              <span class="typ">DelegatedValueConverter</span>
              <span class="pln">
              </span>
              <span class="pun">:</span>
              <span class="pln">
              </span>
              <span class="typ">IValueConverter</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">event</span>
              <span class="pln">
              </span>
              <span class="typ">EventHandler</span>
              <span class="pun">&lt;</span>
              <span class="typ">ValueConvertingEventArgs</span>
              <span class="pun">&gt;</span>
              <span class="pln">
              </span>
              <span class="typ">Converting</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">event</span>
              <span class="pln">
              </span>
              <span class="typ">EventHandler</span>
              <span class="pun">&lt;</span>
              <span class="typ">ValueConvertingEventArgs</span>
              <span class="pun">&gt;</span>
              <span class="pln">
              </span>
              <span class="typ">ConvertingBack</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">object</span>
              <span class="pln">
              </span>
              <span class="typ">Convert</span>
              <span class="pun">(</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">object</span>
              <span class="pln"> value</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">Type</span>
              <span class="pln"> targetType</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">object</span>
              <span class="pln"> parameter</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">CultureInfo</span>
              <span class="pln"> culture</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">if</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="typ">DesignerProperties</span>
              <span class="pun">.</span>
              <span class="typ">IsInDesignTool</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
            </code>
            <code>
              <span class="pln">         </span>
              <span class="kwd">return</span>
              <span class="pln">
              </span>
              <span class="kwd">null</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
              </span>
            </code>
            <code>
              <span class="pln">
                <br />
              </span>
              <span class="pln">        </span>
              <span class="kwd">var</span>
              <span class="pln"> handler </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">this</span>
              <span class="pun">.</span>
              <span class="typ">Converting</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">if</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="pln">handler </span>
              <span class="pun">==</span>
              <span class="pln">
              </span>
              <span class="kwd">null</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
              <span class="pln">            </span>
              <span class="kwd">throw</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">InvalidOperationException</span>
              <span class="pun">(<br /></span>
              <span class="str">"Subscription to 'Converting' is required."</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
              </span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">var</span>
              <span class="pln"> args </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">ValueConvertingEventArgs</span>
              <span class="pun">(</span>
              <span class="pln">
                <br />
value</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
 targetType</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
 parameter</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
 culture</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        handler</span>
              <span class="pun">(</span>
              <span class="kwd">this</span>
              <span class="pun">,</span>
              <span class="pln"> args</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">return</span>
              <span class="pln"> args</span>
              <span class="pun">.</span>
              <span class="typ">Result</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
              </span>
              <span class="pln">
              </span>
              <span class="pln">    </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
                <br />
    </span>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">object</span>
              <span class="pln">
              </span>
              <span class="typ">ConvertBack</span>
              <span class="pun">(</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">object</span>
              <span class="pln"> value</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">Type</span>
              <span class="pln"> targetType</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">object</span>
              <span class="pln"> parameter</span>
              <span class="pun">,</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">CultureInfo</span>
              <span class="pln"> culture</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">if</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="typ">DesignerProperties</span>
              <span class="pun">.</span>
              <span class="typ">IsInDesignTool</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
            </code>
            <code>
              <span class="pln">         </span>
              <span class="kwd">return</span>
              <span class="pln">
              </span>
              <span class="kwd">null</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
              </span>
            </code>
            <code>
              <span class="pln">
                <br />
              </span>
              <span class="pln">        </span>
              <span class="kwd">var</span>
              <span class="pln"> handler </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">this</span>
              <span class="pun">.</span>
              <span class="typ">ConvertingBack</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">if</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="pln">handler </span>
              <span class="pun">==</span>
              <span class="pln">
              </span>
              <span class="kwd">null</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
              <span class="pln">            </span>
              <span class="kwd">throw</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">InvalidOperationException</span>
              <span class="pun">(<br /></span>
              <span class="str">"Subscription to 'ConvertingBack' is required."</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
              </span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">var</span>
              <span class="pln"> args </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">ValueConvertingEventArgs</span>
              <span class="pun">(<br /></span>
              <span class="pln">value</span>
              <span class="pun">,<br /></span>
              <span class="pln"> targetType</span>
              <span class="pun">,<br /></span>
              <span class="pln"> parameter</span>
              <span class="pun">,<br /></span>
              <span class="pln"> culture</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        handler</span>
              <span class="pun">(</span>
              <span class="kwd">this</span>
              <span class="pun">,</span>
              <span class="pln"> args</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">return</span>
              <span class="pln"> args</span>
              <span class="pun">.</span>
              <span class="typ">Result</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
              </span>
              <span class="pln">
              </span>
              <span class="pln">    </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <p>
This implementation throws an <strong>InvalidOperationException</strong> if the related
event does not have any subscribers. After the event executes, the method returns
the value of the <strong>Result</strong> property on the event arguments. The snippets
below show the value converter in action:
</p>
        <p>
          <strong>XAML</strong>:
</p>
        <pre class="default prettyprint">
          <code>
            <span class="tag">&lt;navigation:Page.Resources&gt;</span>
            <span class="pln">
              <br />
    </span>
            <span class="tag">&lt;local:DelegatedValueConverter</span>
            <span class="pln">
              <br />
        </span>
            <span class="atn">x:Key</span>
            <span class="pun">=</span>
            <span class="atv">"DelegatedConverter"</span>
            <span class="pln">
              <br />
        </span>
            <span class="atn">Converting</span>
            <span class="pun">=</span>
            <span class="atv">"OnConverting"</span>
            <span class="pln">
            </span>
            <span class="tag">/&gt;</span>
            <span class="pln">
              <br />
            </span>
            <span class="tag">&lt;/navigation:Page.Resources&gt;</span>
            <span class="pln">
              <br />
              <br />
...<br /><br /></span>
            <span class="tag">&lt;TextBlock</span>
            <span class="pln">
            </span>
            <span class="atn">Text</span>
            <span class="pun">=</span>
            <span class="atv">{Binding</span>
            <span class="pln">
            </span>
            <span class="atn">Stuff</span>
            <span class="pln">, </span>
            <span class="atn">Converter</span>
            <span class="pun">=</span>
            <span class="atv">{StaticResource</span>
            <span class="pln">
            </span>
            <span class="atn">DelegatedConverter</span>
            <span class="pln">}} </span>
            <span class="tag">/&gt;</span>
          </code>
        </pre>
        <p>
          <strong>C# Code-Behind</strong>:
</p>
        <div id="wmd-preview">
          <pre class="default prettyprint">
            <code>
              <span class="kwd">private</span>
              <span class="pln">
              </span>
              <span class="kwd">void</span>
              <span class="pln">
              </span>
              <span class="typ">OnConverting</span>
              <span class="pun">(</span>
              <span class="kwd">object</span>
              <span class="pln"> sender</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="typ">ValueConvertingEventArgs</span>
              <span class="pln"> e</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
    e</span>
              <span class="pun">.</span>
              <span class="typ">Result</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">string</span>
              <span class="pun">.</span>
              <span class="typ">Format</span>
              <span class="pun">(</span>
              <span class="pln">e</span>
              <span class="pun">.</span>
              <span class="typ">Culture</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="str">"Hello,
{0}"</span>
              <span class="pun">,</span>
              <span class="pln"> e</span>
              <span class="pun">.</span>
              <span class="typ">Value</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <hr />
        <p>
With the <strong>DelegatedValueConverter</strong> in tow, I was able to reduce the
overall number of <strong>IValueConverter </strong>implementations in my project.
The new converter allowed the page to take responsibility for conversions each time
it seemed appropriate. I still make new value converter classes if they seem to have
general reusability; however, for one-offs or page-specific conversions, this approach
meets the conversion need without flooding the assembly with converter classes.
</p>
        <p>
Happy Coding!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=75c71e15-a638-4f2b-a620-a2922f1559ce" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Integrating PowerShell Scripts in a Custom MSBuild Task</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2010/09/14/IntegratingPowerShellScriptsInACustomMSBuildTask.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,4809119d-e4cf-4a5c-a390-717924b0471a.aspx</id>
    <published>2010-09-13T23:28:49.024-06:00</published>
    <updated>2010-09-13T23:34:56.8938864-06:00</updated>
    <category term="MSBuild" label="MSBuild" scheme="http://www.notesoncode.com/articles/CategoryView,category,MSBuild.aspx" />
    <category term="PowerShell" label="PowerShell" scheme="http://www.notesoncode.com/articles/CategoryView,category,PowerShell.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <h3>Background<br /></h3>
        <p>
I came across an interesting question recently. How does one execute a PowerShell
script in a Visual Studio project's pre- or post-build event, and get precise error
message feedback when errors occur.
</p>
        <p>
Part of the problem is that errors seem to get "swallowed" in the PowerShell script.
Output can be directed to the console as the post-build event occurs, but nothing
gets sent to the error window, and the build is not interrupted on error.
</p>
        <p>
My initial inclination was to simply use PowerShell error trapping and exit() codes
in the PowerShell script to classify errors, but that hardly pleases the imagination.
At least it provides build termination if you call exit() with any non-zero value,
but it lacks precision.
</p>
        <p>
When compilation errors occur in C# code, Visual Studio provides line numbers and
column positions of the error, with the handly double-click jump-to-error goodness
that makes tracking down the error at least a little less tedious. Using exit() codes
does not provide the same quality of service for PowerShell scripts.
</p>
        <p>
So, in an attempt to find the grail, I developed a small MSBuild task for executing
PowerShell scripts and logging their errors for display in Visual studio. Here is
how it was done.
</p>
        <p>
Sample Project: <a href="content/attachments/Noc.PsBuild.zip">Noc.PsBuild.zip (9.35
KB)</a></p>
        <h3>Creating The MSBuild Task<br /></h3>
        <p>
          <em>(The sample project uses Visual Studio 2008 and targets the .NET Framework 3.5.
I believe the solution can be adapted forward to VS 2010 and backward to VS 2005.
The MSBuild task also requires PowerShell 2.0.)</em>
        </p>
        <p>
The project references the following assemblies for MSBuild and for PowerShell automation:
</p>
        <ul>
          <li>
Microsoft.Build.Framework (GAC)</li>
          <li>
Microsoft.Build.Utilities.v3.5 (GAC)</li>
          <li>
System.Management.Automation (from C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0)</li>
        </ul>
        <p>
Executing a PowerShell script from an MSBuild task turned out to be fairly easy. I
started with a task skeleton that includes a property to specify the path to the PowerShell
script.
</p>
        <pre class="prettyprint">
          <code>
            <span class="kwd">using</span>
            <span class="pln">
            </span>
            <span class="typ">System</span>
            <span class="pun">.</span>
            <span class="pln">IO</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">using</span>
            <span class="pln">
            </span>
            <span class="typ">System</span>
            <span class="pun">.</span>
            <span class="typ">Management</span>
            <span class="pun">.</span>
            <span class="typ">Automation</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">using</span>
            <span class="pln">
            </span>
            <span class="typ">System</span>
            <span class="pun">.</span>
            <span class="typ">Management</span>
            <span class="pun">.</span>
            <span class="typ">Automation</span>
            <span class="pun">.</span>
            <span class="typ">Runspaces</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">using</span>
            <span class="pln">
            </span>
            <span class="typ">Microsoft</span>
            <span class="pun">.</span>
            <span class="typ">Build</span>
            <span class="pun">.</span>
            <span class="typ">Framework</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">using</span>
            <span class="pln">
            </span>
            <span class="typ">Microsoft</span>
            <span class="pun">.</span>
            <span class="typ">Build</span>
            <span class="pun">.</span>
            <span class="typ">Utilities</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
              <br />
            </span>
            <span class="kwd">public</span>
            <span class="pln">
            </span>
            <span class="kwd">class</span>
            <span class="pln">
            </span>
            <span class="typ">PsBuildTask</span>
            <span class="pln">
            </span>
            <span class="pun">:</span>
            <span class="pln">
            </span>
            <span class="typ">Task</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">{</span>
            <span class="pln">
              <br />
    </span>
            <span class="pun">[</span>
            <span class="typ">Required</span>
            <span class="pun">]</span>
            <span class="pln">
              <br />
    </span>
            <span class="kwd">public</span>
            <span class="pln">
            </span>
            <span class="kwd">string</span>
            <span class="pln">
            </span>
            <span class="typ">ScriptPath</span>
            <span class="pln">
            </span>
            <span class="pun">{</span>
            <span class="pln">
            </span>
            <span class="kwd">get</span>
            <span class="pun">;</span>
            <span class="pln">
            </span>
            <span class="kwd">set</span>
            <span class="pun">;</span>
            <span class="pln">
            </span>
            <span class="pun">}</span>
            <span class="pln">
              <br />
              <br />
    </span>
            <span class="kwd">public</span>
            <span class="pln">
            </span>
            <span class="kwd">override</span>
            <span class="pln">
            </span>
            <span class="kwd">bool</span>
            <span class="pln">
            </span>
            <span class="typ">Execute</span>
            <span class="pun">()</span>
            <span class="pln">
              <br />
    </span>
            <span class="pun">{</span>
            <span class="pln">
              <br />
        </span>
            <span class="com">// ...</span>
            <span class="pln">
              <br />
    </span>
            <span class="pun">}</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">}</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
The class inherits from Task, which provides all the infrastructure for generating
compiler errors and warnings via the Log property. The Execute() method should return
false if the task is considered to fail. In this case, it should return false if a
script contains errors. All that remains is to fire up the PowerShell runtime and
execute the specified script.
</p>
        <p>
The following code snippet starts the PowerShell runtime, adds a dot-sourcing command
to the pipeline, executes the pipeline, and retrieves the errors.
</p>
        <pre class="prettyprint">
          <code>
            <span class="com">// create Powershell runspace</span>
            <span class="pln">
              <br />
            </span>
            <span class="typ">Runspace</span>
            <span class="pln"> runspace </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="typ">RunspaceFactory</span>
            <span class="pun">.</span>
            <span class="typ">CreateRunspace</span>
            <span class="pun">();</span>
            <span class="pln">
              <br />
runspace</span>
            <span class="pun">.</span>
            <span class="typ">Open</span>
            <span class="pun">();</span>
            <span class="pln">
              <br />
              <br />
            </span>
            <span class="com">// create a pipeline and feed it the script text</span>
            <span class="pln">
              <br />
            </span>
            <span class="typ">Pipeline</span>
            <span class="pln"> pipeline </span>
            <span class="pun">=</span>
            <span class="pln"> runspace</span>
            <span class="pun">.</span>
            <span class="typ">CreatePipeline</span>
            <span class="pun">();</span>
            <span class="pln">
              <br />
pipeline</span>
            <span class="pun">.</span>
            <span class="typ">Commands</span>
            <span class="pun">.</span>
            <span class="typ">AddScript</span>
            <span class="pun">(</span>
            <span class="str">".
"</span>
            <span class="pln">
            </span>
            <span class="pun">+</span>
            <span class="pln">
            </span>
            <span class="typ">ScriptPath</span>
            <span class="pun">);</span>
            <span class="pln">
              <br />
              <br />
            </span>
            <span class="com">// execute the script and extract errors</span>
            <span class="pln">
              <br />
pipeline</span>
            <span class="pun">.</span>
            <span class="typ">Invoke</span>
            <span class="pun">();</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">var</span>
            <span class="pln"> errors </span>
            <span class="pun">=</span>
            <span class="pln"> pipeline</span>
            <span class="pun">.</span>
            <span class="typ">Error</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
The errors object can read errors from the pipeline, if they exist, using one of the
Read() overloads. The next snippet iterates through the errors, if any, then retrieves
the error record and logs to the Log utility. This particular LogError() overload
allows the specification of which file, line, and column is responsible for the error.
That is key to getting the double-click send-me-to-the-error behavior in Visual Studio.
</p>
        <pre class="prettyprint">
          <code>
            <span class="com">// log an MSBuild error for each
error.</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">foreach</span>
            <span class="pln">
            </span>
            <span class="pun">(</span>
            <span class="typ">PSObject</span>
            <span class="pln"> error </span>
            <span class="kwd">in</span>
            <span class="pln"> errors</span>
            <span class="pun">.</span>
            <span class="typ">Read</span>
            <span class="pun">(</span>
            <span class="pln">errors</span>
            <span class="pun">.</span>
            <span class="typ">Count</span>
            <span class="pun">))</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">{</span>
            <span class="pln">
              <br />
    </span>
            <span class="kwd">var</span>
            <span class="pln"> invocationInfo </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="pun">((</span>
            <span class="typ">ErrorRecord</span>
            <span class="pun">)(</span>
            <span class="pln">error</span>
            <span class="pun">.</span>
            <span class="typ">BaseObject</span>
            <span class="pun">)).</span>
            <span class="typ">InvocationInfo</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
    </span>
            <span class="typ">Log</span>
            <span class="pun">.</span>
            <span class="typ">LogError</span>
            <span class="pun">(</span>
            <span class="pln">
              <br />
        </span>
            <span class="str">"Script"</span>
            <span class="pun">,</span>
            <span class="pln">
              <br />
        </span>
            <span class="kwd">string</span>
            <span class="pun">.</span>
            <span class="typ">Empty</span>
            <span class="pun">,</span>
            <span class="pln">
              <br />
        </span>
            <span class="kwd">string</span>
            <span class="pun">.</span>
            <span class="typ">Empty</span>
            <span class="pun">,</span>
            <span class="pln">
              <br />
        </span>
            <span class="kwd">new</span>
            <span class="pln">
            </span>
            <span class="typ">FileInfo</span>
            <span class="pun">(</span>
            <span class="typ">ScriptPath</span>
            <span class="pun">).</span>
            <span class="typ">FullName</span>
            <span class="pun">,</span>
            <span class="pln">
              <br />
        invocationInfo</span>
            <span class="pun">.</span>
            <span class="typ">ScriptLineNumber</span>
            <span class="pun">,</span>
            <span class="pln">
              <br />
        invocationInfo</span>
            <span class="pun">.</span>
            <span class="typ">OffsetInLine</span>
            <span class="pun">,</span>
            <span class="pln">
              <br />
        </span>
            <span class="lit">0</span>
            <span class="pun">,</span>
            <span class="pln">
              <br />
        </span>
            <span class="lit">0</span>
            <span class="pun">,</span>
            <span class="pln">
              <br />
        error</span>
            <span class="pun">.</span>
            <span class="typ">ToString</span>
            <span class="pun">());</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">}</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
Finally, close the runtime and return true if there were no errors logged.
</p>
        <pre class="prettyprint">
          <code>
            <span class="com">// close the runspace</span>
            <span class="pln">
              <br />
runspace</span>
            <span class="pun">.</span>
            <span class="typ">Close</span>
            <span class="pun">();</span>
            <span class="pln">
              <br />
              <br />
            </span>
            <span class="kwd">return</span>
            <span class="pln">
            </span>
            <span class="pun">!</span>
            <span class="typ">Log</span>
            <span class="pun">.</span>
            <span class="typ">HasLoggedErrors</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
That's it for the MSBuild task. Now, to use the task, it must either be installed
to the GAC, or placed in a known location. Once that is established, other projects
can be configured to consume this new task.
</p>
        <h3>Consuming the MSBuild Task<br /></h3>
        <p>
Consider, for example, a C#-based class library project (.csproj). Integrating the
task in a post build event requires just a few things.
</p>
        <p>
First, register the task just inside the &lt;Project&gt; node of the .csproj file
like so:
</p>
        <pre class="prettyprint">
          <code>
            <span class="tag">&lt;UsingTask</span>
            <span class="pln">
            </span>
            <span class="atn">TaskName</span>
            <span class="pun">=</span>
            <span class="atv">"PsBuildTask"</span>
            <span class="pln">
              <br />
           </span>
            <span class="atn">AssemblyFile</span>
            <span class="pun">=</span>
            <span class="atv">"..\Noc.PsBuild\bin\Debug\Noc.PsBuild.dll"</span>
            <span class="pln">
            </span>
            <span class="tag">/&gt;</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
TaskName should be the name of the task, though it appears namespace is not required.
Assembly file is an absolute path to the custom MSBuild task assembly, or relative
path with respect to the .csproj file. For assemblies in the GAC, you can use the
AssemblyName attribute instead.
</p>
        <p>
Once registered, the task can be used within pre- and post-build events. Configure
a build event within the &lt;Project&gt; element of the .csproj file like so:
</p>
        <pre class="prettyprint">
          <code>
            <span class="tag">&lt;Target</span>
            <span class="pln">
            </span>
            <span class="atn">Name</span>
            <span class="pun">=</span>
            <span class="atv">"AfterBuild"</span>
            <span class="tag">&gt;</span>
            <span class="pln">
              <br />
    </span>
            <span class="tag">&lt;PsBuildTask</span>
            <span class="pln">
            </span>
            <span class="atn">ScriptPath</span>
            <span class="pun">=</span>
            <span class="atv">".\script.ps1"</span>
            <span class="pln">
            </span>
            <span class="tag">/&gt;</span>
            <span class="pln">
              <br />
            </span>
            <span class="tag">&lt;/Target&gt;</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
And that's it. When Visual Studio compiles the project, it loads the custom assembly
and task object and executes the task. Errors raised by the pipeline are retrieved
and reported.
</p>
        <p>
          <img src="content/attachments/PsBuildTask.png" border="0" alt="" width="399" height="295" />
        </p>
        <p>
Now, a final note about the sample project. Visual Studio has a nasty habit of locking
the Noc.PsBuild assembly each time Noc.PsBuild.Demo builds. That means that to rebuild
this solution more than once requires restarting Visual Studio. This is all well and
good for a demo, but of course this project structure, where the build task is in
the same solution as a dependent assembly, is not ideal for real development. Also,
the solution has only the "Works on My Machine" seal of approval. There could be gotchas,
and it certainly could be extended to be even more flexible. Also, the script.ps1
file may be blocked if your execution policy is RemoteSigned. You'll need to unblock
it or relax the policy to get successful execution. Good luck with it.
</p>
        <p>
Happy coding!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=4809119d-e4cf-4a5c-a390-717924b0471a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Handling transparent Images on the clipboard is, for some reason, hard</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2010/08/16/HandlingTransparentImagesOnTheClipboardIsForSomeReasonHard.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,9477983d-2c67-4143-8fa8-2cc480d05c98.aspx</id>
    <published>2010-08-15T23:55:59.583-06:00</published>
    <updated>2010-08-15T01:52:22.3539552-06:00</updated>
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <category term="Extension Methods" label="Extension Methods" scheme="http://www.notesoncode.com/articles/CategoryView,category,ExtensionMethods.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p style="padding-left: 30px;">
Sample code: <a href="content/attachments/Noc.Demo.Clipboard.zip">Noc.Demo.Clipboard.zip
(163.36 KB)</a></p>
        <p>
I came across an interesting problem, the other day. The task at had was to copy an
image to the Clipboard and maintain the alpha channel for pasting into applications
such as Word, PowerPoint, Gimp, or Paint.NET.
</p>
        <p>
What boggles my mind is: this is actually somewhat... well... hard.
</p>
        <h2>Clipboard handling that the .NET Framework forgot<br /></h2>
        <p>
Don't get me wrong. Getting an image onto the clipboard is somewhat easy. It's a one-liner,
really:
</p>
        <div id="wmd-preview">
          <pre class="prettyprint">
            <code>
              <span class="typ">Clipboard</span>
              <span class="pun">.</span>
              <span class="typ">SetImage</span>
              <span class="pun">(</span>
              <span class="pln">myImage</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <p>
The problem with this approach is that the image loses its alpha channel, converting
an image like this:
</p>
        <p style="text-align: center;">
          <img src="content/attachments/demo.png" border="0" alt="" width="210" height="158" />
        </p>
        <p style="text-align: left;">
... to an image like this:
</p>
        <p style="text-align: left;">
 
</p>
        <p style="text-align: center;">
          <img style="border: 0;" src="content/attachments/demogray.png" border="0" alt="" width="210" height="158" />
        </p>
        <p style="text-align: left;">
The resulting image is a 24-bit per pixel bitmap, with the transparent background
filled by a soft gray. I have it on good report that older versions of windows swap
out the transparent color for a virulent blue.
</p>
        <p style="text-align: left;">
Now, I've seen applications cop out of transparency by using black or white, or even
a gut wrenching magenta, for the intent of masking out the default color at run time.
But <em>gray</em>? Why not try to be right <em>some of the time</em> instead of being
wrong <em>all of the time</em>. Who ever really wants to swap out transparency for
soft gray?
</p>
        <h2 style="text-align: left;">Covering up the gray with a little color
</h2>
        <p>
We all know someone who does it. Age creeps up and it's off to the salon for some
dye.
</p>
        <p>
When transparency is not strictly a requirement, a little bit of code can get us on
the way to filling an image with a solid background. For this, I prefer the following
extension method:
</p>
        <div id="wmd-preview">
          <pre class="prettyprint">
            <code>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">static</span>
              <span class="pln">
              </span>
              <span class="typ">Image</span>
              <span class="pln">
              </span>
              <span class="typ">CreateOpaqueBitmap</span>
              <span class="pun">(</span>
              <span class="kwd">this</span>
              <span class="pln">
              </span>
              <span class="typ">Image</span>
              <span class="pln"> image</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="typ">Color</span>
              <span class="pln"> backgroundColor</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">var</span>
              <span class="pln"> bitmap </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">Bitmap</span>
              <span class="pun">(</span>
              <span class="pln">image</span>
              <span class="pun">.</span>
              <span class="typ">Width</span>
              <span class="pun">,</span>
              <span class="pln"> image</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="typ">PixelFormat</span>
              <span class="pun">.</span>
              <span class="typ">Format24bppRgb</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">using</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">var</span>
              <span class="pln"> graphics </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="typ">Graphics</span>
              <span class="pun">.</span>
              <span class="typ">FromImage</span>
              <span class="pun">(</span>
              <span class="pln">bitmap</span>
              <span class="pun">))</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
        graphics</span>
              <span class="pun">.</span>
              <span class="typ">Clear</span>
              <span class="pun">(</span>
              <span class="pln">backgroundColor</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        graphics</span>
              <span class="pun">.</span>
              <span class="typ">DrawImage</span>
              <span class="pun">(</span>
              <span class="pln">image</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">,</span>
              <span class="pln"> image</span>
              <span class="pun">.</span>
              <span class="typ">Width</span>
              <span class="pun">,</span>
              <span class="pln"> image</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
                <br />
    </span>
              <span class="kwd">return</span>
              <span class="pln"> bitmap</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <p>
With the extension method in hand, adding an opaque image to the clipboard was never
easier:
</p>
        <div id="wmd-preview">
          <div id="wmd-preview">
            <pre class="prettyprint">
              <code>
                <span class="kwd">using</span>
                <span class="pln">
                </span>
                <span class="pun">(</span>
                <span class="kwd">var</span>
                <span class="pln"> bitmap </span>
                <span class="pun">=</span>
                <span class="pln"> image</span>
                <span class="pun">.</span>
                <span class="typ">CreateOpaqueBitmap</span>
                <span class="pun">(</span>
                <span class="typ">Color</span>
                <span class="pun">.</span>
                <span class="typ">Magenta</span>
                <span class="pun">))</span>
                <span class="pln">
                  <br />
                </span>
                <span class="pun">{</span>
                <span class="pln">
                  <br />
    </span>
                <span class="typ">Clipboard</span>
                <span class="pun">.</span>
                <span class="typ">Clear</span>
                <span class="pun">();</span>
                <span class="pln">
                  <br />
    </span>
                <span class="typ">Clipboard</span>
                <span class="pun">.</span>
                <span class="typ">SetImage</span>
                <span class="pun">(</span>
                <span class="pln">bitmap</span>
                <span class="pun">);</span>
                <span class="pln">
                  <br />
                </span>
                <span class="pun">}</span>
                <span class="pln">
                  <br />
                </span>
              </code>
            </pre>
          </div>
        </div>
        <p style="text-align: center;">
          <img style="border: 0pt none;" src="content/attachments/demomagenta.png" border="0" alt="" width="210" height="158" />
        </p>
        <h2>But I really <em>need</em> transparency!
</h2>
        <p>
Creating opaque images really only massages an ache, but really doesn't solve the
problem. What can be done about transparency?
</p>
        <p>
A complete answer requires a little understanding of Windows <a href="http://msdn.microsoft.com/en-us/library/ms649013(VS.85).aspx" target="_blank">clipboard
formats</a>. It helps to think of clipboard data as a set of key-value pairs. The
key identifies what format the data is expected to be, and the value is the actual
data. The clipboard can have multiple kinds of data, all representing (supposedly)
the same thing, at any given time.
</p>
        <p>
Some applications can take advantage of this fact to provide <em>text</em> data along
with an image, so that pastes will provide <em>something</em> if pasting in a text
editor, and <em>something else</em> if pasted in an image editor.
</p>
        <p>
What is more often the case is that an application will provide multiple image formats
to increase compatibility with other image software. As a matter of fact, Windows
provides free type conversions between some of the most common image types (e.g. Bitmap
to System.Drawing.Bitmap).
</p>
        <p>
It helps to get a feel for what formats are supported for pasting in an application
and their relative priority by inspecting what formats are generated when copying
from the application. Here are formats generated when copying images from a few favorite
applications:
</p>
        <ul>
          <li>
GIMP: PNG, DeviceIndependentBitmap, System.Drawing.Bitmap, Bitmap, Format17</li>
          <li>
Paint.NET: System.Drawing.Bitmap, Bitmap, PaintDotNet.MaskedSurface</li>
          <li>
Fireworks: Fireworks Internal Clipboard Format 3.0, PNG, DeviceIndependentBitmap</li>
          <li>
MS Paint: Embed Source, Object Descriptor, MetaFilePict, DeviceIndependentBitmap</li>
          <li>
Print Screen (on the keyboard): System.Drawing.Bitmap, Bitmap, DeviceIndependentBitmap,
Format17</li>
          <li>
PhotoScape: System.Drawing.Bitmap, Bitmap, DeviceIndependentBitmap, Format17</li>
          <li>
MS Word: Art::GVML ClipFormat, System.Drawing.Bitmap, Bitmap, PNG, JFIF, GIF, EnhancedMetafile,
MetaFilePict, Object Descriptor</li>
          <li>
MS PowerPoint: Preferred DropEffect, InShellDragLoop, PowerPoint 12.0 Internal Shapes,
Object Descriptor, Art::GVML ClipFormat, PNG, JFIF, GIF, System.Drawing.Bitmap, Bitmap,
EnhancedMetafile, MetaFilePict, PowerPoint 12.0 Internal Theme, PowerPoint 12.0 Internal
Color Scheme</li>
        </ul>
        <h2>Adding transparency with PNG.<br /></h2>
        <p>
It would seem that DeviceIndependentBitmap, Bitmap, and System.Drawing.Bitmap are
the most common formats in the group; however, they are 24-bit opaque bitmaps. Generating
a transparent clipboard data type requires that we properly encode data using a format
that supports an alpha channel.
</p>
        <p>
In the applications above, the PNG (Portable Network Graphics) format is generated
by GIMP, Fireworks, Word, and PowerPoint. We can hope for transparency success in
a broad array of applications merely by placing PNG-formatted data on the clipboard.
Lucky for us, it doesn't take much to write:
</p>
        <div id="wmd-preview">
          <pre class="prettyprint">
            <code>
              <span class="kwd">using</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">var</span>
              <span class="pln"> stream </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">MemoryStream</span>
              <span class="pun">())</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
    image</span>
              <span class="pun">.</span>
              <span class="typ">Save</span>
              <span class="pun">(</span>
              <span class="pln">stream</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="typ">ImageFormat</span>
              <span class="pun">.</span>
              <span class="typ">Png</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">var</span>
              <span class="pln"> data </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">DataObject</span>
              <span class="pun">(</span>
              <span class="str">"PNG"</span>
              <span class="pun">,</span>
              <span class="pln"> stream</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
                <br />
    </span>
              <span class="typ">Clipboard</span>
              <span class="pun">.</span>
              <span class="typ">Clear</span>
              <span class="pun">();</span>
              <span class="pln">
                <br />
    </span>
              <span class="typ">Clipboard</span>
              <span class="pun">.</span>
              <span class="typ">SetDataObject</span>
              <span class="pun">(</span>
              <span class="pln">data</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="kwd">true</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <h2>Adding transparency with 32-bit ARGB bitmap
</h2>
        <p>
Not every application supports PNG formats. It is probably a good idea to have a secondary
format at hand to deal with transparency. It is possible to get a 32bpp image into
the clipboard with a little bit of work.
</p>
        <p>
The format at hand, Format17 (a.k.a. CF_DIBV5)
</p>
        <p>
I almost hate to bring it up, really, mostly because so many applications either mishandle
it, or ignore it altogether. Take the print screen utility, for example. It does generate
valid 32bpp Format17 content, but zeroes all the alpha bytes, and keeps a zero-ing
byte mask for alpha just in case. In other words, it may be using a transparency-enabled
format, but the content isn't transparent. GIMP mishandles the <a href="http://msdn.microsoft.com/en-us/library/dd183381(v=VS.85).aspx" target="_blank">BITMAPV5HEADER</a>,
by accidentally omitting the bV5SizeImage field that is responsible for identifying
how many bits are in the bitmap. (In fairness to GIMP, a clever application could
compute the value based on other fields in the header.) Paint.NET appears to disregard
formats other than 24bpp bitmaps and its own internal MaskedSurface format. Both PhotoScape
and GIMP either disregard Format17 altogether (in favor of Bitmap formats) or mishandle
the alpha, giving paste results like this:
</p>
        <p style="text-align: center;">
          <img style="border: 0pt none;" src="content/attachments/demoblack.png" border="0" alt="" width="210" height="158" />
        </p>
        <p>
So, with <em>"You probably won't find this useful,"</em> as a disclaimer, let's see
how it's done.
</p>
        <p>
The first method is a utility method that copies a 32bpp image into global memory
using interop and a little native marshalling. Basically, the method creates a bitmap
header and marshals it out into memory, then adds the image bits, last row first,
after the header. Note that all the interop methods and constants are omitted for
brevity.
</p>
        <div id="wmd-preview">
          <pre class="prettyprint">
            <code>
              <span class="kwd">private</span>
              <span class="pln">
              </span>
              <span class="kwd">static</span>
              <span class="pln">
              </span>
              <span class="typ">IntPtr</span>
              <span class="pln">
              </span>
              <span class="typ">CreatePackedDIBV5</span>
              <span class="pun">(</span>
              <span class="kwd">this</span>
              <span class="pln">
              </span>
              <span class="typ">Bitmap</span>
              <span class="pln"> bitmap</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
    </span>
              <span class="typ">BitmapData</span>
              <span class="pln"> bmData </span>
              <span class="pun">=</span>
              <span class="pln"> bitmap</span>
              <span class="pun">.</span>
              <span class="typ">LockBits</span>
              <span class="pun">(</span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">Rectangle</span>
              <span class="pun">(</span>
              <span class="lit">0</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">,</span>
              <span class="pln"> bitmap</span>
              <span class="pun">.</span>
              <span class="typ">Width</span>
              <span class="pun">,</span>
              <span class="pln"> bitmap</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pun">),</span>
              <span class="pln">
              </span>
              <span class="typ">ImageLockMode</span>
              <span class="pun">.</span>
              <span class="typ">ReadOnly</span>
              <span class="pun">,</span>
              <span class="pln"> bitmap</span>
              <span class="pun">.</span>
              <span class="typ">PixelFormat</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">uint</span>
              <span class="pln"> bufferLen </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">uint</span>
              <span class="pun">)(</span>
              <span class="typ">Marshal</span>
              <span class="pun">.</span>
              <span class="typ">SizeOf</span>
              <span class="pun">(</span>
              <span class="kwd">typeof</span>
              <span class="pun">(</span>
              <span class="pln">BITMAPV5HEADER</span>
              <span class="pun">))</span>
              <span class="pln">
              </span>
              <span class="pun">+</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pln">
              </span>
              <span class="pun">*</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Stride</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="typ">IntPtr</span>
              <span class="pln"> hMem </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="typ">Kernel32</span>
              <span class="pun">.</span>
              <span class="typ">NativeMethods</span>
              <span class="pun">.</span>
              <span class="typ">GlobalAlloc</span>
              <span class="pun">(</span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="pln">GHND </span>
              <span class="pun">|</span>
              <span class="pln">
              </span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="pln">GMEM_DDESHARE</span>
              <span class="pun">,</span>
              <span class="pln"> bufferLen</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="typ">IntPtr</span>
              <span class="pln"> packedDIBV5 </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="typ">Kernel32</span>
              <span class="pun">.</span>
              <span class="typ">NativeMethods</span>
              <span class="pun">.</span>
              <span class="typ">GlobalLock</span>
              <span class="pun">(</span>
              <span class="pln">hMem</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
                <br />
    BITMAPV5HEADER bmi </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="pln">BITMAPV5HEADER</span>
              <span class="pun">)</span>
              <span class="typ">Marshal</span>
              <span class="pun">.</span>
              <span class="typ">PtrToStructure</span>
              <span class="pun">(</span>
              <span class="pln">packedDIBV5</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="kwd">typeof</span>
              <span class="pun">(</span>
              <span class="pln">BITMAPV5HEADER</span>
              <span class="pun">));</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Size </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">uint</span>
              <span class="pun">)</span>
              <span class="typ">Marshal</span>
              <span class="pun">.</span>
              <span class="typ">SizeOf</span>
              <span class="pun">(</span>
              <span class="kwd">typeof</span>
              <span class="pun">(</span>
              <span class="pln">BITMAPV5HEADER</span>
              <span class="pun">));</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Width </span>
              <span class="pun">=</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Width</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Height </span>
              <span class="pun">=</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Planes </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">1</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5BitCount </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">32</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Compression </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="pln">BI_BITFIELDS</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5SizeImage </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">uint</span>
              <span class="pun">)(</span>
              <span class="pln">bmData</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pln">
              </span>
              <span class="pun">*</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Stride</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5XPelsPerMeter </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5YPelsPerMeter </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5ClrUsed </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5ClrImportant </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5RedMask </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0x00FF0000</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5GreenMask </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0x0000FF00</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5BlueMask </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0x000000FF</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5AlphaMask </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0xFF000000</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5CSType </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0x73524742</span>
              <span class="pun">;</span>
              <span class="pln">
              </span>
              <span class="com">//
User32.LCS_WINDOWS_COLOR_SPACE;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzBlue</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzX </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzBlue</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzY </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzBlue</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzZ </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzGreen</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzX </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzGreen</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzY </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzGreen</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzZ </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzRed</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzX </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzRed</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzY </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Endpoints</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzRed</span>
              <span class="pun">.</span>
              <span class="pln">ciexyzZ </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5GammaRed </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5GammaGreen </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5GammaBlue </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5ProfileData </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5ProfileSize </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Reserved </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Intent </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="pln">LCS_GM_IMAGES</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    </span>
              <span class="typ">Marshal</span>
              <span class="pun">.</span>
              <span class="typ">StructureToPtr</span>
              <span class="pun">(</span>
              <span class="pln">bmi</span>
              <span class="pun">,</span>
              <span class="pln"> packedDIBV5</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="kwd">false</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
                <br />
    </span>
              <span class="kwd">long</span>
              <span class="pln"> offsetBits </span>
              <span class="pun">=</span>
              <span class="pln"> bmi</span>
              <span class="pun">.</span>
              <span class="pln">bV5Size</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
    </span>
              <span class="typ">IntPtr</span>
              <span class="pln"> bits </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="typ">IntPtr</span>
              <span class="pun">)(</span>
              <span class="pln">packedDIBV5</span>
              <span class="pun">.</span>
              <span class="typ">ToInt32</span>
              <span class="pun">()</span>
              <span class="pln">
              </span>
              <span class="pun">+</span>
              <span class="pln"> offsetBits</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">for</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">int</span>
              <span class="pln"> y </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln"> y </span>
              <span class="pun">&lt;</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pun">;</span>
              <span class="pln"> y</span>
              <span class="pun">++)</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">IntPtr</span>
              <span class="pln">
              </span>
              <span class="typ">DstDib</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="typ">IntPtr</span>
              <span class="pun">)(</span>
              <span class="pln">bits</span>
              <span class="pun">.</span>
              <span class="typ">ToInt32</span>
              <span class="pun">()</span>
              <span class="pln">
              </span>
              <span class="pun">+</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="pln">y </span>
              <span class="pun">*</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Stride</span>
              <span class="pun">));</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">IntPtr</span>
              <span class="pln">
              </span>
              <span class="typ">SrcDib</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="typ">IntPtr</span>
              <span class="pun">)(</span>
              <span class="pln">bmData</span>
              <span class="pun">.</span>
              <span class="typ">Scan0</span>
              <span class="pun">.</span>
              <span class="typ">ToInt32</span>
              <span class="pun">()</span>
              <span class="pln">
              </span>
              <span class="pun">+</span>
              <span class="pln">
              </span>
              <span class="pun">((</span>
              <span class="pln">bmData</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pln">
              </span>
              <span class="pun">-</span>
              <span class="pln">
              </span>
              <span class="lit">1</span>
              <span class="pln">
              </span>
              <span class="pun">-</span>
              <span class="pln"> y</span>
              <span class="pun">)</span>
              <span class="pln">
              </span>
              <span class="pun">*</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Stride</span>
              <span class="pun">));</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">for</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">int</span>
              <span class="pln"> x </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">;</span>
              <span class="pln"> x </span>
              <span class="pun">&lt;</span>
              <span class="pln"> bmData</span>
              <span class="pun">.</span>
              <span class="typ">Width</span>
              <span class="pun">;</span>
              <span class="pln"> x</span>
              <span class="pun">++)</span>
              <span class="pln">
                <br />
        </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
            </span>
              <span class="typ">Marshal</span>
              <span class="pun">.</span>
              <span class="typ">WriteInt32</span>
              <span class="pun">(</span>
              <span class="typ">DstDib</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="typ">Marshal</span>
              <span class="pun">.</span>
              <span class="typ">ReadInt32</span>
              <span class="pun">(</span>
              <span class="typ">SrcDib</span>
              <span class="pun">));</span>
              <span class="pln">
                <br />
            </span>
              <span class="typ">DstDib</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="typ">IntPtr</span>
              <span class="pun">)(</span>
              <span class="typ">DstDib</span>
              <span class="pun">.</span>
              <span class="typ">ToInt32</span>
              <span class="pun">()</span>
              <span class="pln">
              </span>
              <span class="pun">+</span>
              <span class="pln">
              </span>
              <span class="lit">4</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
            </span>
              <span class="typ">SrcDib</span>
              <span class="pln">
              </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="typ">IntPtr</span>
              <span class="pun">)(</span>
              <span class="typ">SrcDib</span>
              <span class="pun">.</span>
              <span class="typ">ToInt32</span>
              <span class="pun">()</span>
              <span class="pln">
              </span>
              <span class="pun">+</span>
              <span class="pln">
              </span>
              <span class="lit">4</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
                <br />
    bitmap</span>
              <span class="pun">.</span>
              <span class="typ">UnlockBits</span>
              <span class="pun">(</span>
              <span class="pln">bmData</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="typ">Kernel32</span>
              <span class="pun">.</span>
              <span class="typ">NativeMethods</span>
              <span class="pun">.</span>
              <span class="typ">GlobalUnlock</span>
              <span class="pun">(</span>
              <span class="pln">hMem</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">return</span>
              <span class="pln"> hMem</span>
              <span class="pun">;</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <p>
With the utility method at hand, adding an image to the clipboard using CF_DIBV5 (Format17)
formatting is as easy as:
</p>
        <div id="wmd-preview">
          <pre class="prettyprint">
            <code>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">static</span>
              <span class="pln">
              </span>
              <span class="kwd">void</span>
              <span class="pln">
              </span>
              <span class="typ">Copy32BppBitmapToClipboard</span>
              <span class="pun">(</span>
              <span class="kwd">this</span>
              <span class="pln">
              </span>
              <span class="typ">Image</span>
              <span class="pln"> image</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">using</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">var</span>
              <span class="pln"> bitmap </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">Bitmap</span>
              <span class="pun">(</span>
              <span class="pln">image</span>
              <span class="pun">.</span>
              <span class="typ">Width</span>
              <span class="pun">,</span>
              <span class="pln"> image</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="typ">PixelFormat</span>
              <span class="pun">.</span>
              <span class="typ">Format32bppArgb</span>
              <span class="pun">))</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">using</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">var</span>
              <span class="pln"> bitmapGraphics </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="typ">Graphics</span>
              <span class="pun">.</span>
              <span class="typ">FromImage</span>
              <span class="pun">(</span>
              <span class="pln">bitmap</span>
              <span class="pun">))</span>
              <span class="pln">
                <br />
        </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
            bitmapGraphics</span>
              <span class="pun">.</span>
              <span class="typ">DrawImage</span>
              <span class="pun">(</span>
              <span class="pln">image</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="lit">0</span>
              <span class="pun">,</span>
              <span class="pln"> image</span>
              <span class="pun">.</span>
              <span class="typ">Width</span>
              <span class="pun">,</span>
              <span class="pln"> image</span>
              <span class="pun">.</span>
              <span class="typ">Height</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
                <br />
        </span>
              <span class="kwd">var</span>
              <span class="pln"> packedDIBV5 </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="typ">CreatePackedDIBV5</span>
              <span class="pun">(</span>
              <span class="pln">bitmap</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="typ">NativeMethods</span>
              <span class="pun">.</span>
              <span class="typ">OpenClipboard</span>
              <span class="pun">(</span>
              <span class="typ">IntPtr</span>
              <span class="pun">.</span>
              <span class="typ">Zero</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="typ">NativeMethods</span>
              <span class="pun">.</span>
              <span class="typ">EmptyClipboard</span>
              <span class="pun">();</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="typ">NativeMethods</span>
              <span class="pun">.</span>
              <span class="typ">SetClipboardData</span>
              <span class="pun">(</span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="pln">CF_DIBV5</span>
              <span class="pun">,</span>
              <span class="pln"> packedDIBV5</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">User32</span>
              <span class="pun">.</span>
              <span class="typ">NativeMethods</span>
              <span class="pun">.</span>
              <span class="typ">CloseClipboard</span>
              <span class="pun">();</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <h2>Bringing it home
</h2>
        <p>
I consider the 32bpp CF_DIBV5 format to be a lot of work, considering the poor support
of the format offered by so many applications. I've found that taking a pragmatic
approach, aiming for PNG transparency where supported, and accepting the background
color of my choice otherwise, made for a manageable codebase with decent application
compatibility. I use the following extension method to add images to the clipboard:
</p>
        <div id="wmd-preview">
          <pre class="prettyprint">
            <code>
              <span class="kwd">public</span>
              <span class="pln">
              </span>
              <span class="kwd">static</span>
              <span class="pln">
              </span>
              <span class="kwd">void</span>
              <span class="pln">
              </span>
              <span class="typ">CopyMultiFormatBitmapToClipboard</span>
              <span class="pun">(</span>
              <span class="kwd">this</span>
              <span class="pln">
              </span>
              <span class="typ">Image</span>
              <span class="pln"> image</span>
              <span class="pun">)</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">using</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">var</span>
              <span class="pln"> opaque </span>
              <span class="pun">=</span>
              <span class="pln"> image</span>
              <span class="pun">.</span>
              <span class="typ">CreateOpaqueBitmap</span>
              <span class="pun">(</span>
              <span class="typ">Color</span>
              <span class="pun">.</span>
              <span class="typ">White</span>
              <span class="pun">))</span>
              <span class="pln">
                <br />
    </span>
              <span class="kwd">using</span>
              <span class="pln">
              </span>
              <span class="pun">(</span>
              <span class="kwd">var</span>
              <span class="pln"> stream </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">MemoryStream</span>
              <span class="pun">())</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">{</span>
              <span class="pln">
                <br />
        image</span>
              <span class="pun">.</span>
              <span class="typ">Save</span>
              <span class="pun">(</span>
              <span class="pln">stream</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="typ">ImageFormat</span>
              <span class="pun">.</span>
              <span class="typ">Png</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
                <br />
        </span>
              <span class="typ">Clipboard</span>
              <span class="pun">.</span>
              <span class="typ">Clear</span>
              <span class="pun">();</span>
              <span class="pln">
                <br />
        </span>
              <span class="kwd">var</span>
              <span class="pln"> data </span>
              <span class="pun">=</span>
              <span class="pln">
              </span>
              <span class="kwd">new</span>
              <span class="pln">
              </span>
              <span class="typ">DataObject</span>
              <span class="pun">();</span>
              <span class="pln">
                <br />
        data</span>
              <span class="pun">.</span>
              <span class="typ">SetData</span>
              <span class="pun">(</span>
              <span class="typ">DataFormats</span>
              <span class="pun">.</span>
              <span class="typ">Bitmap</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="kwd">true</span>
              <span class="pun">,</span>
              <span class="pln"> opaque</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        data</span>
              <span class="pun">.</span>
              <span class="typ">SetData</span>
              <span class="pun">(</span>
              <span class="str">"PNG"</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="kwd">true</span>
              <span class="pun">,</span>
              <span class="pln"> stream</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
        </span>
              <span class="typ">Clipboard</span>
              <span class="pun">.</span>
              <span class="typ">SetDataObject</span>
              <span class="pun">(</span>
              <span class="pln">data</span>
              <span class="pun">,</span>
              <span class="pln">
              </span>
              <span class="kwd">true</span>
              <span class="pun">);</span>
              <span class="pln">
                <br />
    </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
              <span class="pun">}</span>
              <span class="pln">
                <br />
              </span>
            </code>
          </pre>
        </div>
        <p>
The results are fairly decent. Here are a few of the applications I tried:
</p>
        <ul>
          <li>
GIMP: transparency supported</li>
          <li>
Fireworks: transparency supported</li>
          <li>
PhotoScape: white background</li>
          <li>
Paint.NET: white background<br /></li>
          <li>
MS PowerPoint: transparency supported</li>
          <li>
MS Word: white background</li>
          <li>
MS Paint: white background</li>
        </ul>
        <p>
Happy coding!
</p>
        <p>
          <a href="content/attachments/Noc.Demo.Clipboard.zip">
            <br />
          </a>
        </p>
        <p>
          <a href="content/attachments/Noc.Demo.Clipboard.zip">Noc.Demo.Clipboard.zip (163.36
KB)</a>
        </p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=9477983d-2c67-4143-8fa8-2cc480d05c98" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Benchmarks for Appending to the WinForms Text Box</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2010/08/07/BenchmarksForAppendingToTheWinFormsTextBox.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,456589d1-8134-4d94-b964-989a86ab8ab8.aspx</id>
    <published>2010-08-07T13:03:14.891-06:00</published>
    <updated>2010-08-07T13:03:33.5987136-06:00</updated>
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <category term="Windows Forms" label="Windows Forms" scheme="http://www.notesoncode.com/articles/CategoryView,category,WindowsForms.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I ran two different benchmark tests to demonstrate different approaches for updating
a WinForms TextBox. I built a simple form a rich text box. On separate runs, I filled
the text box with text as shown below:
</p>
        <p>
// The += approach:
</p>
        <pre class="prettyprint">
          <code>
            <span class="pln">richTextBox1</span>
            <span class="pun">.</span>
            <span class="typ">Text</span>
            <span class="pln">
            </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="kwd">string</span>
            <span class="pun">.</span>
            <span class="typ">Empty</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">for</span>
            <span class="pln">
            </span>
            <span class="pun">(</span>
            <span class="kwd">int</span>
            <span class="pln"> i </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="lit">0</span>
            <span class="pun">;</span>
            <span class="pln"> i </span>
            <span class="pun">&lt;</span>
            <span class="pln">
            </span>
            <span class="lit">1000</span>
            <span class="pun">;</span>
            <span class="pln"> i</span>
            <span class="pun">++)</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">{</span>
            <span class="pln">
              <br />
    richTextBox1</span>
            <span class="pun">.</span>
            <span class="typ">Text</span>
            <span class="pln">
            </span>
            <span class="pun">+=</span>
            <span class="pln">
            </span>
            <span class="str">"Hello,
World!\r\n"</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">}</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
// The StringBuilder approach:
</p>
        <pre class="prettyprint">
          <code>
            <span class="pln">richTextBox2</span>
            <span class="pun">.</span>
            <span class="typ">Text</span>
            <span class="pln">
            </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="kwd">string</span>
            <span class="pun">.</span>
            <span class="typ">Empty</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">var</span>
            <span class="pln"> builder </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="kwd">new</span>
            <span class="pln">
            </span>
            <span class="typ">StringBuilder</span>
            <span class="pun">();</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">for</span>
            <span class="pln">
            </span>
            <span class="pun">(</span>
            <span class="kwd">int</span>
            <span class="pln"> i </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="lit">0</span>
            <span class="pun">;</span>
            <span class="pln"> i </span>
            <span class="pun">&lt;</span>
            <span class="pln">
            </span>
            <span class="lit">1000</span>
            <span class="pun">;</span>
            <span class="pln"> i</span>
            <span class="pun">++)</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">{</span>
            <span class="pln">
              <br />
    builder</span>
            <span class="pun">.</span>
            <span class="typ">AppendLine</span>
            <span class="pun">(</span>
            <span class="str">"Hello,
World!\r\n"</span>
            <span class="pun">);</span>
            <span class="pln">
              <br />
    richTextBox2</span>
            <span class="pun">.</span>
            <span class="typ">Text</span>
            <span class="pln">
            </span>
            <span class="pun">=</span>
            <span class="pln"> builder</span>
            <span class="pun">.</span>
            <span class="typ">ToString</span>
            <span class="pun">();</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">}</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
The AppendText() approach
</p>
        <pre class="prettyprint">
          <code>
            <span class="pln">richTextBox3</span>
            <span class="pun">.</span>
            <span class="typ">Text</span>
            <span class="pln">
            </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="kwd">string</span>
            <span class="pun">.</span>
            <span class="typ">Empty</span>
            <span class="pun">;</span>
            <span class="pln">
              <br />
            </span>
            <span class="kwd">for</span>
            <span class="pln">
            </span>
            <span class="pun">(</span>
            <span class="kwd">int</span>
            <span class="pln"> i </span>
            <span class="pun">=</span>
            <span class="pln">
            </span>
            <span class="lit">0</span>
            <span class="pun">;</span>
            <span class="pln"> i </span>
            <span class="pun">&lt;</span>
            <span class="pln">
            </span>
            <span class="lit">1000</span>
            <span class="pun">;</span>
            <span class="pln"> i</span>
            <span class="pun">++)</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">{</span>
            <span class="pln">
              <br />
    richTextBox3</span>
            <span class="pun">.</span>
            <span class="typ">AppendText</span>
            <span class="pun">(</span>
            <span class="str">"Hello,
World!"</span>
            <span class="pun">);</span>
            <span class="pln">
              <br />
            </span>
            <span class="pun">}</span>
            <span class="pln">
              <br />
            </span>
          </code>
        </pre>
        <p>
And the results on my old machine?
</p>
        <ul>
          <li>
+= Approach: 10.7470703 seconds.</li>
          <li>
StringBuilder: 10.7353515 seconds.</li>
          <li>
AppendText(): 0.7041015 seconds.</li>
        </ul>
        <p>
I ran another benchmark. I filled a text box with 10MB of dummy text, then used the
three approaches to append "Hello, World!" to the text box.
</p>
        <p>
And the results of this?
</p>
        <ul>
          <li>
+= Approach: 11.7470703 seconds.</li>
          <li>
StringBuilder: 12.0615235 seconds.</li>
          <li>
AppendText(): 0.1142578 seconds.</li>
        </ul>
        <p>
Conclusion: It is much faster to append to a text box using AppendText() than to assign
text using string concatenation or from an intermediate data store such as s StringBuilder.
Also note that the update rate drops substantially (9 per second) when the text box
contained 10MB of text. Depending on the circumstances, a form designer might use
multi-threading and caching (via StringBuilder) of text in chunks to reduce the frequency
of updates required in the text box.
</p>
        <p>
Note that the .NET text box is a wrapper of the Win32 text box which doesn't use immutable
strings, thus giving it this edge in appending performance.
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=456589d1-8134-4d94-b964-989a86ab8ab8" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Handling Long SharePoint URLs in the Quick Launch</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2010/07/28/HandlingLongSharePointURLsInTheQuickLaunch.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,3421abad-dcbd-4c68-bb0c-19afc79b17f1.aspx</id>
    <published>2010-07-28T10:36:12.092-06:00</published>
    <updated>2010-07-28T10:39:33.0214096-06:00</updated>
    <category term="SharePoint" label="SharePoint" scheme="http://www.notesoncode.com/articles/CategoryView,category,SharePoint.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Sometimes it happens that SharePoint provides exceptionally long addresses for pages.
If it also happens to be that when adding such a long hyperlink to the Quick Launch,
that the link will exceed the 255 character limit to addresses in the Quick Launch.
This post addresses strategies to shorten long SharePoint URLs into something a little
more manageable.
</p>
        <p>
Take, for example, a typical link to the <span style="font-family: courier new,courier;">NewForm.aspx </span>file
we get when clicking New Item on a list or document library (shown on multiple lines
for convenience):
</p>
        <p style="padding-left: 30px;">
          <span style="font-family: courier new,courier;">http://share.demo.com/sites/ExampleSPSiteDemo/Lists/Document%20LibExamples/NewForm.aspx?RootFolder=%2Fsites%2FExampleSPSiteDemo%2FLists%2FDocument%20LibExamples&amp;Source=http%3A%2F%2Fshare%2Edemo%2Ecom%2Fsites%2FExampleSPSiteDemo%2FLists%2FDocument%2520LibExamples%2FAllItems%2Easpx</span>
        </p>
        <p>
This obscenely long URL winds up getting truncated when typed or pasted into the quick
launch, turning out like:
</p>
        <p style="padding-left: 30px;">
          <span style="font-family: courier new,courier;">http://share.demo.com/sites/ExampleSPSiteDemo/Lists/Document%20LibExamples/NewForm.aspx?RootFolder=%2Fsites%2FExampleSPSiteDemo%2FLists%2FDocument%20LibExamples&amp;Source=http%3A%2F%2Fshare%2Edemo%2Ecom%2Fsites%2FExampleSPSiteDemo%2FLists%2FDocument%2520LibE</span>
        </p>
        <p>
Oftentimes, an adequate solution is to trim the unwanted muck from the address. Here
are some ideas:
</p>
        <ol>
          <li>
Remove the protocol (<span style="font-family: courier new,courier;">http://</span>)
and host name (<span style="font-family: courier new,courier;">share.demo.com</span>)
from the URL. The result is an address that starts with a slash (/) and, as a side
benefit, improves your administrator's ability to do some maintenance tasks. 
<ul><li>
In this case, removing the protocol and host saves us 21 characters, which is enough
to solve the problem at hand, but might be inadequate to completely solve the problem
with exceptionally long addresses.</li></ul></li>
          <li>
Remove unwanted query string values. The query string is everything after the question
mark (?). Query strings are usually formatted like <span style="font-family: courier new,courier;">?key1=value1&amp;key2=value2&amp;key3=value3&amp;</span>...,
where each of the values might appear to be gibberish. In the case of the address
above, there are two keys: RootFolder, and Source. 
<ul><li><span style="font-family: courier new,courier;">RootFolder </span>determines which
folder will receive the new item. If your list does not use folders, feel free to
strip out everything from the word RootFolder to the next ampersand (&amp;).</li><li><span style="font-family: courier new,courier;">Source </span>determines where the
browser should go after the item is inserted. The default source is the default view
of the list or library. If redirecting to the default view is not inappropriate, strip
out the Source key and value.</li><li>
If you strip out all the keys and values, you can delete the question mark as well.</li></ul></li>
        </ol>
        <p>
Supposing you do all the suggested reductions, the URL now looks like this:
</p>
        <p style="padding-left: 30px;">
          <span style="font-family: courier new,courier;">/sites/ExampleSPSiteDemo/Lists/Document%20LibExamples/NewForm.aspx</span>
        </p>
        <p>
...Which is well under the 255 character Quick Launch limit, and is easier for a real
human to digest, anyway.
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=3421abad-dcbd-4c68-bb0c-19afc79b17f1" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Powerful Extension Methods - Part 3</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2009/03/03/PowerfulExtensionMethodsPart3.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,7d1ed8b6-7719-4630-ab58-849708ed6e56.aspx</id>
    <published>2009-03-03T06:16:19.747-07:00</published>
    <updated>2009-03-03T19:41:24.3765344-07:00</updated>
    <category term="ASP.NET" label="ASP.NET" scheme="http://www.notesoncode.com/articles/CategoryView,category,ASPNET.aspx" />
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <category term="Extension Methods" label="Extension Methods" scheme="http://www.notesoncode.com/articles/CategoryView,category,ExtensionMethods.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Welcome to part 3 in the Powerful Extension Methods series. This article takes a look
at a common class in ASP.NET, the <code>System.Web.UI.WebControls.ListItemCollection</code>.
The <code>ListItemCollection</code> is used in many places: the <code>ListBox</code>, <code>DropDownList</code>, <code>CheckBoxList</code>,
and <code>RadioButtonList</code> all store their items in this type of collection.
</p>
        <p>
          <code>ListItemCollection</code> implements <code>IEnumerable</code>, but not the strongly
typed <code>IEnumerable&lt;ListItem&gt;</code>. Many collections throughout the base
class libraries are that way. One of the disadvantages of implementing only <code>IEnumerable</code> is
that when you want to process the collection using LINQ, you must first cast the collection
to the desired type. Something like this:
</p>
        <pre class="code">items<span class="hl sym">.</span>Cast<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;() </span></pre>
        <p>
The <code>Cast&lt;TResult&gt;()</code> function gets called implicitly in LINQ expressions
such as this:
</p>
        <pre class="code">
          <span class="hl kwa">var</span> selectedItems <span class="hl sym">=</span><span class="hl kwa">from</span> ListItem
item <span class="hl kwa">in</span> items <span class="hl kwa">where</span> item<span class="hl sym">.</span>Selected <span class="hl kwa">select</span> item<span class="hl sym">;</span></pre>
        <p>
The query feels slightly less elegant when written using the LINQ methods directly.
</p>
        <pre class="code">
          <span class="hl kwa">var</span> selectedItems <span class="hl sym">=</span> items<span class="hl sym">.</span>Cast<span class="hl sym">&lt;</span>TResult<span class="hl sym">&gt;().</span>Where<span class="hl sym">(</span>item <span class="hl sym">=&gt;</span> item<span class="hl sym">.</span>Selected<span class="hl sym">);</span></pre>
        <p>
Adding a quick extension method like the one below allows calls to the <code>Where&lt;TResult&gt;()</code> method
without including the inelegant call to <code>Cast&lt;TResult&gt;()</code>.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
Filters a &lt;c&gt;ListItemCollection&lt;/c&gt; based on a predicate.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl slc">/// &lt;param name="items"&gt;The &lt;c&gt;ListItemCollection&lt;/c&gt;
to filter.&lt;/param&gt;</span>
          <span class="hl slc">/// &lt;param name="predicate"&gt;A
function to test each element for a condition.&lt;/param&gt;</span>
          <span class="hl slc">///
&lt;returns&gt;An enumerable set of list items filtered by the predicate.&lt;/returns&gt;</span>
          <span class="hl kwa">public
static</span> IEnumerable<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;</span><span class="hl kwd">Where</span><span class="hl sym">(</span><span class="hl kwa">this</span> ListItemCollection
items<span class="hl sym">,</span> Func<span class="hl sym">&lt;</span>ListItem<span class="hl sym">,</span><span class="hl kwb">bool</span><span class="hl sym">&gt;</span> predicate<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">return</span> items<span class="hl sym">.</span>Cast<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;().</span><span class="hl kwd">Where</span><span class="hl sym">(</span>predicate<span class="hl sym">);</span><span class="hl sym">}</span></pre>
        <p>
This allows the simpler call:
</p>
        <pre class="code">
          <span class="hl kwa">var</span> selectedItems <span class="hl sym">=</span> items<span class="hl sym">.</span>Where<span class="hl sym">(</span>item <span class="hl sym">=&gt;</span> item<span class="hl sym">.</span>Selected<span class="hl sym">);</span></pre>
        <p>
The ASP.NET <code>ListItemCollection</code> does not ship with a <code>SelectedItems</code> or <code>SelectedIndices</code> property.
We can elegantly compensate for the missing property with two short extension methods.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
Filters a &lt;c&gt;ListItemCollection&lt;/c&gt; based on whether the item is selected.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl slc">/// &lt;param name="items"&gt;The &lt;c&gt;ListItemCollection&lt;/c&gt;
to filter.&lt;/param&gt;</span>
          <span class="hl slc">/// &lt;returns&gt;An enumerable
set of list items filtered by whether the item is selected.&lt;/returns&gt;</span>
          <span class="hl kwa">public
static</span> IEnumerable<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;</span><span class="hl kwd">WhereSelected</span><span class="hl sym">(</span><span class="hl kwa">this</span> ListItemCollection
items<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">return</span> items<span class="hl sym">.</span>Cast<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;().</span><span class="hl kwd">Where</span><span class="hl sym">(</span>i <span class="hl sym">=&gt;</span> i<span class="hl sym">.</span>Selected<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// Filters a &lt;c&gt;ListItemCollection&lt;/c&gt;
based on whether the item is not selected.</span><span class="hl slc">/// &lt;/summary&gt;</span><span class="hl slc">///
&lt;param name="items"&gt;The &lt;c&gt;ListItemCollection&lt;/c&gt; to filter.&lt;/param&gt;</span><span class="hl slc">///
&lt;returns&gt;An enumerable set of list items filtered by whether the item is not
selected.&lt;/returns&gt;</span><span class="hl kwa">public static</span> IEnumerable<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;</span><span class="hl kwd">WhereNotSelected</span><span class="hl sym">(</span><span class="hl kwa">this</span> ListItemCollection
items<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">return</span> items<span class="hl sym">.</span>Cast<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;().</span><span class="hl kwd">Where</span><span class="hl sym">(</span>i <span class="hl sym">=&gt;
!</span>i<span class="hl sym">.</span>Selected<span class="hl sym">);</span><span class="hl sym">}</span></pre>
        <p>
Often times, it is not the list items themselves that we are interested in, but only
their values. A few brief extension methods make for an elegant way to retrieve <code>SelectedValues</code>.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
Filters a &lt;c&gt;ListItemCollection&lt;/c&gt; based on whether the item is selected,
and retrieves each</span>
          <span class="hl slc">value.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl slc">/// &lt;param name="items"&gt;The &lt;c&gt;ListItemCollection&lt;/c&gt;
to filter.&lt;/param&gt;</span>
          <span class="hl slc">/// &lt;returns&gt;An enumerable
set of list items filtered by whether the item is selected.&lt;/returns&gt;</span>
          <span class="hl kwa">public
static</span> IEnumerable<span class="hl sym">&lt;</span><span class="hl kwb">string</span><span class="hl sym">&gt;</span><span class="hl kwd">ValuesWhereSelected</span><span class="hl sym">(</span><span class="hl kwa">this</span> ListItemCollection
items<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">return</span> items<span class="hl sym">.</span>Cast<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;().</span><span class="hl kwd">Where</span><span class="hl sym">(</span>i <span class="hl sym">=&gt;</span> i<span class="hl sym">.</span>Selected<span class="hl sym">).</span><span class="hl kwd">Select</span><span class="hl sym">(</span>i <span class="hl sym">=&gt;</span> i<span class="hl sym">.</span>Value<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// Filters a &lt;c&gt;ListItemCollection&lt;/c&gt;
based on whether the item is not selected, and retrieves</span><span class="hl slc">each
value.</span><span class="hl slc">/// &lt;/summary&gt;</span><span class="hl slc">///
&lt;param name="items"&gt;The &lt;c&gt;ListItemCollection&lt;/c&gt; to filter.&lt;/param&gt;</span><span class="hl slc">///
&lt;returns&gt;An enumerable set of list items filtered by whether the item is not
selected.&lt;/returns&gt;</span><span class="hl kwa">public static</span> IEnumerable<span class="hl sym">&lt;</span><span class="hl kwb">string</span><span class="hl sym">&gt;</span><span class="hl kwd">ValuesWhereNotSelected</span><span class="hl sym">(</span><span class="hl kwa">this</span> ListItemCollection
items<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">return</span> items<span class="hl sym">.</span>Cast<span class="hl sym">&lt;</span>ListItem<span class="hl sym">&gt;().</span><span class="hl kwd">Where</span><span class="hl sym">(</span>i <span class="hl sym">=&gt;
!</span>i<span class="hl sym">.</span>Selected<span class="hl sym">).</span><span class="hl kwd">Select</span><span class="hl sym">(</span>i <span class="hl sym">=&gt;</span> i<span class="hl sym">.</span>Value<span class="hl sym">);</span><span class="hl sym">}</span></pre>
        <p>
Collecting selected values is helpful, but setting selected values is also helpful.
The next two extension methods enable selecting multiple items provided a list of
values or a Lambda expression predicate.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
Sets each element in the collection as selected based on whether the item is contained
in the</span>
          <span class="hl slc">set of values.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl slc">/// &lt;param name="items"&gt;The items
to update.&lt;/param&gt;</span>
          <span class="hl slc">/// &lt;param name="values"&gt;The
values to select. All other items will be deselected.&lt;/param&gt;</span>
          <span class="hl kwa">public
static</span>
          <span class="hl kwb">void</span>
          <span class="hl kwd">SetAllSelectedByValue</span>
          <span class="hl sym">(</span>
          <span class="hl kwa">this</span> ListItemCollection
items<span class="hl sym">,</span> IEnumerable<span class="hl sym">&lt;</span><span class="hl kwb">string</span><span class="hl sym">&gt;</span> values<span class="hl sym">)</span><span class="hl sym">{</span> var
hashValues <span class="hl sym">=</span><span class="hl kwa">new</span> HashSet<span class="hl sym">&lt;</span><span class="hl kwb">string</span><span class="hl sym">&gt;(</span>values<span class="hl sym">);</span><span class="hl kwa">if</span><span class="hl sym">(</span>values <span class="hl sym">==</span><span class="hl kwa">null</span><span class="hl sym">)</span><span class="hl sym">{</span> items<span class="hl sym">.</span><span class="hl kwd">SetAllSelectedIf</span><span class="hl sym">(</span>i <span class="hl sym">=&gt;</span><span class="hl kwa">false</span><span class="hl sym">);</span><span class="hl sym">}</span><span class="hl kwa">else</span><span class="hl sym">{</span> items<span class="hl sym">.</span><span class="hl kwd">SetAllSelectedIf</span><span class="hl sym">(</span>i <span class="hl sym">=&gt;</span> hashValues<span class="hl sym">.</span><span class="hl kwd">Contains</span><span class="hl sym">(</span>i<span class="hl sym">.</span>Value<span class="hl sym">));</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// Sets each element in the collection
as selected based on a predicate.</span><span class="hl slc">/// &lt;/summary&gt;</span><span class="hl slc">///
&lt;param name="items"&gt;The items to update.&lt;/param&gt;</span><span class="hl slc">///
&lt;param name="predicate"&gt;A function to test each element for a condition, and
update the selected</span><span class="hl slc"> status of the element to the test
result.&lt;/param&gt;</span><span class="hl kwa">public static</span><span class="hl kwb">void</span><span class="hl kwd">SetAllSelectedIf</span><span class="hl sym">(</span><span class="hl kwa">this</span> ListItemCollection
items<span class="hl sym">,</span> Func<span class="hl sym">&lt;</span>ListItem<span class="hl sym">,</span><span class="hl kwb">bool</span><span class="hl sym">&gt;</span> predicate<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">foreach</span><span class="hl sym">(</span>ListItem
item in items<span class="hl sym">)</span><span class="hl sym">{</span> item<span class="hl sym">.</span>Selected <span class="hl sym">=</span><span class="hl kwd">predicate</span><span class="hl sym">(</span>item<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span></pre>
        <p>
These few extension methods don't perform any earth-shaking operations, but they do
provide a clean, elegant way to operate on <code>ListItemCollection</code> objects.
</p>
        <p>
Happy Coding!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=7d1ed8b6-7719-4630-ab58-849708ed6e56" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Powerful Extension Methods - Part 2</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2009/01/27/PowerfulExtensionMethodsPart2.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,2a39a88f-ea06-4757-a26f-e220790e4232.aspx</id>
    <published>2009-01-26T17:47:32.601-07:00</published>
    <updated>2009-01-26T17:47:46.7019536-07:00</updated>
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <category term="Extension Methods" label="Extension Methods" scheme="http://www.notesoncode.com/articles/CategoryView,category,ExtensionMethods.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Welcome to part 2 of the Powerful Extension Methods series. Today, we take a look
at XML serialization. If you have ever used the .NET XmlSerializer class, you know
how powerful it is. Decorate your class with appropriate attributes, and you can generate
or parse complex XML structures without having to write any XML parsing code.
</p>
        <p>
To find out more about .NET and XML serialization, check out the documentation <a title="MSDN Documentation" href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx" target="_blank">here</a>.
If you want to see excellent examples of the XmlSerializer in action, check out the
code of <a title="Das Blog" href="http://www.dasblog.info/" target="_blank">DasBlog</a> and
look at what they do with RSS and Atom feeds. It's pretty neat.
</p>
        <p>
It doesn't take long, working with the XmlSerializer, before the good ol' <acronym title="Don't Repeat Yourself">DRY</acronym> principle
drives us to create serialization helper classes, like <a title="Andrew Gunn's Blog" href="http://andrewgunn.blogspot.com/2008/06/xml-serialization-in-cnet.html" target="_blank">Andrew
Gunn</a> created. Utility classes are usually <em>perfect</em> candidates for extension
methods.
</p>
        <p>
So here we go: one extension method for serializing any object (if it is not serializable,
expect an exception), and a generic method each for deserializing streams, strings,
and XmlNodes.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
This class provides extension methods related to serialization.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl kwa">public static class</span> SerializationExtensions <span class="hl sym">{</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// Serializes an object as XML.</span><span class="hl slc">///
&lt;/summary&gt;</span><span class="hl slc">/// &lt;param name="value"&gt;The object
to serialize.&lt;/param&gt;</span><span class="hl slc">/// &lt;returns&gt;An XML
string representing the serialized object.&lt;/returns&gt;</span><span class="hl kwa">public
static</span><span class="hl kwb">string</span><span class="hl kwd">SerializeAsXml</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl kwb">object</span> value<span class="hl sym">)</span><span class="hl sym">{</span> var
ser <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">XmlSerializer</span><span class="hl sym">(</span><span class="hl kwa">value</span><span class="hl sym">.</span><span class="hl kwd">GetType</span><span class="hl sym">());</span><span class="hl kwa">using</span><span class="hl sym">(</span>var
stream <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">MemoryStream</span><span class="hl sym">())</span><span class="hl kwa">using</span><span class="hl sym">(</span>var
xmlwriter <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">XmlTextWriter</span><span class="hl sym">(</span>stream<span class="hl sym">,</span> Encoding<span class="hl sym">.</span>UTF8<span class="hl sym">))</span><span class="hl sym">{</span> ser<span class="hl sym">.</span><span class="hl kwd">Serialize</span><span class="hl sym">(</span>xmlwriter<span class="hl sym">,</span> value<span class="hl sym">);</span> var
buffer <span class="hl sym">=</span> stream<span class="hl sym">.</span><span class="hl kwd">GetBuffer</span><span class="hl sym">();</span><span class="hl slc">//
skip the byte order mask</span><span class="hl kwa">return</span> Encoding<span class="hl sym">.</span>UTF8<span class="hl sym">.</span><span class="hl kwd">GetString</span><span class="hl sym">(</span>buffer<span class="hl sym">,</span><span class="hl num">3</span><span class="hl sym">,</span> buffer<span class="hl sym">.</span>Length <span class="hl sym">-</span><span class="hl num">3</span><span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// Deserializes the specified string
using an XML serializer.</span><span class="hl slc">/// &lt;/summary&gt;</span><span class="hl slc">///
&lt;typeparam name="T"&gt;The type of object to deserialize.&lt;/typeparam&gt;</span><span class="hl slc">///
&lt;param name="stream"&gt;The stream to deserialize.&lt;/param&gt;</span><span class="hl slc">///
&lt;returns&gt;A deserialized object of the specified type.&lt;/returns&gt;</span><span class="hl kwa">public
static</span> T Deserialize<span class="hl sym">&lt;</span>T<span class="hl sym">&gt;(</span><span class="hl kwa">this</span> Stream
stream<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">using</span><span class="hl sym">(</span>var
reader <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">XmlTextReader</span><span class="hl sym">(</span>reader<span class="hl sym">))</span><span class="hl sym">{</span> var
ser <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">XmlSerializer</span><span class="hl sym">(</span><span class="hl kwd">typeof</span><span class="hl sym">(</span>T<span class="hl sym">));</span><span class="hl kwa">return</span><span class="hl sym">(</span>T<span class="hl sym">)</span>ser<span class="hl sym">.</span><span class="hl kwd">Deserialize</span><span class="hl sym">(</span>reader<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// Deserializes the specified string
using an XML serializer.</span><span class="hl slc">/// &lt;/summary&gt;</span><span class="hl slc">///
&lt;typeparam name="T"&gt;The type of object to deserialize.&lt;/typeparam&gt;</span><span class="hl slc">///
&lt;param name="xml"&gt;The XML to deserialize.&lt;/param&gt;</span><span class="hl slc">///
&lt;returns&gt;A deserialized object of the specified type.&lt;/returns&gt;</span><span class="hl kwa">public
static</span> T Deserialize<span class="hl sym">&lt;</span>T<span class="hl sym">&gt;(</span><span class="hl kwa">this</span><span class="hl kwb">string</span> xml<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">using</span><span class="hl sym">(</span>var
reader <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">StringReader</span><span class="hl sym">(</span>xml<span class="hl sym">))</span><span class="hl sym">{</span> var
ser <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">XmlSerializer</span><span class="hl sym">(</span><span class="hl kwd">typeof</span><span class="hl sym">(</span>T<span class="hl sym">));</span><span class="hl kwa">return</span><span class="hl sym">(</span>T<span class="hl sym">)</span>ser<span class="hl sym">.</span><span class="hl kwd">Deserialize</span><span class="hl sym">(</span>reader<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// Deserializes the specified node using
an XML serializer.</span><span class="hl slc">/// &lt;/summary&gt;</span><span class="hl slc">///
&lt;typeparam name="T"&gt;The type of object to deserialize.&lt;/typeparam&gt;</span><span class="hl slc">///
&lt;param name="node"&gt;The node containing XML to deserialize.&lt;/param&gt;</span><span class="hl slc">///
&lt;returns&gt;A deserialized object of the specified type.&lt;/returns&gt;</span><span class="hl kwa">public
static</span> T Deserialize<span class="hl sym">&lt;</span>T<span class="hl sym">&gt;(</span><span class="hl kwa">this</span> XmlNode
node<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">using</span><span class="hl sym">(</span>var
reader <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">StringReader</span><span class="hl sym">(</span>node<span class="hl sym">.</span>OuterXml<span class="hl sym">))</span><span class="hl sym">{</span> var
ser <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">XmlSerializer</span><span class="hl sym">(</span><span class="hl kwd">typeof</span><span class="hl sym">(</span>T<span class="hl sym">));</span><span class="hl kwa">return</span><span class="hl sym">(</span>T<span class="hl sym">)</span>ser<span class="hl sym">.</span><span class="hl kwd">Deserialize</span><span class="hl sym">(</span>reader<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl sym">}</span></pre>
        <p>
Happy Coding!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=2a39a88f-ea06-4757-a26f-e220790e4232" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Powerful Extension Methods - Part 1</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2009/01/24/PowerfulExtensionMethodsPart1.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,1cd7b5f5-8bb1-41ae-8f9e-1219c9b0f072.aspx</id>
    <published>2009-01-24T08:27:50.85-07:00</published>
    <updated>2009-01-24T08:30:32.6334368-07:00</updated>
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <category term="Extension Methods" label="Extension Methods" scheme="http://www.notesoncode.com/articles/CategoryView,category,ExtensionMethods.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Welcome to part 1 of the Powerful Extension Methods series. The extension method concept
is an excellent feature of the latest breeds of the .NET framework. They allow us
to abstract away static utility classes in a way that makes the utility methods appear
to belong to the object they operate upon. Beginners can check things out <a title="MSDN Documentation" href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" target="_blank">here</a> and <a title="Scott Gu's Introduction to Extension Methods" href="http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx" target="_blank">here</a> for
a good introduction.
</p>
        <p>
I do WinForms programming from time to time. In any Windows application, whether through
traditional WinForms or through WPF, managing event handling in the face of threading
is critical. Exceptions are thrown when code updates any UI Control property from
any thread <em>except</em> the thread that created the control. This problem surfaces
when some background thread needs to update the UI.
</p>
        <p>
This led to a lot of creative solutions involving InvokeRequired and Invoke. One solution
involves creating an event on the threaded object which the UI can subscribe to. The
On<em>MyEvent</em> method of the object handles invoking each event handler methods
on the thread from which they subscribed. The full idea is described <a title="CodeProject article" href="http://www.codeproject.com/KB/threads/invoke_other_way.aspx" target="_blank">here</a>.
</p>
        <p>
It only took me an event handler or two before the <acronym title="Don't Repeat Yourself">DRY</acronym> principle
screamed for attention. Enter, the <span class="code">SafeInvoke</span> extension
method:
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
Raises the event asynchronously.</span>
          <span class="hl slc">/// &lt;/summary&gt;</span>
          <span class="hl slc">///
&lt;param name="handler"&gt;The handler.&lt;/param&gt;</span>
          <span class="hl slc">///
&lt;param name="source"&gt;The source.&lt;/param&gt;</span>
          <span class="hl slc">///
&lt;param name="args"&gt;The &lt;see cref="System.EventArgs"/&gt; instance containing
the event data.&lt;</span>
          <span class="hl slc">/param&gt;</span>
          <span class="hl kwa">public
static</span>
          <span class="hl kwb">void</span>
          <span class="hl kwd">SafeInvoke</span>
          <span class="hl sym">(</span>
          <span class="hl kwa">this</span> EventHandler
handler<span class="hl sym">,</span><span class="hl kwb">object</span> source<span class="hl sym">,</span> EventArgs
args<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">if</span><span class="hl sym">(</span>handler <span class="hl sym">!=</span><span class="hl kwa">null</span><span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">foreach</span><span class="hl sym">(</span>EventHandler
singleCast in handler<span class="hl sym">.</span><span class="hl kwd">GetInvocationList</span><span class="hl sym">())</span><span class="hl sym">{</span> var
syncInvoke <span class="hl sym">=</span> singleCast<span class="hl sym">.</span>Target
as ISynchronizeInvoke<span class="hl sym">;</span><span class="hl kwa">try</span><span class="hl sym">{</span><span class="hl kwa">if</span><span class="hl sym">(</span>syncInvoke <span class="hl sym">!=</span><span class="hl kwa">null</span><span class="hl sym">&amp;&amp;</span> syncInvoke<span class="hl sym">.</span>InvokeRequired<span class="hl sym">)</span><span class="hl sym">{</span> syncInvoke<span class="hl sym">.</span><span class="hl kwd">Invoke</span><span class="hl sym">(</span>singleCast<span class="hl sym">,</span><span class="hl kwa">new</span><span class="hl kwb">object</span><span class="hl sym">[]
{</span> source<span class="hl sym">,</span> args <span class="hl sym">});</span><span class="hl sym">}</span><span class="hl kwa">else</span><span class="hl sym">{</span><span class="hl kwd">singleCast</span><span class="hl sym">(</span>source<span class="hl sym">,</span> args<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl kwa">catch</span><span class="hl sym">{</span><span class="hl slc">//
Do nothing. The event handler may have been detached asynchronously.</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl sym">}</span></pre>
        <p>
With this extension method, we can construct our threaded object to look something
like this:
</p>
        <pre class="code">
          <span class="hl kwa">public class</span> MyWorker <span class="hl sym">{</span><span class="hl kwa">public
event</span> EventHandler SomeEvent<span class="hl sym">;</span><span class="hl kwa">protected
virtual</span><span class="hl kwb">void</span><span class="hl kwd">OnSomeEvent</span><span class="hl sym">(</span>EventArgs
e<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">this</span><span class="hl sym">.</span>SomeEvent<span class="hl sym">.</span><span class="hl kwd">SafeInvoke</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">,</span> e<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span></pre>
        <p>
You can see that using this pattern, the event will manage on its own the process
of ensuring the event is handled on the subscribing threads. No more threading exceptions
when updating the UI from a background worker!
</p>
        <p>
Another common event delegate that deserves a similar extension method is the generic <span class="code">EventHandler&lt;T&gt;</span> class.
The model of the function is no surprise; but, here it is in full.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
Raises the event asynchronously.</span>
          <span class="hl slc">/// &lt;/summary&gt;</span>
          <span class="hl slc">///
&lt;typeparam name="T"&gt;The type of the event handler arguments&lt;/typeparam&gt;</span>
          <span class="hl slc">///
&lt;param name="handler"&gt;The handler.&lt;/param&gt;</span>
          <span class="hl slc">///
&lt;param name="source"&gt;The source.&lt;/param&gt;</span>
          <span class="hl slc">///
&lt;param name="args"&gt;The arguments containing the event data.&lt;/param&gt;</span>
          <span class="hl kwa">public
static</span>
          <span class="hl kwb">void</span> SafeInvoke<span class="hl sym">&lt;</span>T<span class="hl sym">&gt;(</span><span class="hl kwa">this</span> EventHandler<span class="hl sym">&lt;</span>T<span class="hl sym">&gt;</span> handler<span class="hl sym">,</span><span class="hl kwb">object</span> source<span class="hl sym">,</span> T
args<span class="hl sym">)</span><br />
where T <span class="hl sym">:</span> EventArgs <span class="hl sym">{</span><span class="hl kwa">if</span><span class="hl sym">(</span>handler <span class="hl sym">!=</span><span class="hl kwa">null</span><span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">foreach</span><span class="hl sym">(</span>EventHandler<span class="hl sym">&lt;</span>T<span class="hl sym">&gt;</span> singleCast
in handler<span class="hl sym">.</span><span class="hl kwd">GetInvocationList</span><span class="hl sym">())</span><span class="hl sym">{</span> var
syncInvoke <span class="hl sym">=</span> singleCast<span class="hl sym">.</span>Target
as ISynchronizeInvoke<span class="hl sym">;</span><span class="hl kwa">try</span><span class="hl sym">{</span><span class="hl kwa">if</span><span class="hl sym">(</span>syncInvoke <span class="hl sym">!=</span><span class="hl kwa">null</span><span class="hl sym">&amp;&amp;</span> syncInvoke<span class="hl sym">.</span>InvokeRequired<span class="hl sym">)</span><span class="hl sym">{</span> syncInvoke<span class="hl sym">.</span><span class="hl kwd">Invoke</span><span class="hl sym">(</span>singleCast<span class="hl sym">,</span><span class="hl kwa">new</span><span class="hl kwb">object</span><span class="hl sym">[]
{</span> source<span class="hl sym">,</span> args <span class="hl sym">});</span><span class="hl sym">}</span><span class="hl kwa">else</span><span class="hl sym">{</span><span class="hl kwd">singleCast</span><span class="hl sym">(</span>source<span class="hl sym">,</span> args<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl kwa">catch</span><span class="hl sym">{</span><span class="hl slc">//
Do nothing. The event handler may have been detached asynchronously.</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl sym">}</span></pre>
        <p>
          <em>Happy Coding!</em>
        </p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=1cd7b5f5-8bb1-41ae-8f9e-1219c9b0f072" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Automate your Defrag in Windows XP</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2008/08/02/AutomateYourDefragInWindowsXP.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,fdb07dde-b422-4cbd-8145-df685c38397c.aspx</id>
    <published>2008-08-01T18:30:11.561-06:00</published>
    <updated>2008-08-01T18:46:07.35564-06:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
It happens so gradually that it is possible not to even notice your computer's performance
go down the drain. That's how it happened with me. My hard drive was so filthily fragmented
that it could barely limp along.
</p>
        <p>
So a friend of mine suggested I set up a scheduled task to run the defragmenter nightly.
I did this, and my the performance smoothed out nicely. I thought I'd pass it along.
</p>
        <p>
Before doing so:
</p>
        <p style="float:left; margin: 0px 10px 10px 40px">
          <img src="content/attachments/warning.png" border="0" alt="" />
        </p>
        <p style="font-size: 14pt; color: #de5d20;">
Use at your own risk. I take zero responsibility for consequences good or bad for
using this script. It worked fine for me. I run Windows XP.
</p>
        <p style="clear:both">
That said, here's the script, implemented as a command (batch) file. You can copy
it from the page, but you'll have to massage the line breaks; or you can download
the command file: <a href="content/attachments/defrag_setup.cmd">defrag_setup.cmd
(.47 KB)</a>. The original script was targeted for a computer with a C:\ and D:\ hard
drives. I stripped the scheduled task for the second drive -- I don't have two --
but I left the bit where it computes offsets so that you don't try to defrag every
drive at once. If you can get your drive in good condition, it should always defrag
in only a few minutes; especially for a home PC that is defragmenting every single
night.
</p>
        <pre class="code">@echo off
echo <span class="hl str">""</span><span class="hl sym">-------------------------------------------------------</span> echo <span class="hl str">""</span> Script
for defraging hard drives echo <span class="hl str">""</span> Use at your own risk <span class="hl sym">:)</span> echo <span class="hl str">""</span><span class="hl sym">-------------------------------------------------------</span><span class="hl kwb">SET</span> Start_Time<span class="hl sym">=</span><span class="hl num">1</span><span class="hl kwb">SET</span> Offset_Time<span class="hl sym">=</span><span class="hl num">1</span><span class="hl kwb">SET</span> Start_Time_C<span class="hl sym">=%</span>Start_Time<span class="hl sym">%</span><span class="hl kwb">SET</span><span class="hl sym">/</span>a
Start_Time_D<span class="hl sym">=</span>Start_Time<span class="hl sym">+</span>Offset_Time
@echo on schtasks <span class="hl sym">/</span>Create <span class="hl sym">/</span>tn <span class="hl str">"Defrag
Drive C"</span><span class="hl sym">/</span>tr <span class="hl str">"C:\windows\system32\defrag.exe
C: -f -v"</span><span class="hl sym">/</span>sc daily <span class="hl sym">/</span>st <span class="hl str">"0%Start_Time_C%:00:00"</span><span class="hl sym">/</span>ru <span class="hl str">"System"</span></pre>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=fdb07dde-b422-4cbd-8145-df685c38397c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>More on Control Collections</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2008/07/31/MoreOnControlCollections.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,35099b90-0bbe-4598-8554-07a8ce56bdf3.aspx</id>
    <published>2008-07-30T21:33:06.386-06:00</published>
    <updated>2008-07-30T21:36:57.5377635-06:00</updated>
    <category term="ASP.NET" label="ASP.NET" scheme="http://www.notesoncode.com/articles/CategoryView,category,ASPNET.aspx" />
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
ASP.NET control collections are finicky. They are the most difficult to handle when
trying to modify a control collection from a scope outside of that control. The mischievous
error sneaked up on me <a href="2007/07/07/ModifyingControlCollections.aspx">some
time ago</a>. It manifests itself with the following error:
</p>
        <blockquote>"The control collection cannot be modified during DataBind, Init, Load,
PreRender or Unload phases."</blockquote>
        <p>
While fiddling around for a friend I came across some interesting behavior. Perhaps
it is best to just show the code and disclaim my ignorance.
</p>
        <p>
Suppose I have an ASP.NET 2.0 application containing two user controls implementing
an interface <code>IReadyable</code>.
</p>
        <pre class="code">
          <span class="hl kwa">public interface</span> IReadyable <span class="hl sym">{</span><span class="hl kwa">event</span> EventHandler
Ready<span class="hl sym">;</span><span class="hl sym">}</span></pre>
        <p>
Each user control contains handling code to satisfy the interface, like so:
</p>
        <pre class="code">
          <span class="hl kwa">public event</span> EventHandler Ready<span class="hl sym">;</span><span class="hl kwa">protected
override</span><span class="hl kwb">void</span><span class="hl kwd">OnLoad</span><span class="hl sym">(</span>EventArgs
e<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">OnReady</span><span class="hl sym">(</span>EventArgs<span class="hl sym">.</span>Empty<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl kwa">private</span><span class="hl kwb">void</span><span class="hl kwd">OnReady</span><span class="hl sym">(</span>EventArgs
e<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">if</span><span class="hl sym">(</span>Ready <span class="hl sym">!=</span><span class="hl kwa">null</span><span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">Ready</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">,</span> e<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span></pre>
        <p>
The idea is that we can use the <code>Ready</code> event to signal a time to swap
user controls in and out of our page. Allright, now to set up the <a href="http://en.wikipedia.org/wiki/Straw_man" target="_blank">straw
man</a>. We have a page that contains a placeholder. At some point, one of our user
controls is added to the control collection of the placeholder. When the <code>OnLoad</code> event
of the control fires, the handler activates the <code>Ready</code> event as well.
</p>
        <p>
Our application code responds to the ready event by swapping the user control for
another. This causes the peculiar exception.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
This method wires up the event handlers early in the page lifecycle,</span>
          <span class="hl slc">///
but not early enough to allow us to modify some control collections.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl kwa">protected</span>
          <span class="hl kwb">void</span>
          <span class="hl kwd">Page_Load</span>
          <span class="hl sym">(</span>
          <span class="hl kwb">object</span> sender<span class="hl sym">,</span> EventArgs
e<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa"> base</span><span class="hl sym">.</span><span class="hl kwd">OnInit</span><span class="hl sym">(</span>e<span class="hl sym">);</span> IReadyable
readyable <span class="hl sym">= (</span>IReadyable<span class="hl sym">)</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">LoadControl</span><span class="hl sym">(</span><span class="hl str">"~/MailControl01.ascx"</span><span class="hl sym">);</span> readyable<span class="hl sym">.</span>Ready <span class="hl sym">+=</span><span class="hl kwa">new</span><span class="hl kwd">EventHandler</span><span class="hl sym">(</span>readyable_Ready<span class="hl sym">);</span><span class="hl kwa">this</span><span class="hl sym">.</span>placeHolder<span class="hl sym">.</span>Controls<span class="hl sym">.</span><span class="hl kwd">Add</span><span class="hl sym">((</span>Control<span class="hl sym">)</span>readyable<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// This method does not work because
it is invoked too late in the page lifecycle.</span><span class="hl slc">/// &lt;/summary&gt;</span><span class="hl kwb">void</span><span class="hl kwd">readyable_Ready</span><span class="hl sym">(</span><span class="hl kwb">object</span> sender<span class="hl sym">,</span> EventArgs
e<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">this</span><span class="hl sym">.</span>placeHolder<span class="hl sym">.</span>Controls<span class="hl sym">.</span><span class="hl kwd">Clear</span><span class="hl sym">();</span><span class="hl slc">//
&lt;-- An exception is thrown here.</span> IReadyable readyable <span class="hl sym">=
(</span>IReadyable<span class="hl sym">)</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">LoadControl</span><span class="hl sym">(</span><span class="hl str">"~/MailControl02.ascx"</span><span class="hl sym">);</span> readyable<span class="hl sym">.</span>Ready <span class="hl sym">+=</span><span class="hl kwa">new</span><span class="hl kwd">EventHandler</span><span class="hl sym">(</span>again_Ready<span class="hl sym">);</span><span class="hl kwa">this</span><span class="hl sym">.</span>placeHolder<span class="hl sym">.</span>Controls<span class="hl sym">.</span><span class="hl kwd">Add</span><span class="hl sym">((</span>Control<span class="hl sym">)</span>readyable<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl slc">///
&lt;summary&gt;</span><span class="hl slc">/// Stub for an event handler.</span><span class="hl slc">///
&lt;/summary&gt;</span><span class="hl kwb">void</span><span class="hl kwd">again_Ready</span><span class="hl sym">(</span><span class="hl kwb">object</span> sender<span class="hl sym">,</span> EventArgs
e<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl sym">}</span></pre>
        <p>
Notice the first line in the <code>readyable_Ready</code> method?
</p>
        <p>
Now for the interesting behavior. I say interesting because the error states that
control collections are unmodifyable during the Init and Load phase; however, if you
swap <code>Page_Load</code> for an override on the page's <code>OnInit</code> method,
and swap the user control's <code>OnLoad</code> override for an <code>OnInit</code> override,
no exception occurs. Everything works just fine. I suppose there are some arcane rules
I am unaware of.
</p>
        <p>
Granted, in my day-to-day development, I avoid the entire issue by creating custom
server controls. I make each control responsible for its own control collection and
ignorant of anything outside. It seems a control can modify its own collection any
time it pleases, although there are some costs to doing it late in the page lifecycle.
I found this page from Microsoft helpful: <a href="http://msdn.microsoft.com/en-us/library/ms178472.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/ms178472.aspx</a>.
</p>
        <p>
I hope this turns out helpful for someone. A full demo is attached here: <a href="content/attachments/ControlCollections.zip">ControlCollections.zip
(6.21 KB)</a></p>
        <p>
Happy coding.
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=35099b90-0bbe-4598-8554-07a8ce56bdf3" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Migrating to dasBlog</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2008/07/26/MigratingToDasBlog.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,e261c383-dfec-4e5b-8c55-7cb34503948b.aspx</id>
    <published>2008-07-25T20:19:13.617-06:00</published>
    <updated>2008-07-25T20:31:46.5199216-06:00</updated>
    <category term="Misc" label="Misc" scheme="http://www.notesoncode.com/articles/CategoryView,category,Misc.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Well, I took the plunge. The truth is, that my home-brewed blog engine was too buggy
to be practical. I found myself spending a few hours massaging code, and then left
with no time to write. Certainly, I want nothing to do with "More Code than Content"
syndrome.
</p>
        <p>
My only regret is that permalinks are fatally broken. I suppose a tool such as <a href="http://www.isapirewrite.com/" target="_blank">ISAPI
Rewrite</a> could bail me out here; but given time constraints and so few blog entries,
I'm settling for burning the ship.
</p>
        <p>
So here goes. Comments are enabled for a number of days. If you see something that
peaks your interest, join in the conversation.
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=e261c383-dfec-4e5b-8c55-7cb34503948b" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Internet Explorer Cannot Open the Internet Site</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/11/01/InternetExplorerCannotOpenTheInternetSite.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,79804b9d-a777-4862-aa23-7426cb320014.aspx</id>
    <published>2007-10-31T19:44:01-06:00</published>
    <updated>2007-10-31T19:44:01-06:00</updated>
    <category term="Internet Explorer" label="Internet Explorer" scheme="http://www.notesoncode.com/articles/CategoryView,category,InternetExplorer.aspx" />
    <category term="JavaScript" label="JavaScript" scheme="http://www.notesoncode.com/articles/CategoryView,category,JavaScript.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I encountered an interesting IE bug/feature today worth mentioning: When running a
page, I received the error message <em>"Internet Explorer cannot open the Internet
site, Operation aborted."</em> This perplexed me largely because the page seemed
to load, and behaved very kindly in Firefox.
</p>
        <p>
The problem was a single offending line of JavaScript:
</p>
        <pre class="code">document.body.appendChild(someElement);</pre>
        <p>
This line was positioned within the body tag, so it would execute before IE finished
rendering the body. Instead of saying <em>"You cannot use script to add to the
body tag until the page is fully loaded,"</em> the browser provided the cryptic <em>"Operation
aborted"</em> message.
</p>
        <p>
I hope this helps. 
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=79804b9d-a777-4862-aa23-7426cb320014" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Achoo!</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/10/13/Achoo.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,a23faeb3-dda6-4921-983b-a952c6c525d4.aspx</id>
    <published>2007-10-13T12:58:44-06:00</published>
    <updated>2007-10-13T12:58:44-06:00</updated>
    <category term="Misc" label="Misc" scheme="http://www.notesoncode.com/articles/CategoryView,category,Misc.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today, my computer got a cold. It was a brutal virus that took some doing to fix.
My gratitute to the folks who publish great tools such as <a href="http://www.spybot.info/en/">Spybot
Search &amp; Destroy</a>, <a href="http://www.lavasoftusa.com/">AdAware</a>, and <a href="http://www.trendsecure.com/portal/en-US/tools/security_tools/hijackthis">Hijack
This</a>. These tools really saved my bacon.
</p>
        <p>
Everything seems fine now, but I do think I'll reload the OS anyway. It's nice to
feel clean, and its horrid to be unsure if it is really gone. Sigh. Well, here goes...
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=a23faeb3-dda6-4921-983b-a952c6c525d4" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Modifying Control Collections</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/07/07/ModifyingControlCollections.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,05d26fde-402e-450c-833a-68aaaee7838a.aspx</id>
    <published>2007-07-07T13:25:21.2-06:00</published>
    <updated>2007-07-31T06:40:13.56-06:00</updated>
    <category term="ASP.NET" label="ASP.NET" scheme="http://www.notesoncode.com/articles/CategoryView,category,ASPNET.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was building a new server control for <a href="http://www.atk.com/">my employer</a> when
I stumbled across this unexpected error:
</p>
        <blockquote>"The control collection cannot be modified during DataBind, Init, Load,
PreRender or Unload phases."</blockquote>
        <p>
This proved to be a misleading error. The problem occurred because I tried to modify
the <code>Control</code> collection <em>outside</em> of the new server control's own
collection. This could only be done when the <code>Parent</code> property had been
set, which is never until the <code>Init</code> cycle. Effectively, modifying a parent's
control collection is disallowed.
</p>
        <p>
The solution to my problem was ensure that all dynamically added controls were added
to the custom server control's collection only.
</p>
        <p>
Happy Coding!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=05d26fde-402e-450c-833a-68aaaee7838a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Building a Custom AJAX Control Extender</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/06/30/BuildingACustomAJAXControlExtender.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,ad872df0-da73-44df-9c07-03b38e437995.aspx</id>
    <published>2007-06-30T09:34:23.733-06:00</published>
    <updated>2007-07-31T06:40:13.56-06:00</updated>
    <category term="ASP.NET" label="ASP.NET" scheme="http://www.notesoncode.com/articles/CategoryView,category,ASPNET.aspx" />
    <category term="AJAX" label="AJAX" scheme="http://www.notesoncode.com/articles/CategoryView,category,AJAX.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Download the source code for this demo <a href="content/attachments/AjaxControlDemo.zip">here</a>.
</p>
        <h4>Introduction
</h4>
        <p>
The demand for high quality web interfaces is continually increasing. The movement
towards <em>Web 2.0</em> places an increasing emphasis in making a web application
look and feel like it were a home desktop application, with all the bells and whistles
attached. Users expect each page they visit to interact with them in a smooth and
natural way.
</p>
        <p>
Asynchronous JavaScript and XML, <acronym title="Asynchronous JavaScript and XML">AJAX</acronym>,
is one tool that helps to create this user experience. In a typical scenario, JavaScript
on the page sends and retrieves data from the web server asynchronously, updating
the web page without flicker and with minimal delay. <a href="http://www.google.com/" rel="nofollow">Google</a> Inc.'s <a href="http://www.gmail.com/" rel="nofollow">GMail</a> is
an example. Each GMail page retrieves content from GMail only a portion at a time,
"on demand". The entire experience is seamless.
</p>
        <p>
          <a href="http://www.microsoft.com/">Microsoft</a> recently released a framework for <a href="http://ajax.asp.net/"><acronym title="Asynchronous JavaScript and XML">AJAX</acronym></a>,
and a corresponding collection of control extenders called the <a href="http://ajax.asp.net/ajaxtoolkit">AJAX
Control Toolkit</a>. The toolkit contains several control extenders. An <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> control
extender adds <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> functionality
to a non-ajax web control. The extender approach can be particularly useful when there
is a requirement to add similar <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> behavior
to more than one control type, such as adding behaviors to buttons, images, and panels.
</p>
        <p>
This tutorial introduces the basics of creating a custom <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> control
extender. We discuss embedded resources, property decorations (attributes), and client-side
Web service calls.
</p>
        <h4>The Scenario
</h4>
        <p>
Consider a form built for a web application. The form contains several places for
input. From time to time, users flood you with questions about the meaning of each
element. You want to add some context sensitive help to the page to spare yourself
all the most frequently asked questions, saving both time and money.
</p>
        <p>
We'll create a very simple <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> control
extender that wraps a server control, such as a <code>Button</code> or a <code>Label</code>,
and adds context sensitive help at the click of a mouse. Moreover, the extender will
populate the help with the results of a web service call to separate the content from
the functionality.
</p>
        <h4>Getting Started
</h4>
        <p>
Below is an example of the body of a very simple page. There are three main elements.
On each, we want to add context sensitive help. The fourth element, the <code>Panel</code> at
the bottom, is a placeholder for our help content.
</p>
        <pre class="code">
          <span class="hl kwa">&lt;form</span> id=<span class="hl str">"form1"</span> runat=<span class="hl str">"server"</span>&gt; <span class="hl kwa">&lt;asp:Button</span> ID=<span class="hl str">"Button1"</span> runat=<span class="hl str">"server"</span> Text=<span class="hl str">"Looking
for help..."</span>/&gt; <span class="hl kwa">&lt;br</span> /&gt; <span class="hl kwa">&lt;br</span> /&gt; <span class="hl kwa">&lt;asp:Image</span> ID=<span class="hl str">"Image1"</span> runat=<span class="hl str">"server"</span> ImageUrl=<span class="hl str">"~/flower.jpg"</span> /&gt; <span class="hl kwa">&lt;br</span> /&gt; <span class="hl kwa">&lt;br</span> /&gt; <span class="hl kwa">&lt;asp:Panel</span> ID=<span class="hl str">"Panel1"</span> runat=<span class="hl str">"server"</span>&gt;
This is the content of the panel.<span class="hl kwa">&lt;br</span> /&gt; If you would
like to find help, kindly click among this text.<span class="hl kwa">&lt;br</span> /&gt;
Good luck! <span class="hl kwa">&lt;/asp:Panel&gt;</span><span class="hl kwa">&lt;br</span> /&gt; <span class="hl kwa">&lt;br</span> /&gt; <span class="hl kwa">&lt;asp:Panel</span> ID=<span class="hl str">"HelpPanel"</span> runat=<span class="hl str">"server"</span> /&gt; <span class="hl kwa">&lt;br</span> /&gt; <span class="hl kwa">&lt;br</span> /&gt; <span class="hl kwa">&lt;/form&gt;</span></pre>
        <p>
To make our control extender consumable from any website, we'll compile the extender
into a separate assembly. To do this, first make sure that the extender templates
are installed. Download the <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> control
toolkit from <a href="http://ajax.asp.net" rel="nofollow">http://ajax.asp.net</a>,
extract the files into the directory of choice, and execute the .vsi installers located
in the archive at <strong>AjaxControlExtender\AjaxControlExtender.vsi</strong>. Once
this is installed, add the new extender project to your Visual Studio solution by
right clicking on the solution and selecting Add -&gt; New Project, or selecting File
-&gt; Add -&gt; New Project from the menu.
</p>
        <img src="content/attachments/addnewproj.jpg" alt="" />
        <p>
Select <strong>ASP.NET AJAX Control Project</strong> from the templates.
</p>
        <img src="content/attachments/ajaxproject.gif" alt="" />
        <p>
Delete the default <code>.cs</code> and <code>.js</code> files, and create a directory, <code>Help</code> to
hold the new control. Right click on the folder, select Add -&gt; New Item, and select <strong>ASP.NET
AJAX Extender Control</strong> from the templates. Name the control "Help", since
the convention of "HelpExtender" is added by default.
</p>
        <img src="content/attachments/ajaxcontrol.jpg" alt="" />
        <p>
We now have the basic file structure for the control.
</p>
        <h4>Configuring the Namespaces
</h4>
        <p>
It is important to give some thought to the namespace conventions for your control.
There are three namespaces of immediate concern: 
</p>
        <ol>
          <li>
The namespace of your server code</li>
          <li>
The namespace of your client JavaScript</li>
          <li>
The default namespace of your assembly</li>
        </ol>
        <p>
Adjusting the namespace of server code is plain and direct. I chose <code>KbrProductions.Web.Extensions</code>,
after the pattern set by Microsoft's <code>System.Web.Extensions</code>. The client
namespace is adjusted in the <code>.js</code> file. For this project the client namespace
is <code>KbrProductions.Ajax</code>. A simple search and replace can fix the handful
of references. Finally, the default namespace of the assembly can be configured by
right clicking on the project file, selecting Properties, and editing the namespace
in the Application tab. This namespace is important because it influences embedded
resources.
</p>
        <img src="content/attachments/projproperties.jpg" alt="" />
        <p>
For the JavaScript file to be consumable by the website, we must include it as a resource
to the project assembly. Do this by selecting the file in Solution Explorer, viewing
its properties, and setting the Build Action attribute to Embedded Resource.
</p>
        <img src="content/attachments/embed.jpg" alt="" />
        <p>
Now visit the <code>HelpExtender.cs</code> file. Edit the assembly attribute to read:
</p>
        <pre class="code">
          <span class="hl sym">[</span>assembly<span class="hl sym">:</span> System<span class="hl sym">.</span>Web<span class="hl sym">.</span>UI<span class="hl sym">.</span><span class="hl kwd">WebResource</span><span class="hl sym">(</span><span class="hl str">"KbrProductions.Web.Extensions.Help.HelpBehavior.js"</span><span class="hl sym">,</span><span class="hl str">"text/javascript"</span><span class="hl sym">)]</span></pre>
        <p>
The first parameter is a resource path for the javascript file. The naming convention
for the path is: [Assembly Namespace][.directory][.FileName]. Remember, the assembly
namespace is the default namespace set in the project properties. For the directory,
use dots (.) to separate folders instead of backslashes. Misconfiguring this line
is the common cause of the following web page error:
</p>
        <blockquote>Assembly 'Extensions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
contains a Web resource with name 'Extensions.Help.HelpBehavior.js', but does not
contain an embedded resource with name 'Extensions.Help.HelpBehavior.js'.</blockquote>
        <p>
When in doubt, fire up <acronym title="Intermediate Language Disassembler">ILDASM</acronym> and
view the contents of the control assembly. The manifest contains the proper path for
the JavaScript file on a <code>.mresource</code> line.
</p>
        <img src="content/attachments/ildasm.jpg" alt="" />
        <p>
The extender class includes the JavaScript file by means of a <code>ClientScriptResource</code> decoration.
Modify the decoration as shown below, where the first string indicates the client
class name, and the second string specifies the resource exactly as specified in the
assembly attribute earlier in the page.
</p>
        <pre class="code">
          <span class="hl sym">[</span>
          <span class="hl kwd">ClientScriptResource</span>
          <span class="hl sym">(</span>
          <span class="hl str">"KbrProductions.Ajax.HelpBehavior"</span>
          <span class="hl sym">,</span>
          <span class="hl str">"KbrProductions.Web.Extensions.Help.HelpBehavior.js"</span>
          <span class="hl sym">)]</span>
        </pre>
        <p>
At this point, the namespaces of the control assembly should be configured.
</p>
        <h4>Server-Side Extender Properties
</h4>
        <p>
Next, we'll specify the properties that will be available as attributes to our extender
markup. Because we inherit from <code>ExtenderControlBase</code>, we already have
a <code>TargetControlID</code> property, which we can use to specify the control we
want to extend.
</p>
        <p>
We also want to specify the control that will contain the contents of our help. We
decorate the property with the <code>IDReferenceProperty</code> attribute to enable
the extender to automatically resolve the specified <code>ID</code> into a <code>ClientID</code>.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
ID of the control that will contain the help content.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl sym">[</span>ExtenderControlProperty<span class="hl sym">]</span><span class="hl sym">[</span><span class="hl kwd">DefaultValue</span><span class="hl sym">(</span><span class="hl str">""</span><span class="hl sym">)]</span><span class="hl sym">[</span><span class="hl kwd">IDReferenceProperty</span><span class="hl sym">(</span><span class="hl kwd">typeof</span><span class="hl sym">(</span>WebControl<span class="hl sym">))]</span><span class="hl sym">[</span><span class="hl kwd">ClientPropertyName</span><span class="hl sym">(</span><span class="hl str">"helpPanelID"</span><span class="hl sym">)]</span><span class="hl kwa">public</span><span class="hl kwb">string</span> HelpPanelID <span class="hl sym">{</span><span class="hl kwa">get</span><span class="hl sym">{</span><span class="hl kwa">return</span><span class="hl kwd">GetPropertyValue</span><span class="hl sym">(</span><span class="hl str">"HelpPanelID"</span><span class="hl sym">,</span><span class="hl str">""</span><span class="hl sym">);
}</span><span class="hl kwa">set</span><span class="hl sym">{</span><span class="hl kwd">SetPropertyValue</span><span class="hl sym">(</span><span class="hl str">"HelpPanelID"</span><span class="hl sym">,</span><span class="hl kwa">value</span><span class="hl sym">);
}</span><span class="hl sym">}</span></pre>
        <p>
Next, we'll build properties to define the location of a Web service that provides
the text for the context-sensitive help. We decorate this property as a <code>UrlProperty</code>,
which provides automatic resolving of server-relative URLs, that is, any URL starting
with "~/". We also decorate it with a <code>TypeConverter</code> to handle some Web
service specific url handling.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
Path to the webservice that the extender will pull the images from.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl sym">[</span>
          <span class="hl kwd">UrlProperty</span>
          <span class="hl sym">()]</span>
          <span class="hl sym">[</span>
          <span class="hl kwd">ExtenderControlProperty</span>
          <span class="hl sym">()]</span>
          <span class="hl sym">[</span>
          <span class="hl kwd">TypeConverter</span>
          <span class="hl sym">(</span>
          <span class="hl kwd">typeof</span>
          <span class="hl sym">(</span>ServicePathConverter<span class="hl sym">))]</span><span class="hl sym">[</span><span class="hl kwd">ClientPropertyName</span><span class="hl sym">(</span><span class="hl str">"servicePath"</span><span class="hl sym">)]</span><span class="hl kwa">public</span><span class="hl kwb">string</span> ServicePath <span class="hl sym">{</span><span class="hl kwa">get</span><span class="hl sym">{</span><span class="hl kwa">return</span><span class="hl kwd">GetPropertyValue</span><span class="hl sym">(</span><span class="hl str">"ServicePath"</span><span class="hl sym">,</span><span class="hl str">""</span><span class="hl sym">);
}</span><span class="hl kwa">set</span><span class="hl sym">{</span><span class="hl kwd">SetPropertyValue</span><span class="hl sym">(</span><span class="hl str">"ServicePath"</span><span class="hl sym">,</span><span class="hl kwa">value</span><span class="hl sym">);
}</span><span class="hl sym">}</span></pre>
        <p>
Next we add a required property to define which method should be called.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
The webservice method that will be called to supply help.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl sym">[</span>ExtenderControlProperty<span class="hl sym">]</span><span class="hl sym">[</span>RequiredProperty<span class="hl sym">]</span><span class="hl sym">[</span><span class="hl kwd">DefaultValue</span><span class="hl sym">(</span><span class="hl str">""</span><span class="hl sym">)]</span><span class="hl sym">[</span><span class="hl kwd">ClientPropertyName</span><span class="hl sym">(</span><span class="hl str">"serviceMethod"</span><span class="hl sym">)]</span><span class="hl kwa">public</span><span class="hl kwb">string</span> ServiceMethod <span class="hl sym">{</span><span class="hl kwa">get</span><span class="hl sym">{</span><span class="hl kwa">return</span><span class="hl kwd">GetPropertyValue</span><span class="hl sym">(</span><span class="hl str">"ServiceMethod"</span><span class="hl sym">,</span><span class="hl str">""</span><span class="hl sym">);
}</span><span class="hl kwa">set</span><span class="hl sym">{</span><span class="hl kwd">SetPropertyValue</span><span class="hl sym">(</span><span class="hl str">"ServiceMethod"</span><span class="hl sym">,</span><span class="hl kwa">value</span><span class="hl sym">);
}</span><span class="hl sym">}</span></pre>
        <p>
And, finally, we add a property to define a parameter for the Web service call. We
could treat this parameter as a key to determine which piece of help to return from
the service.
</p>
        <pre class="code">
          <span class="hl slc">/// &lt;summary&gt;</span>
          <span class="hl slc">///
Context key to pass to the service method to get help text.</span>
          <span class="hl slc">///
&lt;/summary&gt;</span>
          <span class="hl sym">[</span>ExtenderControlProperty<span class="hl sym">]</span><span class="hl sym">[</span><span class="hl kwd">DefaultValue</span><span class="hl sym">(</span><span class="hl str">""</span><span class="hl sym">)]</span><span class="hl sym">[</span><span class="hl kwd">ClientPropertyName</span><span class="hl sym">(</span><span class="hl str">"helpContextKey"</span><span class="hl sym">)]</span><span class="hl kwa">public</span><span class="hl kwb">string</span> HelpContextKey <span class="hl sym">{</span><span class="hl kwa">get</span><span class="hl sym">{</span><span class="hl kwa">return</span><span class="hl kwd">GetPropertyValue</span><span class="hl sym">(</span><span class="hl str">"HelpContextKey"</span><span class="hl sym">,</span><span class="hl str">""</span><span class="hl sym">);
}</span><span class="hl kwa">set</span><span class="hl sym">{</span><span class="hl kwd">SetPropertyValue</span><span class="hl sym">(</span><span class="hl str">"HelpContextKey"</span><span class="hl sym">,</span><span class="hl kwa">value</span><span class="hl sym">);
}</span><span class="hl sym">}</span></pre>
        <p>
The next step is to provide a client-side equivalent interface to these properties.
</p>
        <h4>Client-Side Extender Properties
</h4>
        <p>
Basic handling of each property from JavaScript is made extremely simple due to the
AJAX Control Toolkit. All that is required is to add variable declarations to the
constructor function, and add get/set functions to the object prototype. It is important
to note that the property names for the get and set functions are case sensitive and
should reflect the <code>ClientPropertyName</code> configured in the server-side extender
code. Additional utility variables can be added to the constructor function as well.
</p>
        <pre class="code">KbrProductions<span class="hl sym">.</span>Ajax<span class="hl sym">.</span>HelpBehavior <span class="hl sym">=</span><span class="hl kwa">function</span><span class="hl sym">(</span>element<span class="hl sym">)
{</span> KbrProductions<span class="hl sym">.</span>Ajax<span class="hl sym">.</span>HelpBehavior<span class="hl sym">.</span><span class="hl kwd">initializeBase</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">,
[</span>element<span class="hl sym">]);</span><span class="hl kwa">this</span><span class="hl sym">.</span>_helpContextKey <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl slc">//
HelpContextKey property</span><span class="hl kwa">this</span><span class="hl sym">.</span>_serviceMethod <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl slc">//
ServiceMethod property</span><span class="hl kwa">this</span><span class="hl sym">.</span>_servicePath <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl slc">//
ServicePath property</span><span class="hl kwa">this</span><span class="hl sym">.</span>_helpPanelID <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl slc">//
HelpPanelID property</span><span class="hl kwa">this</span><span class="hl sym">.</span>_helpPanel <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl slc">//
HelpPanel element</span><span class="hl kwa">this</span><span class="hl sym">.</span>_clickHandler <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl slc">//
Click Event handler for the extended control</span><span class="hl kwa">this</span><span class="hl sym">.</span>_targetElement <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl slc">//
Element of the extended control</span><span class="hl sym">}</span> KbrProductions<span class="hl sym">.</span>Ajax<span class="hl sym">.</span>HelpBehavior<span class="hl sym">.</span><span class="hl kwa">prototype</span><span class="hl sym">=
{</span><span class="hl slc">// ...</span><span class="hl slc">// extended properties</span> get_serviceMethod <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">()
{</span><span class="hl kwa">return this</span><span class="hl sym">.</span>_serviceMethod<span class="hl sym">;
},</span> set_serviceMethod <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">(</span><span class="hl kwc">value</span><span class="hl sym">)
{</span><span class="hl kwa">this</span><span class="hl sym">.</span>_serviceMethod <span class="hl sym">=</span><span class="hl kwc">value</span><span class="hl sym">;
},</span> get_servicePath <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">()
{</span><span class="hl kwa">return this</span><span class="hl sym">.</span>_servicePath<span class="hl sym">;
},</span> set_servicePath <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">(</span><span class="hl kwc">value</span><span class="hl sym">)
{</span><span class="hl kwa">this</span><span class="hl sym">.</span>_servicePath <span class="hl sym">=</span><span class="hl kwc">value</span><span class="hl sym">;
},</span> get_helpContextKey <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">()
{</span><span class="hl kwa">return this</span><span class="hl sym">.</span>_helpContextKey<span class="hl sym">;
},</span> set_helpContextKey <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">(</span><span class="hl kwc">value</span><span class="hl sym">)
{</span><span class="hl kwa">this</span><span class="hl sym">.</span>_helpContextKey <span class="hl sym">=</span><span class="hl kwc">value</span><span class="hl sym">;
},</span> get_helpPanelID <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">()
{</span><span class="hl kwa">return this</span><span class="hl sym">.</span>_helpPanelID<span class="hl sym">;
},</span> set_helpPanelID <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">(</span><span class="hl kwc">value</span><span class="hl sym">)
{</span><span class="hl kwa">this</span><span class="hl sym">.</span>_helpPanelID <span class="hl sym">=</span><span class="hl kwc">value</span><span class="hl sym">;
}</span><span class="hl sym">}</span></pre>
        <h4>Fleshing out the Client Behavior
</h4>
        <p>
All that remains to complete our extender is to implement the client behavior. To
provide feedback to the user that a control contains help, change the mouse cursor
of the extended element. The object prototype's initialize method is a good place
to do this.
</p>
        <pre class="code">initialize <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">()
{</span> KbrProductions<span class="hl sym">.</span>Ajax<span class="hl sym">.</span>HelpBehavior<span class="hl sym">.</span><span class="hl kwd">callBaseMethod</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">,</span><span class="hl str">'initialize'</span><span class="hl sym">);</span><span class="hl slc">//
Apply the CSS cursor style, "help"</span><span class="hl kwa">this</span><span class="hl sym">.</span>_targetElement <span class="hl sym">=</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">get_element</span><span class="hl sym">();</span><span class="hl kwa">this</span><span class="hl sym">.</span>_targetElement<span class="hl sym">.</span>style<span class="hl sym">.</span>cursor <span class="hl sym">=</span><span class="hl str">"help"</span><span class="hl sym">;</span><span class="hl slc">//
...</span></pre>
        <p>
Next, wire up an event handler in the initialize function to handle the click event
of the target element. Use the Function.createDelegate method to create the handler.
This ensures that multiple handlers can potentially be attached to the element without
conflicting.
</p>
        <pre class="code">
          <span class="hl slc">// Attach an event handler to the click
event of the element</span>
          <span class="hl kwa">if</span>
          <span class="hl sym">(</span>
          <span class="hl kwa">this</span>
          <span class="hl sym">.</span>_targetElement<span class="hl sym">)
{</span><span class="hl kwa">this</span><span class="hl sym">.</span>_clickHandler <span class="hl sym">=</span> Function<span class="hl sym">.</span><span class="hl kwd">createDelegate</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">,</span><span class="hl kwa">this</span><span class="hl sym">.</span>_onClick<span class="hl sym">);</span> $<span class="hl kwd">addHandler</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">.</span>_targetElement<span class="hl sym">,</span><span class="hl str">'click'</span><span class="hl sym">,</span><span class="hl kwa">this</span><span class="hl sym">.</span>_clickHandler<span class="hl sym">);</span><span class="hl sym">}</span></pre>
        <p>
Add functionality to the dispose method to clean up the event handler. This is good
practice to keep our memory clean.
</p>
        <pre class="code">dispose <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">()
{</span><span class="hl slc">// Remove the event handler from the element if attached.</span><span class="hl kwa">if</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">.</span>_clickHandler<span class="hl sym">)
{</span> $<span class="hl kwd">removeHandler</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">.</span>_targetElement<span class="hl sym">,</span><span class="hl str">'click'</span><span class="hl sym">,</span><span class="hl kwa">this</span><span class="hl sym">.</span>_clickHandler<span class="hl sym">);</span><span class="hl kwa">this</span><span class="hl sym">.</span>_clickHandler <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl sym">}</span> KbrProductions<span class="hl sym">.</span>Ajax<span class="hl sym">.</span>HelpBehavior<span class="hl sym">.</span><span class="hl kwd">callBaseMethod</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">,</span><span class="hl str">'dispose'</span><span class="hl sym">);</span><span class="hl sym">},</span></pre>
        <p>
We now create the <code>this._onClick</code> function to handle the mouse click. We
first implement a few lines to prevent any full-page postback that might occur. Parameters
to the service method should be prepared as a dictionary key-value pair. We then can
invoke the method using the ASP.NET AJAX <code>Sys.Net.WebServiceProxy.invoke</code> method.
The method has seven parameters: 
</p>
        <ol>
          <li>
The path to the Web service.</li>
          <li>
The method to invoke.</li>
          <li>
A parameter to indicate whether the call should use HTTP POST. For security reasons,
this defaults to <code>false</code>.</li>
          <li>
The parameters for the method.</li>
          <li>
An event handler to be called when the service call returns successfully.</li>
          <li>
An event handler to be called if the service call fails.</li>
          <li>
Any JavaScript structure to pass to the event handler. This is a place holder if you
want to send more than the defaults.</li>
        </ol>
        <pre class="code">
          <span class="hl slc">// click event for the extended element</span> _onClick <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">(</span>e<span class="hl sym">)
{</span><span class="hl slc">// prevent post back.</span> e<span class="hl sym">.</span><span class="hl kwd">preventDefault</span><span class="hl sym">();</span> e<span class="hl sym">.</span><span class="hl kwd">stopPropagation</span><span class="hl sym">();</span><span class="hl slc">//
prepare parameters, if necessary</span><span class="hl kwa">var</span> params <span class="hl sym">=</span><span class="hl kwa">null</span><span class="hl sym">;</span><span class="hl kwa">if</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">.</span>_helpContextKey<span class="hl sym">)
{</span> params <span class="hl sym">= {</span><span class="hl str">'helpContextKey'</span><span class="hl sym">:</span><span class="hl kwa">this</span><span class="hl sym">.</span>_helpContextKey <span class="hl sym">};</span><span class="hl sym">}</span><span class="hl slc">//
Invoke the web service</span> Sys<span class="hl sym">.</span>Net<span class="hl sym">.</span>WebServiceProxy<span class="hl sym">.</span><span class="hl kwd">invoke</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">.</span>_servicePath<span class="hl sym">,</span><span class="hl slc">//
Service path</span><span class="hl kwa">this</span><span class="hl sym">.</span>_serviceMethod<span class="hl sym">,</span><span class="hl slc">//
Service method</span><span class="hl kwa">false</span><span class="hl sym">,</span><span class="hl slc">//
use POST (default false)</span> params<span class="hl sym">,</span><span class="hl slc">//
params</span> Function<span class="hl sym">.</span><span class="hl kwd">createDelegate</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">,</span><span class="hl kwa">this</span><span class="hl sym">.</span>_onServiceReply<span class="hl sym">),</span><span class="hl slc">//
on success</span><span class="hl kwa">null</span><span class="hl sym">,</span><span class="hl slc">//
on failure</span><span class="hl kwa">null</span><span class="hl sym">);</span><span class="hl slc">//
additional context</span><span class="hl sym">},</span></pre>
        <p>
The last addition to the script is the <code>this._onServiceReplay</code> handler.
The toolkit uses <code>sender</code> and <code>eventArgs</code> as parameters to the
method. I think they're misnamed, because the object coming in through the <code>sender</code> parameter
is the server reply; a <code>string</code>. At any rate, we fill our help panel with
the contents of the reply.
</p>
        <pre class="code">
          <span class="hl slc">// reply event for the service call</span> _onServiceReply <span class="hl sym">:</span><span class="hl kwa">function</span><span class="hl sym">(</span>sender<span class="hl sym">,</span> eventArgs<span class="hl sym">)
{</span><span class="hl kwc">document</span><span class="hl sym">.</span><span class="hl kwc">getElementById</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">.</span>_helpPanelID<span class="hl sym">).</span><span class="hl kwc">innerHTML</span><span class="hl sym">=</span> sender<span class="hl sym">;</span><span class="hl sym">}</span></pre>
        <p>
At this point, we completed all the code for the extender. All that remains is to
reference this assembly by the website and add our extender to the page.
</p>
        <h4>Using the Help Extender
</h4>
        <p>
Building the extender took a fair handful of code lines, but it all pays off when
we start using the extender in the Web site. Add a reference to the extender project,
and add the folling line to the <code>&lt;system.web&gt;&lt;pages&gt;&lt;controls&gt;</code> element
of the Web.config file:
</p>
        <pre class="code">
          <span class="hl kwa">&lt;add</span> tagPrefix=<span class="hl str">"kbr"</span> namespace=<span class="hl str">"KbrProductions.Web.Extensions"</span> assembly=<span class="hl str">"Extensions"</span>/&gt; </pre>
        <p>
Note that the application will need references to the ASP.NET AJAX assembly and the
AJAX Control Toolkit as well. Add a <code>ScriptManager</code> to the page, and extenders
for the <code>Button</code>, <code>Image</code> and <code>Panel</code>.
</p>
        <pre class="code">
          <span class="hl kwa">&lt;kbr:HelpExtender</span> ID=<span class="hl str">"help1"</span> runat=<span class="hl str">"server"</span> TargetControlID=<span class="hl str">"Button1"</span> HelpContextKey=<span class="hl str">"1"</span> HelpPanelID=<span class="hl str">"HelpPanel"</span> ServiceMethod=<span class="hl str">"GetHelp"</span> /&gt; <span class="hl kwa">&lt;kbr:HelpExtender</span> ID=<span class="hl str">"help2"</span> runat=<span class="hl str">"server"</span> TargetControlID=<span class="hl str">"Image1"</span> HelpContextKey=<span class="hl str">"2"</span> HelpPanelID=<span class="hl str">"HelpPanel"</span> ServiceMethod=<span class="hl str">"GetHelp"</span> /&gt; <span class="hl kwa">&lt;kbr:HelpExtender</span> ID=<span class="hl str">"help3"</span> runat=<span class="hl str">"server"</span> TargetControlID=<span class="hl str">"Panel1"</span> HelpContextKey=<span class="hl str">"3"</span> HelpPanelID=<span class="hl str">"HelpPanel"</span> ServiceMethod=<span class="hl str">"GetHelp"</span> /&gt; </pre>
        <p>
All that remains is to define the Web service that provides our help. We'll inject
an AJAX-friendly service method right into this page. In a more practical application,
the <code>if/else if</code> structure could be replaced with database access, file
IO, or any other data retrieval. All that is required is that the method is static,
takes the appropriate parameters, and returns the expected <code>string</code> result.
</p>
        <pre class="code">
          <span class="hl kwa">&lt;script</span> runat=<span class="hl str">"Server"</span> type=<span class="hl str">"text/C#"</span>&gt; </pre>
        <pre class="code">
          <span class="hl sym">[</span>System<span class="hl sym">.</span>Web<span class="hl sym">.</span>Services<span class="hl sym">.</span>WebMethod<span class="hl sym">]</span><span class="hl sym">[</span>System<span class="hl sym">.</span>Web<span class="hl sym">.</span>Script<span class="hl sym">.</span>Services<span class="hl sym">.</span>ScriptMethod<span class="hl sym">]</span><span class="hl kwa">public
static</span><span class="hl kwb">string</span><span class="hl kwd">GetHelp</span><span class="hl sym">(</span><span class="hl kwb">string</span> helpContextKey<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">if</span><span class="hl sym">(</span>helpContextKey <span class="hl sym">==</span><span class="hl str">"1"</span><span class="hl sym">)</span><span class="hl kwa">return</span><span class="hl str">"There
is help awaiting you."</span><span class="hl sym">;</span><span class="hl kwa">else
if</span><span class="hl sym">(</span>helpContextKey <span class="hl sym">==</span><span class="hl str">"2"</span><span class="hl sym">)</span><span class="hl kwa">return</span><span class="hl str">"Excellent
clicking, friend!"</span><span class="hl sym">;</span><span class="hl kwa">else</span><span class="hl kwa">return</span><span class="hl str">"There
is no help found for the likes of you."</span><span class="hl sym">;</span><span class="hl sym">}</span></pre>
        <pre class="code">
          <span class="hl kwa">&lt;/script&gt;</span>
        </pre>
        <p>
Running the page now shows that each control has a help cursor. When clicked, JavaScript
issues an asynchronous Web service call which populates a portion of the page with
context-sensitive help. The control extender is finished.
</p>
        <img src="content/attachments/screen.jpg" alt="" />
        <h4>Conclusion
</h4>
        <p>
ASP.NET <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> is an excellent
tool to provide a richer experience to the user by taking advantage of the control
extender model and asynchronous callbacks. With a little footwork, it is possible
to create extenders that add complex behaviors to a variety of server controls, potentially
saving considerable effort down the road. The AJAX Control Toolkit provides classes
that simplify the process of creating your own extenders. Also, because the AJAX Control
Toolkit is open source, you can download the existing control extenders and add behaviors
to them, as well.
</p>
        <p>
Happy Coding!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=ad872df0-da73-44df-9c07-03b38e437995" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Contributing to Open Source</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/06/14/ContributingToOpenSource.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,15e0316e-e337-41a5-a2fe-522f15388bf8.aspx</id>
    <published>2007-06-13T21:12:31.65-06:00</published>
    <updated>2007-07-31T06:40:13.56-06:00</updated>
    <category term="Misc" label="Misc" scheme="http://www.notesoncode.com/articles/CategoryView,category,Misc.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
A few months ago I contributed to an open-source project for the first time. This
was an exciting moment for me. Until recently, I had always borrowed knowledge from
blogging gurus such as <a href="http://weblogs.asp.net/scottgu/default.aspx" rel="nofollow">Scott
Guthrie</a> and <a href="http://www.hanselman.com/blog/" rel="nofollow">Scott Hanselman</a>,
and open source repositories such as <a href="http://www.codeproject.com/" rel="nofollow">Code
Project</a> and <a href="http://web.sourceforge.com/" rel="nofollow">SourceForge</a>.
This world of programming was, and still is, a great well of programming tips and
tricks that help me out quite regularly.
</p>
        <p>
As I developed the framework for Notes on Code, I started using the <acronym title="cascading style sheets">CSS</acronym> Friendly
Control Adapters, an open source library available on <a href="http://www.codeplex.com/cssfriendly" rel="nofollow">CodePlex.com</a>.
These control adapters improve the quality of ASP.NET page markup by reducing the
frequency of <code>&lt;table&gt;</code> objects on the page when rendering complex
controls such as the <code>TreeView</code>.
</p>
        <p>
On my pages, I kept a small link to <acronym title="World Wide Web Consortium">W3C</acronym> to
verify that my <acronym title="Extended Hypertext Markup Language">XHTML</acronym> was
correct. What to my surprise when I found that it was not. The culprit turned out
to be the control adapters, which injected a <code>&lt;link&gt;</code> tag in the <code>&lt;body&gt;</code> section.
After searching Google for some time, it became clear to me that this was an unidentified
bug.
</p>
        <p>
It was a simple fix, really. It only took a moment to find the offending lines in
the source code and, due to the quality design of the original product, find a suitable
alternative.
</p>
        <p>
I was very impressed with the management of the project by <a href="http://www.sidesofmarch.com/" rel="nofollow">bdemarzo</a>.
By the evening of the same day, the source code for the project was updated to include
the changes.
</p>
        <p>
I'll say that it felt like a rite of passage for me. I felt like I had something to
contribute to the community, however small that contribution might be. If you haven't
tried it yet, go for it. Go anywhere there is code and try it out.
</p>
        <p>
Happy Coding!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=15e0316e-e337-41a5-a2fe-522f15388bf8" />
      </div>
    </content>
  </entry>
  <entry>
    <title>How to Mark a Method Deprecated in C#</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/06/12/HowToMarkAMethodDeprecatedInC.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,957012d3-28a2-4a98-b54b-20ee9f1ae353.aspx</id>
    <published>2007-06-12T17:50:19.95-06:00</published>
    <updated>2007-07-31T06:40:13.56-06:00</updated>
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Have you ever started out writing code one way and later discover that another way
is much, much better? It happens to me daily. I face a difficulty, sometimes, when
I want to refactor my code into a more concise, elegant form, but some of my teammates
already use the existing methods.
</p>
        <p>
One neat feature of C# is the ability to decorate methods and other structures in
code. A useful decoration for this situation is the <code>Obsolete</code> decoration.
Here are several examplse:
</p>
        <pre class="code">
          <span class="hl sym">[</span>Obsolete<span class="hl sym">]</span><span class="hl kwb">void</span><span class="hl kwd">ObsoleteMethod1</span><span class="hl sym">()
{ }</span><span class="hl sym">[</span><span class="hl kwd">Obsolete</span><span class="hl sym">(</span><span class="hl str">"This
is why we don't use this..."</span><span class="hl sym">)]</span><span class="hl kwb">void</span><span class="hl kwd">ObsoleteMethod2</span><span class="hl sym">()
{ }</span><span class="hl sym">[</span><span class="hl kwd">Obsolete</span><span class="hl sym">(</span><span class="hl str">"If
you use this, there will be compile errors"</span><span class="hl sym">,</span><span class="hl kwa">true</span><span class="hl sym">)]</span><span class="hl kwb">void</span><span class="hl kwd">ObsoleteMethod3</span><span class="hl sym">()
{ }</span></pre>
        <p>
The description comes in handy because it will show up in the tooltip when typing
in the method in Visual Studio. This ensures that it is not necessary for developers
to have source code to detect whether a method should be discontinued.
</p>
        <center>
          <img src="content/attachments/deprecated.jpg" alt="Descriptions specified in the Obsolete decoration appear in the tooltip" />
        </center>
        <p>
You can also forcefully terminate the use of the method without blindly removing it.
The third sample demonstrates this. Using the <code>ObsoleteMethod3</code> method
would cause a compile-time error. This provides a good opportunity to discontinue
a method and provide an explanation as to why it is no longer used.
</p>
        <p>
Happy coding!
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=957012d3-28a2-4a98-b54b-20ee9f1ae353" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Basic File IO and the DataGridView</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/06/11/BasicFileIOAndTheDataGridView.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,587a27c4-d752-4b8e-b0cf-03dc3a38f309.aspx</id>
    <published>2007-06-11T15:54:46.873-06:00</published>
    <updated>2007-07-31T06:40:13.56-06:00</updated>
    <category term="C#" label="C#" scheme="http://www.notesoncode.com/articles/CategoryView,category,C.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Copyright ©2006 By <strong><em>Keith Rimington</em></strong><ul><li><a href="content/attachments/LineCounter_exe.zip">Download sample exe - 24 Kb </a></li><li><a href="content/attachments/LineCounter_prj.zip">Download project - 36 Kb </a></li></ul><p><img src="content/attachments/LineCounter.png" alt="Screenshot Image - LineCounter counts the lines in files and places the results for each file in a DataGridView" /></p><h2>Introduction
</h2><p>
If you have ever wanted to know how quickly you write code, you have probably counted
lines. As programs get more involved and work is shared among a team, it is difficult
to know how many lines are "owned" by you.
</p><p>
Lines of code may not be the best way to measure performance (I am imagining a classroom
full of monkeys striking Enter, Enter, Enter... ). But sometimes is satisfying to
say, "Look what was done!"
</p><p>
This articles explores basic file IO, how to manually store results in a <code>DataGridView</code>,
and basic event handling.
</p><h2>Wiring up the GUI
</h2><p>
The GUI has just a few components. A <code>TextBox</code> provides a place where we
can enter the file extensions we are interested in counting. A <code>DataGridView</code> provides
a place to show results. A <code>CheckBox</code> provides us some options and a <code>StatusStrip</code> helps
us summarize results to the user.
</p><p>
Use the <code>Anchor</code> property to adjust how each <code>Control</code> "Clings"
to the walls of the <code>Form</code>. This allows us to resize the window to get
a better view if we have long filenames or a large number of results. Anchoring is
one of the convenient layout tools builtin to the environment.
</p><p><img src="content/attachments/LineCounter1.png" alt="New controls in the form editor make changing Anchoring a breeze." /></p><p>
Now we will wire up the columns in the <code>DataGridView</code> control. The form
editor makes this a breeze. Highlight the <code>DataGridView</code> and select from
the properties <code>Columns</code>.
</p><p><img src="content/attachments/LineCounter2.png" alt="The properties editor makes creating data columns easy." /></p><p>
We now have a dialog that can be used to generate our columns. Clicking on the Add
button opens an additional dialog that can be used to create columns. Choose a name
and header text, and the column type of <code>DataGridViewTextBoxColumn</code>. Other
interesting column properties include <code>FillWeight</code>, which affects how much
priority the column receives during layout.
</p><p><img src="content/attachments/LineCounter3.png" alt="Individual column properties can be adjusted in these dialogs." /></p><p>
The next step to giving the GUI functionality is to add event handlers. For example,
when we click on the Go button, we want the application to find files that match our
search criteria, open them, and count lines.
</p><p>
We can use the form editor to add this handler easily. Just double-click on the Go
button, and the event handler is added for us, like so:
</p><pre class="code"><span class="hl kwa">private</span><span class="hl kwb">void</span><span class="hl kwd">goButton_Click</span><span class="hl sym">(</span><span class="hl kwb">object</span> sender<span class="hl sym">,</span> EventArgs
e<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl slc">//
TODO: Count files here...</span><span class="hl sym">}</span></pre><p>
Also, the function is registered with the event delegate in the designer.cs file.
This is what tells the runtime that we want to run the <code>goButton_Click</code> method
when the <code>goButton.Click</code> event is fired.
</p><pre class="code"><span class="hl kwa">this</span><span class="hl sym">.</span>goButton<span class="hl sym">.</span>Click <span class="hl sym">+=</span><span class="hl kwa">new</span> System<span class="hl sym">.</span><span class="hl kwd">EventHandler</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">.</span>goButton_Click<span class="hl sym">);</span></pre><p>
Because there may be files found by our program that we want to ignore, we will wire
up the <code>DataGridView</code> to gather information about selected files only.
We can then pick and choose which results we want to tally up for our final line count.
</p><p>
Using the form editor, we set the <code>MultiSelect</code> property to <code>True</code> and
the <code>SelectionMode</code> property to <code>FullRowSelect</code>. All that's
left is adding an event handler to respond to changes in the selection. Find the <code>SelectionChanged</code> property
in the form editor and double-click to generate the following method:
</p><pre class="code"><span class="hl kwa">private</span><span class="hl kwb">void</span><span class="hl kwd">dgvResult_SelectionChanged</span><span class="hl sym">(</span><span class="hl kwb">object</span> sender<span class="hl sym">,</span> EventArgs
e<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl slc">//
TODO: Count the selection here.</span><span class="hl sym">}</span></pre><p>
Which is wired up in the designer.cs file like so:
</p><pre class="code"><span class="hl kwa">this</span><span class="hl sym">.</span>dgvResult<span class="hl sym">.</span>SelectionChanged <span class="hl sym">+=</span><span class="hl kwa">new</span> System<span class="hl sym">.</span><span class="hl kwd">EventHandler</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">.</span>dgvResult_SelectionChanged<span class="hl sym">);</span></pre><p>
A lot of changes can happen by playing with the properties in the form editor, but
lets move on to the meat of the project, cranking out our own lines of code.
</p><h2>Using a StreamReader to count lines
</h2><p>
Reading a file from the system is very easy in C#. The key objects involved are <code>File</code> and <code>StreamReader</code>.
The static method <code>File.OpenText</code> opens a file specified by a local or
fully-qualified path name, and generates a <code>StreamReader</code> object to digest
the file contents. <code>StreamReader</code> is built with the <code>ReadLine</code> method;
perfect for our task.
</p><pre class="code"><span class="hl kwa">private</span><span class="hl kwb">int</span><span class="hl kwd">CountLinesInFile</span><span class="hl sym">(</span><span class="hl kwb">string</span> filename<span class="hl sym">)</span><span class="hl sym">{</span> StreamReader
sr <span class="hl sym">=</span> File<span class="hl sym">.</span><span class="hl kwd">OpenText</span><span class="hl sym">(</span>filename<span class="hl sym">);</span><span class="hl kwb">int</span> count <span class="hl sym">=</span><span class="hl num">0</span><span class="hl sym">;</span><span class="hl kwa">while</span><span class="hl sym">(</span>sr<span class="hl sym">.</span><span class="hl kwd">ReadLine</span><span class="hl sym">()
!=</span><span class="hl kwa">null</span><span class="hl sym">)</span> count<span class="hl sym">++;</span> sr<span class="hl sym">.</span><span class="hl kwd">Close</span><span class="hl sym">();</span><span class="hl kwa">return</span> count<span class="hl sym">;</span><span class="hl sym">}</span></pre><h2>Finding Files in a Directory
</h2><p>
Our next task is to determine which files we should open. We will make use of the <code>System.Collections.Generic.List&lt;&gt;</code> class
to contain our filenames. The following code snippet demonstrates how we collect all
the filenames that match the requested extensions.
</p><pre class="code"><span class="hl kwa">private</span><span class="hl kwb">void</span><span class="hl kwd">CountFiles</span><span class="hl sym">()</span><span class="hl sym">{</span><span class="hl slc">//
Repository for discovered filenames</span> List<span class="hl sym">&lt;</span><span class="hl kwb">string</span><span class="hl sym">&gt;</span> filenames <span class="hl sym">=</span><span class="hl kwa">new</span> List<span class="hl sym">&lt;</span><span class="hl kwb">string</span><span class="hl sym">&gt;();</span><span class="hl slc">//
Running linecount total</span><span class="hl kwb">int</span> total <span class="hl sym">=</span><span class="hl num">0</span><span class="hl sym">;</span><span class="hl slc">//
The Split method is a quick and dirty way to parse a string.</span><span class="hl kwb">string</span><span class="hl sym">[]</span> extensions <span class="hl sym">=</span> txtExts<span class="hl sym">.</span>Text<span class="hl sym">.</span><span class="hl kwd">Split</span><span class="hl sym">(</span><span class="hl str">""</span><span class="hl str">""</span><span class="hl sym">.</span><span class="hl kwd">ToCharArray</span><span class="hl sym">());</span><span class="hl kwa">foreach</span><span class="hl sym">(</span><span class="hl kwb">string</span> ext
in extensions<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl slc">//
The third parameter of this overload allows us to</span><span class="hl slc">// automatically
inspect subdirectories. Default is</span><span class="hl slc">// SearchOption.TopDirectoryOnly,
and the argument</span><span class="hl slc">// could have been omitted, but is included
here for</span><span class="hl slc">// information's sake.</span> filenames<span class="hl sym">.</span><span class="hl kwd">AddRange</span><span class="hl sym">(</span> chkSubDir<span class="hl sym">.</span>Checked
? Directory<span class="hl sym">.</span><span class="hl kwd">GetFiles</span><span class="hl sym">(</span> Directory<span class="hl sym">.</span><span class="hl kwd">GetCurrentDirectory</span><span class="hl sym">(),</span><span class="hl str">""</span><span class="hl sym">*.</span><span class="hl str">""</span><span class="hl sym">+</span> ext<span class="hl sym">,</span> SearchOption<span class="hl sym">.</span>AllDirectories<span class="hl sym">)
:</span> Directory<span class="hl sym">.</span><span class="hl kwd">GetFiles</span><span class="hl sym">(</span> Directory<span class="hl sym">.</span><span class="hl kwd">GetCurrentDirectory</span><span class="hl sym">(),</span><span class="hl str">""</span><span class="hl sym">*.</span><span class="hl str">""</span><span class="hl sym">+</span> ext<span class="hl sym">,</span> SearchOption<span class="hl sym">.</span>TopDirectoryOnly<span class="hl sym">));</span><span class="hl sym">}</span><span class="hl slc">//
...</span></pre><p>
Our next task is to open each file, count the lines, and add the results to the <code>DataGridView</code>.
We will use the <code>DataGridView.Rows.Add(object[] params)</code> method to add
each new row. With this method, each <code>object</code> should correspond, in order,
to the columns of the <code>DataGridView</code>.
</p><pre class="code"><span class="hl slc">// ...</span><span class="hl slc">// Wipe
out any previous results</span> dgvResult<span class="hl sym">.</span>Rows<span class="hl sym">.</span><span class="hl kwd">Clear</span><span class="hl sym">();</span><span class="hl slc">//
No that we have all the filenames,</span><span class="hl slc">// open the files to
count their lines.</span><span class="hl kwa">foreach</span><span class="hl sym">(</span><span class="hl kwb">string</span> filename
in filenames<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwb">int</span> count <span class="hl sym">=</span><span class="hl kwd">CountLinesInFile</span><span class="hl sym">(</span>filename<span class="hl sym">);</span> total <span class="hl sym">+=</span> count<span class="hl sym">;</span><span class="hl slc">//
This line adds a new row to the DataGridView.</span><span class="hl slc">// We choose
the string.Substring method to display</span><span class="hl slc">// only the relative
path of the file</span> dgvResult<span class="hl sym">.</span>Rows<span class="hl sym">.</span><span class="hl kwd">Add</span><span class="hl sym">(</span> filename<span class="hl sym">.</span><span class="hl kwd">Substring</span><span class="hl sym">(</span>Directory<span class="hl sym">.</span><span class="hl kwd">GetCurrentDirectory</span><span class="hl sym">().</span>Length<span class="hl sym">+</span><span class="hl num">1</span><span class="hl sym">),</span> count<span class="hl sym">.</span><span class="hl kwd">ToString</span><span class="hl sym">());</span><span class="hl sym">}</span><span class="hl slc">//
Add the total to the bottom</span> dgvResult<span class="hl sym">.</span>Rows<span class="hl sym">.</span><span class="hl kwd">Add</span><span class="hl sym">(</span><span class="hl kwa">new</span><span class="hl kwb">object</span><span class="hl sym">[]
{</span><span class="hl str">""</span>Total<span class="hl sym">:</span><span class="hl str">""</span><span class="hl sym">,</span> total<span class="hl sym">.</span><span class="hl kwd">ToString</span><span class="hl sym">()
});</span><span class="hl sym">}</span></pre><p>
Call this method from the <code>goButton_Clicked</code> event handler and we have
a line counter!
</p><h2>Using MultiSelect with the DataGridView
</h2><p>
To wrap things up, we will add functionality to ignore some of the results, if we
wish, in our total. The following code snippet counts the results in the selected
rows, and writes the results to the <code>StatusStrip</code> below.
</p><pre class="code"><span class="hl kwa">private</span><span class="hl kwb">void</span><span class="hl kwd">CountSelection</span><span class="hl sym">()</span><span class="hl sym">{</span><span class="hl kwb">int</span> selected <span class="hl sym">=</span><span class="hl num">0</span><span class="hl sym">;</span><span class="hl kwb">int</span> total <span class="hl sym">=</span><span class="hl num">0</span><span class="hl sym">;</span><span class="hl kwa">foreach</span><span class="hl sym">(</span>DataGridViewRow
row in dgvResult<span class="hl sym">.</span>Rows<span class="hl sym">)</span><span class="hl sym">{</span><span class="hl kwa">try</span><span class="hl sym">{</span><span class="hl slc">//
Ignore rows that are either not selected</span><span class="hl slc">// or are the
total row. Because some ""filler""</span><span class="hl slc">//
rows exist, use the catch block to effectively</span><span class="hl slc">// ignore
the invalid data in those rows.</span><span class="hl kwa">if</span><span class="hl sym">(</span>row<span class="hl sym">.</span>Selected <span class="hl sym">&amp;&amp;</span> row<span class="hl sym">.</span>Cells<span class="hl sym">[</span><span class="hl num">0</span><span class="hl sym">].</span>Value<span class="hl sym">.</span><span class="hl kwd">ToString</span><span class="hl sym">()
!=</span><span class="hl str">""</span>Total<span class="hl sym">:</span><span class="hl str">""</span><span class="hl sym">)</span><span class="hl sym">{</span> selected<span class="hl sym">++;</span> total <span class="hl sym">+=</span><span class="hl kwb">int</span><span class="hl sym">.</span><span class="hl kwd">Parse</span><span class="hl sym">(</span>row<span class="hl sym">.</span>Cells<span class="hl sym">[</span><span class="hl num">1</span><span class="hl sym">].</span>Value<span class="hl sym">.</span><span class="hl kwd">ToString</span><span class="hl sym">());</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl kwa">catch</span><span class="hl sym">{
}</span><span class="hl sym">}</span><span class="hl slc">// Update the status label
with the results</span> lblFileCt<span class="hl sym">.</span>Text <span class="hl sym">=</span> selected<span class="hl sym">.</span><span class="hl kwd">ToString</span><span class="hl sym">()
+</span><span class="hl str">""</span> files selected<span class="hl str">""</span><span class="hl sym">;</span> lblLineCt<span class="hl sym">.</span>Text <span class="hl sym">=</span> total <span class="hl sym">==</span><span class="hl num">0</span> ? <span class="hl str">""</span>No
lines<span class="hl str">""</span><span class="hl sym">:</span> total<span class="hl sym">.</span><span class="hl kwd">ToString</span><span class="hl sym">()
+</span><span class="hl str">""</span> lines<span class="hl str">""</span><span class="hl sym">;</span><span class="hl sym">}</span></pre><h2>Conclusion
</h2><p>
This article just scratches the surface of file IO and data controls like the <code> DataGridView</code>.
I hope you found this article useful. This <a href="http://www.codeproject.com/useritems/LineCounter.asp"> article</a> was
published on <a href="http://www.codeproject.com/">CodeProject</a></p><img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=587a27c4-d752-4b8e-b0cf-03dc3a38f309" /></div>
    </content>
  </entry>
  <entry>
    <title>Full-featured Drag and Drop Event Handling in Java</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/06/11/FullfeaturedDragAndDropEventHandlingInJava.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,2ce56067-8636-4666-8e01-8d6e1fbd3272.aspx</id>
    <published>2007-06-11T06:53:24.543-06:00</published>
    <updated>2007-07-31T06:40:13.56-06:00</updated>
    <category term="Java" label="Java" scheme="http://www.notesoncode.com/articles/CategoryView,category,Java.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Copyright ©2006 By <strong><em>Keith Rimington</em></strong><ul><li><a href="content/attachments/DragAndDrop_src.zip">Download source - 8 Kb </a></li><li><a href="content/attachments/DragAndDrop_doc.zip">Download javadocs - 69 Kb </a></li><li><a href="content/attachments/DragAndDrop_prj.zip">Download eclipse project - 17 Kb</a></li></ul><p><img src="content/attachments/DragAndDrop.png" alt="Screenshot Image - two rectangular JLabels act as a DragSource and a DropTarget" /></p><h4>Introduction
</h4><p>
While writing a computer variant of Milton Bradley's famous game, BattleShip, I wanted
to allow the user to drag and drop his/her own ships onto the grid in very much the
same way that it would be done in real life. This required Java's powerful <code>java.awt.dnd</code> and <code>java.awt.dnd.datatransfer</code> API.
Finding that there seemed to be only a little information on the internet about drag
and drop event handling in Java, I prepared this demonstration.
</p><p>
Responsive interaction with the application and the mouse is important when writing
graphical applications, such as a games. As the complexity of our data structures
grow, and the requirements of our interface to communicate to the user increase, having
a good mechanism to do Drag and Drop (DND) operations is vital. Because many things
can happen during a drag operation, including data transfer, failed drags, and crossing
in, over, and out of controls, Java provides a comprehensive event-handling API for
drag and drop.
</p><h4>What's in the Demo?
</h4><p>
This article explores drag and drop within single applications. The demo is a simple
window with two custom controls. One control is configured to be the source of drag
operations, the other the target. Additionally, the data transferred between controls
is a custom class containing both a <code>String</code> and a <code>Color</code>.
Knowing how to handle such a simple class gives us the capability of transfering any
object of any class!
</p><p>
Will will focus on the following seven classes and interfaces:
</p><ul><li>
The <code>DataFlavor</code> class to define custom data types.</li><li>
The <code>Transferable</code> Interface, which defines packages of transferable data.</li><li>
The <code>DragSource</code> which we will include in a component we wish to be the
source of a drag.</li><li>
The <code>DropTarget</code> which we will inclide in a component we wish to be the
target of a drag.</li><li>
The <code>DragGestureListener</code> which fires handlers when the drag operation
begins</li><li>
The <code>DragSourceListener</code> Interface, which defines objects that handle five
events related to drag and drop over-effects.</li><li>
The <code>DropTargetListener</code> Interface, which defines objects that handle five
events related to drag and drop under-effects.</li></ul><p>
The source code included with this project contains almost line-by-line comments describing
each step in further detail.
</p><h4>Over-effects and Under-effects
</h4><p>
Before looking at the code, it is fitting to say a little about drag effects. Over-effects
and under-effects are two different ways that a GUI can communicate to the user what
is taking place. Over-effects are usually cursor changes generated by the source of
the drag whenever the drag state changes or updates. Under-effects are usually generated
by targets to add to the drag effect.
</p><p>
For example, in some editors that support dragging text from one document to another,the
source document may choose whether to display a move cursor or a cancel cursor. This
is an over-effect. The target document may display a caret at the point of insertion
in the document. This is an under-effect.
</p><p>
By separating the roles of the source and the target, neither is dependent on the
actions of the other to ensure that the appropriate message is displayed to the user.
</p><h4>Creating a Transferable and DataFlavors
</h4><p>
Java's <code>Transferable</code> interface provides a way to wrap up any class and
label it for transfer. In the demo, we will wrap up a <code>Color </code>object and
a <code>String</code>. The first thing we will do is make a custom <code>DataFlavor</code> for
our data. A <code>DataFlavor</code> is a label that identifies what kind of object
is being dragged. By giving our data a <code>DataFlavor</code> the target can discriminate
between which flavors it can receive.
</p><pre class="code"><span class="hl kwa">public class</span> DemoTransferable <span class="hl sym">{</span><span class="hl slc">//
This is the DataFlavor we will associate with Color\n</span><span class="hl kwa">public
static final</span><span class="hl kwc">DataFlavor</span> customColorFlavor <span class="hl sym">=</span><span class="hl kwd">getCustomColorFlavor</span><span class="hl sym">();</span><span class="hl slc">//
This is the DataFlavor we will associate with String</span><span class="hl kwa">public
static final</span><span class="hl kwc">DataFlavor</span> customStringFlavor <span class="hl sym">=</span><span class="hl kwd">getCustomColorFlavor</span><span class="hl sym">();</span><span class="hl slc">//
...</span><span class="hl slc">// This method creates a flavor for Color.</span><span class="hl kwa">public
static</span><span class="hl kwc">DataFlavor</span><span class="hl kwd">getCustomColorFlavor</span><span class="hl sym">()
{</span><span class="hl kwc">DataFlavor</span> temp <span class="hl sym">=</span> null<span class="hl sym">;</span><span class="hl kwa">try</span><span class="hl sym">{</span> temp <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwc">DataFlavor</span><span class="hl sym">(</span><span class="hl kwc">DataFlavor</span><span class="hl sym">.</span>javaJVMLocalObjectMimeType <span class="hl sym">+</span><span class="hl str">""</span><span class="hl sym">;</span><span class="hl kwa">class</span><span class="hl sym">=</span>java<span class="hl sym">.</span>awt<span class="hl sym">.</span><span class="hl kwc">Color</span><span class="hl str">""</span><span class="hl sym">);</span><span class="hl sym">}</span><span class="hl kwa">catch</span><span class="hl sym">(</span><span class="hl kwc">ClassNotFoundException</span> e<span class="hl sym">)
{</span><span class="hl slc">// Handle the exception</span><span class="hl sym">}</span><span class="hl kwa">return</span> temp<span class="hl sym">;</span><span class="hl sym">}</span><span class="hl slc">//
This method creates a flavor for String</span><span class="hl kwa">public static</span><span class="hl kwc">DataFlavor</span><span class="hl kwd">getCustomStringFlavor</span><span class="hl sym">()
{</span><span class="hl kwc">DataFlavor</span> temp <span class="hl sym">=</span> null<span class="hl sym">;</span><span class="hl kwa">try</span><span class="hl sym">{</span> temp <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwc">DataFlavor</span><span class="hl sym">(</span><span class="hl kwc">DataFlavor</span><span class="hl sym">.</span>javaJVMLocalObjectMimeType <span class="hl sym">+</span><span class="hl str">""</span><span class="hl sym">;</span><span class="hl kwa">class</span><span class="hl sym">=</span>java<span class="hl sym">.</span>lang<span class="hl sym">.</span><span class="hl kwc">String</span><span class="hl str">""</span><span class="hl sym">);</span><span class="hl sym">}</span><span class="hl kwa">catch</span><span class="hl sym">(</span><span class="hl kwc">ClassNotFoundException</span> e<span class="hl sym">)
{</span><span class="hl slc">// Handle the exception</span><span class="hl sym">}</span><span class="hl kwa">return</span> temp<span class="hl sym">;</span><span class="hl sym">}</span><span class="hl sym">}</span></pre><p>
The static <code>String</code>, <code>DataFlavor.javaJVMLocalObjectMimeType </code> identifes
our flavor as one that must stay within the application. This can be useful if you
want to restrict the ability to transfer data from one instance of the application
to another.
</p><p>
The remaining three methods are required by the <code>Transferable</code> interface.
They are used to broadcast which <code>DataFlavor</code> types are available and do
the data transfer.
</p><pre class="code"><span class="hl slc">// ...</span><span class="hl slc">// Provide
an array of supported flavors</span><span class="hl kwa">public synchronized</span><span class="hl kwc">DataFlavor</span><span class="hl sym">[]</span><span class="hl kwd">getTransferDataFlavors</span><span class="hl sym">()
{</span><span class="hl kwa">return new</span><span class="hl kwc">DataFlavor</span><span class="hl sym">[]
{</span> customColorFlavor<span class="hl sym">,</span> customStringFlavor <span class="hl sym">};</span><span class="hl sym">}</span><span class="hl slc">//
Answer inquiries on supported flavors</span><span class="hl kwa">public</span><span class="hl kwb">boolean</span><span class="hl kwd">isDataFlavorSupported</span><span class="hl sym">(</span><span class="hl kwc">DataFlavor</span> flavor<span class="hl sym">)
{</span><span class="hl kwa">return</span><span class="hl sym">(</span> flavor<span class="hl sym">.</span><span class="hl kwd">match</span><span class="hl sym">(</span>customColorFlavor<span class="hl sym">)
||</span> flavor<span class="hl sym">.</span><span class="hl kwd">match</span><span class="hl sym">(</span>customStringFlavor<span class="hl sym">));</span><span class="hl sym">}</span><span class="hl slc">//
Do data transfer</span><span class="hl kwa">public synchronized</span><span class="hl kwc">Object</span><span class="hl kwd">getTransferData</span><span class="hl sym">(</span><span class="hl kwc">DataFlavor</span> flavor<span class="hl sym">)</span><span class="hl kwa">throws</span><span class="hl kwc">UnsupportedFlavorException</span><span class="hl sym">{</span><span class="hl kwa">if</span><span class="hl sym">(</span>flavor<span class="hl sym">.</span><span class="hl kwd">match</span><span class="hl sym">(</span>customColorFlavor<span class="hl sym">))</span><span class="hl kwa">return</span> color<span class="hl sym">;</span><span class="hl kwa">else
if</span><span class="hl sym">(</span>flavor<span class="hl sym">.</span><span class="hl kwd">match</span><span class="hl sym">(</span>customStringFlavor<span class="hl sym">))</span><span class="hl kwa">return</span> string<span class="hl sym">;</span><span class="hl kwa">else
throw new</span><span class="hl kwc">UnsupportedFlavorException</span><span class="hl sym">(</span>flavor<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl slc">//
...</span></pre><h4>Creating a Drag Source
</h4><p>
Now we will add functionality to a <code>JLabel</code> to allow it to be the source
of a drag operation. To do this, we will embed a <code>DragSource </code>object in
it.
</p><pre class="code"><span class="hl kwa">public class</span> SourceLabel <span class="hl kwa">extends</span><span class="hl kwc">JLabel</span><span class="hl sym">{</span><span class="hl slc">//
This object makes our JLabel a drag source.</span><span class="hl kwa">protected</span><span class="hl kwc">DragSource</span> dragSource<span class="hl sym">;</span><span class="hl slc">//
...</span></pre><p>
Now we must give the <code>dragSource</code> a <code>DragGestureListener </code> .
This object will respond to the event that is a combination of a mouse down event
and a mouse move event. Before we associate this listener with <code>dragSource</code>,
we will implement the interface in a concrete class. Furthermore, our new <code>DemoDragGestureListener</code> class
delegates the remaining drag and drop events to a <code>DragSourceListener</code>.
Both class are implemented below:
</p><pre class="code"><span class="hl kwa">private class</span> DemoDragGestureListener <span class="hl kwa">implements</span><span class="hl kwc">DragGestureListener</span><span class="hl sym">{</span><span class="hl com">/**</span><span class="hl com"> *
This method is invoked when a drag gesture begins.</span><span class="hl com"> *
Our main goal here is to begin the drag process and</span><span class="hl com"> *
attach a {@code DragSourceListener}.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dragGestureRecognized</span><span class="hl sym">(</span><span class="hl kwc">DragGestureEvent</span> e<span class="hl sym">)
{</span><span class="hl slc">// modifiers includes information about the mouse click.</span><span class="hl kwb">int</span> modifiers <span class="hl sym">=</span> e<span class="hl sym">.</span><span class="hl kwd">getTriggerEvent</span><span class="hl sym">().</span><span class="hl kwd">getModifiers</span><span class="hl sym">();</span><span class="hl slc">//
Send black text on a left click.</span><span class="hl kwa">if</span><span class="hl sym">((</span>modifiers <span class="hl sym">&amp;</span><span class="hl kwc">InputEvent</span><span class="hl sym">.</span>BUTTON1_MASK<span class="hl sym">)
!=</span><span class="hl num">0</span><span class="hl sym">) {</span><span class="hl slc">//
The startDrag method attaches a DemoDragSourceListener</span><span class="hl slc">//
to handle the remaining dnd events.</span> e<span class="hl sym">.</span><span class="hl kwd">startDrag</span><span class="hl sym">(</span><span class="hl kwc">DragSource</span><span class="hl sym">.</span>DefaultMoveNoDrop<span class="hl sym">,</span><span class="hl kwa">new</span><span class="hl kwd">DemoTransferable</span><span class="hl sym">(</span><span class="hl str">""</span>Transferred <span class="hl kwc">Text</span><span class="hl sym">.</span><span class="hl str">""</span><span class="hl sym">,</span><span class="hl kwc">Color</span><span class="hl sym">.</span>black<span class="hl sym">),</span><span class="hl kwa">new</span><span class="hl kwd">DemoDragSourceListener</span><span class="hl sym">());</span><span class="hl sym">}</span><span class="hl slc">//
Send randomly colored text on a right click.</span><span class="hl kwa">else if</span><span class="hl sym">((</span>modifiers <span class="hl sym">&amp;</span><span class="hl kwc">InputEvent</span><span class="hl sym">.</span>BUTTON3_MASK<span class="hl sym">)
!=</span><span class="hl num">0</span><span class="hl sym">) {</span><span class="hl slc">//
Do the same thing, but with a random color ...</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl sym">}</span><span class="hl kwa">private
class</span> DemoDragSourceListener <span class="hl kwa">implements</span><span class="hl kwc">DragSourceListener</span><span class="hl sym">{</span><span class="hl com">/**</span><span class="hl com"> *
dragEnter is fired whenever the cursor enters a new component.</span><span class="hl com"> *</span><span class="hl com"> *
Here we will determine if the target component is allowing</span><span class="hl com"> *
a move action, and update the cursor appropriately.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dragEnter</span><span class="hl sym">(</span><span class="hl kwc">DragSourceDragEvent</span> e<span class="hl sym">){</span><span class="hl kwb">int</span> action <span class="hl sym">=</span> e<span class="hl sym">.</span><span class="hl kwd">getDropAction</span><span class="hl sym">();</span><span class="hl kwa">if</span><span class="hl sym">((</span>action <span class="hl sym">&amp;</span><span class="hl kwc">DnDConstants</span><span class="hl sym">.</span>ACTION_MOVE<span class="hl sym">)!=</span><span class="hl num">0</span><span class="hl sym">)</span> e<span class="hl sym">.</span><span class="hl kwd">getDragSourceContext</span><span class="hl sym">().</span><span class="hl kwd">setCursor</span><span class="hl sym">(</span><span class="hl kwc">DragSource</span><span class="hl sym">.</span>DefaultMoveDrop<span class="hl sym">);</span><span class="hl kwa">else</span> e<span class="hl sym">.</span><span class="hl kwd">getDragSourceContext</span><span class="hl sym">()</span><span class="hl sym">.</span><span class="hl kwd">setCursor</span><span class="hl sym">(</span><span class="hl kwc">DragSource</span><span class="hl sym">.</span>DefaultMoveNoDrop<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl com">/**</span><span class="hl com"> *
dragOver is fired rapidly whenever the cursor moves within</span><span class="hl com"> *
a component.</span><span class="hl com"> *</span><span class="hl com"> * Here we
will determine if the target component is allowing</span><span class="hl com"> *
a move action, and update the cursor appropriately.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dragOver</span><span class="hl sym">(</span><span class="hl kwc">DragSourceDragEvent</span> e<span class="hl sym">){</span><span class="hl kwb">int</span> action <span class="hl sym">=</span> e<span class="hl sym">.</span><span class="hl kwd">getDropAction</span><span class="hl sym">();</span><span class="hl kwa">if</span><span class="hl sym">((</span>action <span class="hl sym">&amp;</span><span class="hl kwc">DnDConstants</span><span class="hl sym">.</span>ACTION_MOVE<span class="hl sym">)!=</span><span class="hl num">0</span><span class="hl sym">)</span> e<span class="hl sym">.</span><span class="hl kwd">getDragSourceContext</span><span class="hl sym">().</span><span class="hl kwd">setCursor</span><span class="hl sym">(</span><span class="hl kwc">DragSource</span><span class="hl sym">.</span>DefaultMoveDrop<span class="hl sym">);</span><span class="hl kwa">else</span> e<span class="hl sym">.</span><span class="hl kwd">getDragSourceContext</span><span class="hl sym">()</span><span class="hl sym">.</span><span class="hl kwd">setCursor</span><span class="hl sym">(</span><span class="hl kwc">DragSource</span><span class="hl sym">.</span>DefaultMoveNoDrop<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl com">/**</span><span class="hl com"> *
dragExit is fired whenever the cursor exits a component.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dragExit</span><span class="hl sym">(</span><span class="hl kwc">DragSourceEvent</span> e<span class="hl sym">){</span> e<span class="hl sym">.</span><span class="hl kwd">getDragSourceContext</span><span class="hl sym">()</span><span class="hl sym">.</span><span class="hl kwd">setCursor</span><span class="hl sym">(</span><span class="hl kwc">DragSource</span><span class="hl sym">.</span>DefaultMoveNoDrop<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl com">/**</span><span class="hl com"> *
dragDropEnd is called whenever the dnd action concludes.</span><span class="hl com"> *</span><span class="hl com"> *
Here we simply change the text on the label</span><span class="hl com"> * to reflect
the success of the operation.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dragDropEnd</span><span class="hl sym">(</span><span class="hl kwc">DragSourceDropEvent</span> e<span class="hl sym">){</span><span class="hl kwa">if</span><span class="hl sym">(</span>e<span class="hl sym">.</span><span class="hl kwd">getDropSuccess</span><span class="hl sym">())</span> SourceLabel<span class="hl sym">.</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">setText</span><span class="hl sym">(</span><span class="hl str">""</span>The
drop succeeded<span class="hl sym">!</span><span class="hl str">""</span><span class="hl sym">);</span><span class="hl kwa">else</span> SourceLabel<span class="hl sym">.</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">setText</span><span class="hl sym">(</span><span class="hl str">""</span>The
drop failed<span class="hl sym">.</span><span class="hl str">""</span><span class="hl sym">);</span><span class="hl sym">}</span><span class="hl com">/**</span><span class="hl com"> *
dropActionChanged is an opportunity to unify actions when the</span><span class="hl com"> *
drop action changes. For our purposes, it wasn't necessary to</span><span class="hl com"> *
do anything here.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dropActionChanged</span><span class="hl sym">(</span><span class="hl kwc">DragSourceDragEvent</span> e<span class="hl sym">){</span><span class="hl sym">}</span><span class="hl sym">}</span></pre><p>
All that's left to do for the drag source is to hook up these internal classes in
our <code>SourceLabel</code> class.
</p><h4>Creating the Drop Target
</h4><p>
Now all we need to do is create a drop target that can receive our custom class. We
will add this functionality to another <code>JLabel</code>.
</p><pre class="code"><span class="hl kwa">public class</span> TargetLabel <span class="hl kwa">extends</span><span class="hl kwc">JLabel</span><span class="hl sym">{</span><span class="hl slc">//
This gives our class DropTarget abilities.</span><span class="hl kwa">protected</span><span class="hl kwc">DropTarget</span> dropTarget<span class="hl sym">;</span><span class="hl slc">//
We will define this class below.</span><span class="hl kwa">protected</span> DemoDropTargetListener
demoDropTargetListener<span class="hl sym">;</span><span class="hl slc">// ...</span></pre><p><code>DemoDropTargetListener</code> implements the <code>DropTargetListener</code> interface
to handle the five drag and drop events. We will implement the class below:
</p><pre class="code"><span class="hl kwa">private class</span> DemoDropTargetListener <span class="hl kwa">implements</span><span class="hl kwc">DropTargetListener</span><span class="hl sym">{</span><span class="hl com">/**
True indicates dragging should be painted. */</span><span class="hl kwb">boolean</span> dragging<span class="hl sym">=</span>false<span class="hl sym">;</span><span class="hl com">/**
The string being transfered. */</span><span class="hl kwc">String</span> string<span class="hl sym">;</span><span class="hl com">/**
The color being transfered. */</span><span class="hl kwc">Color</span> color<span class="hl sym">;</span><span class="hl com">/**
The location of the dragging cursor. */</span><span class="hl kwc">Point</span> dragLocation <span class="hl sym">=</span> null<span class="hl sym">;</span><span class="hl com">/**</span><span class="hl com"> *
dragEnter is called whenever the cursor enters this component.</span><span class="hl com"> *
Our under effect will be a string drawn in the designated color.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dragEnter</span><span class="hl sym">(</span><span class="hl kwc">DropTargetDragEvent</span> e<span class="hl sym">)
{</span><span class="hl kwa">if</span><span class="hl sym">(!</span><span class="hl kwd">isValidData</span><span class="hl sym">(</span>e<span class="hl sym">))
{</span> e<span class="hl sym">.</span><span class="hl kwd">rejectDrag</span><span class="hl sym">();</span> dragging<span class="hl sym">=</span>false<span class="hl sym">;</span><span class="hl kwd">repaint</span><span class="hl sym">();</span><span class="hl kwa">return</span><span class="hl sym">;</span><span class="hl sym">}</span> e<span class="hl sym">.</span><span class="hl kwd">acceptDrag</span><span class="hl sym">(</span><span class="hl kwc">DnDConstants</span><span class="hl sym">.</span>ACTION_MOVE<span class="hl sym">);</span> dragging <span class="hl sym">=</span> true<span class="hl sym">;</span> dragLocation <span class="hl sym">=</span> e<span class="hl sym">.</span><span class="hl kwd">getLocation</span><span class="hl sym">();</span> color <span class="hl sym">=</span><span class="hl kwd">getColor</span><span class="hl sym">(</span>e<span class="hl sym">);</span> string <span class="hl sym">=</span><span class="hl kwd">getString</span><span class="hl sym">(</span>e<span class="hl sym">);</span><span class="hl kwd">repaint</span><span class="hl sym">();</span><span class="hl sym">}</span><span class="hl com">/**</span><span class="hl com"> *
dragOver is called when the cursor moves within this component.</span><span class="hl com"> *
dragOver allows us to update the location of the string.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dragOver</span><span class="hl sym">(</span><span class="hl kwc">DropTargetDragEvent</span> e<span class="hl sym">)
{</span><span class="hl kwa">if</span><span class="hl sym">(!</span><span class="hl kwd">isValidData</span><span class="hl sym">(</span>e<span class="hl sym">))
{</span> e<span class="hl sym">.</span><span class="hl kwd">rejectDrag</span><span class="hl sym">();</span> dragging<span class="hl sym">=</span>false<span class="hl sym">;</span><span class="hl kwd">repaint</span><span class="hl sym">();</span><span class="hl kwa">return</span><span class="hl sym">;</span><span class="hl sym">}</span> e<span class="hl sym">.</span><span class="hl kwd">acceptDrag</span><span class="hl sym">(</span><span class="hl kwc">DnDConstants</span><span class="hl sym">.</span>ACTION_MOVE<span class="hl sym">);</span> dragging <span class="hl sym">=</span> true<span class="hl sym">;</span> dragLocation <span class="hl sym">=</span> e<span class="hl sym">.</span><span class="hl kwd">getLocation</span><span class="hl sym">();</span><span class="hl kwd">repaint</span><span class="hl sym">();</span><span class="hl sym">}</span><span class="hl com">/**</span><span class="hl com"> *
dropActionChanged is an opportunity to unify actions when the</span><span class="hl com"> *
drop action changes. For our purposes, it isn't necessary to</span><span class="hl com"> *
do anything here.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dropActionChanged</span><span class="hl sym">(</span><span class="hl kwc">DropTargetDragEvent</span> e<span class="hl sym">)
{</span><span class="hl sym">}</span><span class="hl com">/**</span><span class="hl com"> *
dragExit is called whenever the cursor exits this component.</span><span class="hl com"> *
Our under-effects should quit immediately.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">dragExit</span><span class="hl sym">(</span><span class="hl kwc">DropTargetEvent</span> e<span class="hl sym">)
{</span> dragging <span class="hl sym">=</span> false<span class="hl sym">;</span><span class="hl kwd">repaint</span><span class="hl sym">();</span><span class="hl sym">}</span><span class="hl com">/**</span><span class="hl com"> *
This is where the drop magic actually occurs.</span><span class="hl com"> * Note:
The reason we do not call getColor now is that we</span><span class="hl com"> * already
have it from the DragEnter event.</span><span class="hl com"> */</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">drop</span><span class="hl sym">(</span><span class="hl kwc">DropTargetDropEvent</span> e<span class="hl sym">)
{</span><span class="hl kwa">if</span><span class="hl sym">(!</span><span class="hl kwd">isValidData</span><span class="hl sym">(</span>e<span class="hl sym">))
{</span> e<span class="hl sym">.</span><span class="hl kwd">rejectDrop</span><span class="hl sym">();</span> dragging<span class="hl sym">=</span>false<span class="hl sym">;</span><span class="hl kwd">repaint</span><span class="hl sym">();</span><span class="hl kwa">return</span><span class="hl sym">;</span><span class="hl sym">}</span> e<span class="hl sym">.</span><span class="hl kwd">dropComplete</span><span class="hl sym">(</span>true<span class="hl sym">);</span> dragging<span class="hl sym">=</span>false<span class="hl sym">;</span> TargetLabel<span class="hl sym">.</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">setBackground</span><span class="hl sym">(</span>color<span class="hl sym">);</span> TargetLabel<span class="hl sym">.</span><span class="hl kwa">this</span><span class="hl sym">.</span><span class="hl kwd">setText</span><span class="hl sym">(</span>string<span class="hl sym">);</span><span class="hl kwd">repaint</span><span class="hl sym">();</span><span class="hl sym">}</span><span class="hl slc">//
...</span><span class="hl slc">// isValidData(), getColor, and getString are defined
in the source.</span><span class="hl slc">// ...</span><span class="hl sym">}</span></pre><p>
Now a few lines of code to hook our new class up into <code>DropLabel </code>.
</p><pre class="code"><span class="hl kwa">public</span><span class="hl kwd">TargetLabel</span><span class="hl sym">()
{</span><span class="hl slc">// ...</span> demoDropTargetListener <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwd">DemoDropTargetListener</span><span class="hl sym">();</span><span class="hl com">/**</span><span class="hl com"> *
This constructor takes four argments, which are:</span><span class="hl com"> * The
listening component.</span><span class="hl com"> * The allowed drop actions.</span><span class="hl com"> *
The listener who will monitor drag and drops.</span><span class="hl com"> * A flag
indicating the target will immediately listen.</span><span class="hl com"> */</span> dropTarget <span class="hl sym">=</span><span class="hl kwa">new</span><span class="hl kwc">DropTarget</span><span class="hl sym">(</span><span class="hl kwa">this</span><span class="hl sym">,</span><span class="hl kwc">DnDConstants</span><span class="hl sym">.</span>ACTION_MOVE<span class="hl sym">,</span> demoDropTargetListener<span class="hl sym">,</span> true<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl kwa">public</span><span class="hl kwb">void</span><span class="hl kwd">paint</span><span class="hl sym">(</span><span class="hl kwc">Graphics</span> g<span class="hl sym">)
{</span><span class="hl kwa">super</span><span class="hl sym">.</span><span class="hl kwd">paint</span><span class="hl sym">(</span>g<span class="hl sym">);</span><span class="hl kwa">if</span><span class="hl sym">(</span>demoDropTargetListener<span class="hl sym">.</span>dragging<span class="hl sym">)
{</span> g<span class="hl sym">.</span><span class="hl kwd">setColor</span><span class="hl sym">(</span>demoDropTargetListener<span class="hl sym">.</span>color<span class="hl sym">);</span> g<span class="hl sym">.</span><span class="hl kwd">drawString</span><span class="hl sym">(</span> demoDropTargetListener<span class="hl sym">.</span>string<span class="hl sym">,</span> demoDropTargetListener<span class="hl sym">.</span>dragLocation<span class="hl sym">.</span>x<span class="hl sym">,</span> demoDropTargetListener<span class="hl sym">.</span>dragLocation<span class="hl sym">.</span>y<span class="hl sym">);</span><span class="hl sym">}</span><span class="hl sym">}</span></pre><h4>Wrapping it all up
</h4><p>
Now the two classes are complete and all that is left is to place them in a <code>Frame</code> and
watch them play out! Using a similar setup to this I was able to transfer images of
ships across panels and other components and render them on the components or the
glass pane.
</p><p>
I hope you found this article useful. Especially because this is my first public article,
your feedback is welcome. Thank you for reading.
</p><p>
This <a href="http://www.codeproject.com/useritems/DragAndDrop.asp">article</a> was
published on <a href="http://www.codeproject.com/">CodeProject</a></p><img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=2ce56067-8636-4666-8e01-8d6e1fbd3272" /></div>
    </content>
  </entry>
  <entry>
    <title>Notes On Code Debut</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/06/02/NotesOnCodeDebut.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,fb2e64b5-bce2-4448-9b43-35db2bc1ccbf.aspx</id>
    <published>2007-06-01T22:36:00-06:00</published>
    <updated>2007-07-31T06:40:13.56-06:00</updated>
    <category term="Misc" label="Misc" scheme="http://www.notesoncode.com/articles/CategoryView,category,Misc.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
At long last, Notes On Code arrives to the Web. So many great Web contributors have
helped me out that I hope in some small way to give back.
</p>
        <p>
My thanks to you all.
</p>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=fb2e64b5-bce2-4448-9b43-35db2bc1ccbf" />
      </div>
    </content>
  </entry>
  <entry>
    <title>A Few Old CS Projects</title>
    <link rel="alternate" type="text/html" href="http://www.notesoncode.com/articles/2007/03/16/AFewOldCSProjects.aspx" />
    <id>http://www.notesoncode.com/articles/PermaLink,guid,d9af21cc-da60-4ae4-87c9-8f34f7fd61ae.aspx</id>
    <published>2007-03-15T18:00:00-06:00</published>
    <updated>2009-05-02T17:57:33.1753184-06:00</updated>
    <category term="Misc" label="Misc" scheme="http://www.notesoncode.com/articles/CategoryView,category,Misc.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <span>While migrating to the new site, I found these programs I wrote while working
on my degree at <a href="http://www.kbrimington.net/articles/content/attachments/http://www.usu.edu">Utah
State University</a>. I have many fun memories learning how to write the code for
them, so I'm posting them here.</span>
        </p>
        <p>
          <span>
            <em>Happy Coding!</em>
          </span>
        </p>
        <table border="0">
          <tbody>
            <tr>
              <td>
                <a href="content/attachments/Battleship2006.rar">
                  <img style="width: 128px; height: 128px;" src="content/attachments/battleship.jpg" border="0" alt="" />
                  <br />
Download</a>
              </td>
              <td>
                <p>
                  <span>The first official K-b-rimington Productions application is Battleship 2006,
based on the 1984 Milton Bradley game, Battleship. In this game, compete against multiple
levels of artificial intelligence to become the king of the seas! OpenGL graphics
draw flying cannonballs and animations to enhance the playing experience. Logging
in over 11,000 lines of code, this is my most ambitious project ever! Enjoy! Thanks
to Dean Mathias for graphics feedback, and my wife, Delores, for her unfailing good
taste.</span>
                </p>
              </td>
            </tr>
            <tr>
              <td>
                <a href="content/attachments/3dhearts.msi">
                  <img style="width: 128px; height: 128px;" src="content/attachments/HeartsLarge.jpg" border="0" alt="" />
                  <br />
Download</a>
              </td>
              <td>
                <p>
                  <span>WereRabbits Hearts, developed in 2005 by Keith Rimington, Jeremy Pack, and Cody
Hillyard. This application includes 3-dimensional graphics, network play, artificial
intelligence, networked chat, animation and sound. To enjoy Hearts to the fullest,
click on everything in the room, such as the walls, your opponents, or the portraits
of dogs playing poker. Thanks to Jeremy and Cody for their tireless assistance developing
my favorite CS project to date!</span>
                </p>
              </td>
            </tr>
            <tr>
              <td>
                <a href="content/attachments/GameOfLife2.rar">
                  <img style="width: 128px; height: 128px;" src="content/attachments/GameOfLife2.jpg" border="0" alt="" />
                  <br />
Download</a>
              </td>
              <td>
                <p>
                  <span>The Game of Life v2.0 is the next stage of John Conway's wonderful simulation.
This new version uses OpenGL to accellerate graphics, allowing a framerate of up to
120 generations per second! Save and load different configurations with this new version.
Print your favorite generation, or circulate favorite patterns on the internet. Includes
a short history of the Game of Life and a summary of some of the most famous basic
formations.</span>
                </p>
                <p>
                  <span>Perhaps future iterations of the Game of Life will expand the grid, add scrolling,
and include file formats used by Game of Life researchers throughout the world. Keep
an eye out for the next Game of Life!</span>
                </p>
              </td>
            </tr>
            <tr>
              <td>
                <a href="content/attachments/GameOfLife.rar">
                  <img style="width: 128px; height: 128px;" src="content/attachments/GameOfLife.jpg" border="0" alt="" />
                  <br />
Download</a>
              </td>
              <td>
                <p>
                  <span>The Game of Life v1.0 is based on John Conway's fascinating simulated, "petri
dish." Each cell of the grid represents a place where "life" may exist. But life is
fragile, and can be snuffed out by overcrowding or even lonliness. Build colonies
of tiny organisms, flying spaceships, blossoming flowers, or any of a variety of new
formations and watch it grow!</span>
                </p>
                <p>
                  <span>Now Available : The Game of Life v2.0 with enhanced features and preset formations!
The Game of Life v2.0 will surely advance the enjoyment of watching the "Circle of
Life!"</span>
                </p>
              </td>
            </tr>
            <tr>
              <td>
                <a href="content/attachments/Hangman.rar">
                  <img style="width: 128px; height: 128px;" src="content/attachments/Hangman.jpg" border="0" alt="" />
                  <br />
Download</a>
              </td>
              <td>
                <p>
                  <span>Hangman v1.0 is the newest addition to my software projects. Developed completely
in C#, Hangman v1.0 represents my first work ever in the language. Enjoy a 34,000
word dictionary containing seemingly endless hangman fun. Extract the RAR archive
anywhere you want and enjoy. May require the .NET Framework 1.1 to function. Thanks
to Dr. Greg Jones for this fun introduction to C#.</span>
                </p>
              </td>
            </tr>
            <tr>
              <td>
                <a href="content/attachments/FlowerCube.zip">
                  <img style="width: 128px; height: 128px;" src="content/attachments/FlowerCube.jpg" border="0" alt="" />
                  <br />
Download</a>
              </td>
              <td>
                <p>
                  <span>In 2005 I began Studying OpenGL to prepare for the programming required for
WereRabbits Hearts. Using the wonderful online tutorials by NeHe posted on www.gamedev.net,
I wrote this simple program called FlowerCube. Use arrows to change the rotation of
the cube, page up and page down for zoom, F, L, and B for other settings. The picture
of the flower is a cropping from a photograph I took with my wife while we were on
our Honeymoon, so this simple program is one of my favorites.</span>
                </p>
              </td>
            </tr>
            <tr>
              <td>
                <a href="content/attachments/Stars.zip">
                  <img style="width: 128px; height: 128px;" src="content/attachments/Stars.jpg" border="0" alt="" />
                  <br />
Download</a>
              </td>
              <td>
                <p>
                  <span>Stars, although another very simple OpenGL program, has an enchanting appeal
as the formations fluxuate. This program used alpha blending to overlap flat textures
to create the allusion of distant, three-dimensional stars. Thanks again to NeHe and
his wonderful online tutorials. I think this application could make a splendid screen
saver. Perhaps in the near future I will add the screen saver handlers and redistribute,
but until then I am quite pleased with the result.</span>
                </p>
              </td>
            </tr>
            <tr>
              <td>
                <a href="content/attachments/IceRoom.zip">
                  <img style="width: 128px; height: 128px;" src="content/attachments/IceRoom.jpg" border="0" alt="" />
                  <br />
Download</a>
              </td>
              <td>
                <p>
                  <span>IceRoom is yet another OpenGL program I owe to the NeHe tutorials. This application
places the user as a "character" in a small room. Using the arrows, page up, and page
down allow the user to travel this small world. Caution is advised; there is no collision
detection. Some other features, such as lighting and texture quality may be toggled
used various letters of the keyboard. Enjoy this frozen chamber!</span>
                </p>
              </td>
            </tr>
          </tbody>
        </table>
        <img width="0" height="0" src="http://www.notesoncode.com/articles/aggbug.ashx?id=d9af21cc-da60-4ae4-87c9-8f34f7fd61ae" />
      </div>
    </content>
  </entry>
</feed>
