<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Attilan Software: C#, .NET, Image Tools for Forms</title>
        <link>http://www.attilan.com/</link>
        <description>Constructing software tools in C#, .NET, and Windows Forms.</description>
        <language>en</language>
        <copyright>Copyright 2008</copyright>
        <lastBuildDate>Mon, 18 Aug 2008 01:11:00 -0800</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title><![CDATA[Cory Doctorow&rsquo;s Little Brother and the Sony PSP as an E-Book Reader]]></title>
            <description><![CDATA[<p></p>  <p></p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/CoryDoctorowsLittleBrothermakesmeturnthe_B0F1/0035_2.jpg"><img title="Cory Doctorow&#39;s Little Brother in Sony PSP Image viewer" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="276" alt="Cory Doctorow&#39;s Little Brother in Sony PSP Image viewer" src="http://www.attilan.com/WindowsLiveWriter/CoryDoctorowsLittleBrothermakesmeturnthe_B0F1/0035_thumb.jpg" width="484" border="0" /></a> </p>  <p>Here's a roundabout story about I've reinvigorated my Sony Playstation Portable, which would not have been possible without Cory Doctorow's excellent novel, <a href="http://craphound.com/littlebrother" target="_blank">Little Brother</a>.</p>  <p>I've been flirting with the Amazon Kindle for months ever since it went on sale.&#160; It's a cool device for a book lover.&#160; Imagine being able to carry around tons of books everywhere you go.&#160; Being able to download a book after reading a review in the Sunday newspaper.&#160; It's fantastic...except for the limitations.&#160; DRM on the books that you download isn't very cool.&#160; I think what really galls me is that Amazon charges for downloading blogs (via RSS) when you can easily get them for free online.&#160; Charging to email/convert documents to the Kindle device is another thing I cannot understand.&#160; Combine all of these things with the high price of the Kindle and I just cannot make that purchase.</p>  <p>Which made me turn to my Sony Playstation Portable.&#160; I've let this device languish for the past two years after I stopped commuting to San Francisco on BART.&#160; In the back of my mind, I've had this idea that the PSP, with it's brilliant screen display and brightness controls, could be a great e-book reader.&#160; After visiting Cory Doctorow's <a href="http://craphound.com/littlebrother/download/" target="_blank">Little Brother download page</a>, where he provides the novel in a variety of formats (under Creative Commons license), I finally decided to give it a try and see if one of those would work on the PSP.</p>  <p>The result is that none of them worked that well.&#160; It's amazing that after being first sold in 2005 in North America, the Sony PSP still does not have an Adobe PDF Reader.&#160; I found one that used to work, but apparently not on firmware 4.05.&#160; I suppose I could have gotten that to work if I flashed the PSP with a hacked set of firmware, but I want to keep up with the official builds from Sony, as I have a Playstation 3 and want to use my PSP in conjunction with that.&#160; </p>  <p>Next, I tried the HTML version of Little Brother, which I copied over to the PSP/COMMON folder and pointed the PSP's browser at that location.&#160; The HTML version looked superb, the text was very readable, and you can increase/decrease the text size very easily.</p>  <p>However, there were some problems with reading books in HTML format on the PSP.&#160; Paging/scrolling to see the next page is a pain, when you must use the arrow keys on the left hand side of the device.&#160; If the entire book is in one HTML file, you cannot jump between chapters that easily.&#160; When I stopped near Chapter 3, then the next time I started the PSP, I spent a long time scrolling down (using square button + down) to get to that section.&#160; I read that some Sony ebook fans will break up novels into several HTML chunks and link the whole thing together in an index file.&#160; Too much work for me!</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/CoryDoctorowsLittleBrothermakesmeturnthe_B0F1/psp_ebook_creator_2.png"><img title="PSP EBook Creator" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="404" alt="PSP EBook Creator" src="http://www.attilan.com/WindowsLiveWriter/CoryDoctorowsLittleBrothermakesmeturnthe_B0F1/psp_ebook_creator_thumb.png" width="404" border="0" /></a> </p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p>A friend of mine suggested converting the document into a series of JPG files and using the Sony PSP Photo/Image viewer.&#160; I was really dubious about this until I found the <a href="http://www.download.com/Psp-Ebook-Creator/3000-2125_4-10499628.html" target="_blank">PSP EBook Creator on download.com</a>.&#160; What the heck, I decided to give it a shot.&#160; The PSP E-book Creator takes a text file file as the input/source, parses it and creates a series of JPG images.&#160; It gives you a number of options for formatting the text: you can choose the font that you want, the font color, the background color, etc.&#160; It may take a while to determine the best font to read on the PSP screen, I've found that either Arial or Verdana works best for me.</p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p>The e-book creator parsed and split the Little Brother source text into 897 jpg files, which I copied over to the PSP's PHOTO folder, under a subfolder called LB.&#160; When I turn on the PSP, I simply navigated to the Photo slot, select Memory Stick, select the LB folder, select page 1 and pressed X.&#160; Voila, the first page appears and it's easily readable.&#160; To go to the next page, you just press the right shoulder button on top of the PSP.&#160; The PSP can easily be held in one hand with a finger resting on the next button to advance pages.&#160; The left shoulder button allows you to go to the previous page.</p>  <p>Several things are great about this.&#160; Little Brother took up about 40 mb on my Sony Memory stick, which is pretty small.&#160; Having the book split up into X number of jpgs allows you to quickly find the last page you were on: just press the down arrow to scroll down quickly to page 222 or whatever.&#160; The Sony PSP has a brightness control on the front that allows you to see the screen during the daytime or at night.&#160; This is really convenient if you're reading in bed and don't want to disturb your partner with a bright screen--the lowest brightness level works perfectly in total darkness.&#160; You have no idea how long I've searched for a solution to this problem!&#160; </p>  <p>What are the disadvantages of this method?&#160; There are two big ones.&#160; You can't customize the text size dynamically, and the glassy Sony PSP screen is not readable outdoors in the sunlight, due to the glare bouncing off the screen.&#160; I usually read indoors, so this is not a problem for me.</p>  <p>Unlike the Kindle, where finding/downloading books is a breeze, finding content to download and convert is a challenge, as not every author is as generous as Cory Doctorow.&#160; But if you're used to downloading other media, you can find content to use with the PSP E-Book Creator, although usually the content will need to be converted to text.&#160; You can look for books that are in RTF or HTML format and convert to text using a number of programs (Internet Explorer, Firefox, Microsoft Word, etc).&#160; Books in PDF file format can also be converted to text.&#160; You can also find books in the Microsoft Reader format (.LIT files), and use the free <a href="http://www.processtext.com/abclit.html" target="_blank">ABC Amber LIT Converter program</a> to convert them.</p>  <p>I've got about a dozen books, many of them recent books that I purchased in hardback (plus all of Doctorow's other novels), on my Sony PSP.&#160; I bought a SanDisk 4 GB memory stick for about $40 on Amazon to hold this content, along with 12 episodes of LOST and a number of comic books that I want to read on my next vacation.&#160; With all this content available, playing games on the PSP seems like a bonus feature.</p>  <p>Little Brother is a very engaging book, I devoured it in a couple of days after getting on my PSP.&#160; Little Brother is a young adult novel (although just as good for adults) about a high school kid named Marcus Yallow (aka w1n5t0n) in San Francisco. San Francisco is attacked by terrorists and the Department of Homeland Security swoops in and starts heavily monitoring all citizens. Marcus fights back against the DHS by hacking his Xbox with an operating system called &quot;Paranoid Linux&quot; and inspiring a group of young techno-geeks to help him out.&#160; I highly recommend it.</p>  <p>Link: <a href="http://www.download.com/Psp-Ebook-Creator/3000-2125_4-10499628.html" target="_blank">PSP E-Book Creator</a></p>  <p>Link: <a href="http://www.processtext.com/abclit.html" target="_blank">ABC Amber Lit Converter</a></p>  <p>Link: <a href="http://craphound.com" target="_blank">Cory Doctorow's Craphound</a></p>  <p>Link: <a href="http://craphound.com/littlebrother/" target="_blank">Little Brother site</a></p>  <p>Download: <a href="http://www.attilan.com/downloads/little_brother_psp.zip" target="_blank">Little Brother for Sony PSP (Image files, zipped).</a></p>]]></description>
            <link>http://www.attilan.com/2008/08/cory-doctorows-little-brother.php</link>
            <guid>http://www.attilan.com/2008/08/cory-doctorows-little-brother.php</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Cory Doctorow</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Little Brother</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Sony PSP</category>
            
            <pubDate>Mon, 18 Aug 2008 01:11:00 -0800</pubDate>
        </item>
        
        <item>
            <title>Crystal Image Toolkit 0.81: Header Groups for Image Thumbnail Grid View</title>
            <description><![CDATA[<p><strong>Crystal Image Toolkit 0.81</strong> is ready to <a href="http://www.attilan.com/downloads/Crystal_Toolkit_081.zip" target="_blank">download</a>. </p>  <p><strong>New Feature</strong>: Header group items are now part of <strong>CrystalCollector, CrystalImageGridModel, and CrystalImageGridView</strong>.&#160; You can now assign a group of thumbnail images to a collapsible header.&#160; To illustrate this, here’s a screenshot from the demo application “HeaderGroupItemDemo” which is included in the project:</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/Cry.81HeaderGroupsforImageThumbnailGridV_143D0/HeaderGroupItem1_2.png"><img title="HeaderGroupItem1" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="592" alt="HeaderGroupItem1" src="http://www.attilan.com/WindowsLiveWriter/Cry.81HeaderGroupsforImageThumbnailGridV_143D0/HeaderGroupItem1_thumb.png" width="671" border="0" /></a> </p>  <p>There are four header groups visible that you can see here (FF, Hulk, Iron Man, Spider-Man).&#160; Each contains a set of thumbnails.&#160; The arrow icon indicates the expanded state; you can replace this icon in the framework as I am just using a free icon here.&#160; Likewise you can replace the folder icon to represent something unique about this group of images if you wish.&#160; But what’s important to note here is that the header group can be collapsed/expanded by clicking on it:</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/Cry.81HeaderGroupsforImageThumbnailGridV_143D0/HeaderGroupItemCollapsed_2.png"><img title="HeaderGroupItemCollapsed" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="455" alt="HeaderGroupItemCollapsed" src="http://www.attilan.com/WindowsLiveWriter/Cry.81HeaderGroupsforImageThumbnailGridV_143D0/HeaderGroupItemCollapsed_thumb.png" width="671" border="0" /></a> </p>  <p>Here I’ve collapsed two of the header items and left the other ones open.&#160; You can see I have CrystalImageItem objects selected in each of the header groups.</p>  <p>In the C# code, Header groups translates to a CrystalGroupItem object containing a List of CrystalImageItem objects.&#160; Each object now has a Parent property so it knows the group that it belongs to.&#160; The biggest change in the collector is that now every GridModel has at least one root header. In the default mode, for backward compatibility, the header item is not displayed (ShowHeaders is set to false in CrystalImageGridView). This may cause problems in older applications that use CrystalImageGridView and try to navigate to item 0 in the GridModel.&#160; You will need to do a test, such as: &quot;if (theImage is CrystalGroupItem)&quot;.&#160; See InitInitialImageImp in CrystalPictureShowController.cs for how to deal with this situation.</p>  <p>CrystalCollector now has an additional abstract method that requires you to CollectImages on a CrystalGroupItem object.&#160; CrystalFileCollector implements this method and creates a default root header for simplicity.&#160; But if you want to explicitly create CrystalGroupItem objects and add them to the collector, you do it like this:</p>  <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">   <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">     <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> CrystalGroupItem groupItem = <span style="color: #0000ff">new</span> CrystalGroupItem();</pre>

<p>    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> groupItem.ImageName = <span style="color: #006080">&quot;Fantastic Four&quot;</span>;</pre></p>

<p>    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> groupItem.ImageLocation = <span style="color: #006080">&quot;..\\..\\SampleImages\\Fantastic Four&quot;</span>;</pre></p>

<p>    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #008000">// Optional: set a unique image icon for this group header item in the image grid.</span></pre></p>

<p>    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> <span style="color: #008000">//groupItem.FullImage = my Image icon;</span></pre></p>

<p>    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span> _theCollector.CollectImages(groupItem);</pre><br />
  </div><br />
</div></p>

<p>This is a bit of an early release of the header group feature.&#160; In the future, I will add additional style bits for the header text font, add a border state around the header item, perhaps add mouse over events for it.</p>

<p>There are several bug fixes to the toolkit, which is why I wanted to release it now, even though this feature is a bit early.&#160; To see all the bug fixes, please read the release notes in the zip file.</p>

<p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_081.zip" target="_blank">Crystal Image Toolkit 0.81</a>.&#160; Totally free, open-source, C# .NET Framework 2.0 for Windows Forms.</p>]]></description>
            <link>http://www.attilan.com/2008/07/crystal-image-toolkit-081-head.php</link>
            <guid>http://www.attilan.com/2008/07/crystal-image-toolkit-081-head.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Downloads</category>
            
            
            <pubDate>Wed, 30 Jul 2008 23:02:00 -0800</pubDate>
        </item>
        
        <item>
            <title>Crystal Image Toolkit 0.80: Thumbnail scaling, Image tracking in C# .Net</title>
            <description><![CDATA[<p>Crystal Image Toolkit 0.80 is ready to <a href="http://www.attilan.com/downloads/Crystal_Toolkit_080.zip" target="_blank">download</a>.&#160; </p>  <p>New Features:</p>  <ul>   <li>CrystalImageGridView now has ZoomFactor: allows scaling of thumbnail images!     <br />See ZoomImageGrid demo and Crystal Picture Show Controller demo. </li>    <li>CrystalPictureTracker: Pan Window that works with CrystalPictureShow.     <br />See Crystal Picture Show Controller demo. </li>    <li>CrystalPictureShow: Hand cursors that allow the user to drag zoomed images around. </li>    <li>CrystalImageGridView now has a new rounded rect border style.&#160; Check out the groovy red borders in the Picture Show Controller demo.</li>    <li>Crystal Toolkit now integrates <a href="http://logging.apache.org/log4net/index.html" target="_blank">log4net</a>.&#160; See CrystalLogger object.      <br />You can get even more debug logging by declaring CRYSTAL_DEBUG in project properties/build.</li> </ul>  <p>And now it's demo time, with Marvel comics pictures, of course:</p>  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="470" alt="CrystalImageGridView using ZoomFactor to scale thumbnails" src="http://www.attilan.com/WindowsLiveWriter/CrystalImageToolkit0.80Thumbnailscal.Net_1B5F/CrystalPicDemo_thumb_zooming_3.png" width="700" border="0" /></p>  <p><strong>CrystalImageGridView: ZoomFactor</strong> applied to zoom to a larger thumbnail image.&#160; <a href="http://www.attilan.com/2008/05/scaling-thumbnail-images-with.php">See my earlier article</a> that explains how to set this up.&#160; Changes were made to CrystalPictureShowController to add a second trackbar object to control thumbnail zooming.&#160; </p>  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="528" alt="CrystalPictureTracker working with CrystalPictureBox" src="http://www.attilan.com/WindowsLiveWriter/CrystalImageToolkit0.80Thumbnailscal.Net_1B5F/CrystalPicDemo_tracker_window_3.png" width="700" border="0" /> </p>  <p><strong>CrystalPictureTracker: Panning</strong> (controlling CrystalPictureBox) in separate window.&#160; Tracker window appears when image is larger than client area.&#160; You can close it, make it appear again by clicking on the Pan Window button.</p>  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="525" alt="Red rounded borders" src="http://www.attilan.com/WindowsLiveWriter/CrystalImageToolkit0.80Thumbnailscal.Net_1B5F/CrystalPicDemo_roundrect_3.png" width="700" border="0" /> </p>  <p><strong>CrystalImageGridView: Rounded borders on selected images.</strong>&#160; There is now a property called <strong>BorderState</strong> that allows you to switch between these rounded borders and the old square frame.&#160; Also, notice that in the split view mode, the CrystalPictureShowController hides the thumbnail trackbar and toolstrip objects auto-magically.&#160;&#160; Thumbnail sizes in the split mode are fixed, whereas in the vertical orientation (with a sheet of thumbnails) they can be scaled.</p>  <p>This release comes in a ZIP file. Simply unzip the contents to your hard drive, navigate to the root Attilan folder, and double click on <strong>CrystalDemo.sln</strong>. This solution file contains the Crystal Toolkit plus demo programs. Just build the solution (which compiles the CrystalToolkit library first) and run the demo programs to see how they work. You can run the demo programs without building the source by clicking on &quot;<strong>StartDemo.bat</strong>&quot; in the root Attilan folder or <strong>CrystalDemoLauncher.exe</strong> in Attilan\bin.</p>  <p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_080.zip" target="_blank">Crystal Image Toolkit 0.80</a>.&#160; Totally free, open-source, C# .NET Framework 2.0 for Windows Forms.&#160; </p>]]></description>
            <link>http://www.attilan.com/2008/05/crystal-image-toolkit-080-thum.php</link>
            <guid>http://www.attilan.com/2008/05/crystal-image-toolkit-080-thum.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Downloads</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalImageGridView</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalPictureBox</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalPictureTracker</category>
            
            <pubDate>Tue, 27 May 2008 20:07:03 -0800</pubDate>
        </item>
        
        <item>
            <title>Scaling Thumbnail Images with C# WinForms, CrystalImageGridView</title>
            <description><![CDATA[<p>I haven't posted any articles here for quite a while.&#160; You might think I've given up on the Crystal Toolkit, but not yet!&#160; I've been making various improvements, bug fixes, and enhancements.&#160; It's slowly getting better.&#160; Probably by the time I am done, Windows Forms will be dead!</p>  <p>Here's a big feature, coming very soon in <a href="http://www.attilan.com/2008/05/crystal-image-toolkit-080-thum.php">Crystal Toolkit 0.80</a>, that I've wanted for my own image viewing programs: zooming the thumbnail images that are contained within CrystalImageGridView.&#160; Previously I was only able to allow users to set the CellSize property and that was it.&#160; If you had a thumbnail image that was 300 x 300, you were stuck with that until you changed that property and had the internal grid recalculate itself.&#160; It might have worked, but the images would all have to be re-thumbnailed at that new size, and a lot of time would be wasted.</p>  <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">   <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">     <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #008000">/// &lt;summary&gt;</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #008000">/// Sets up the Matrix object used for displaying the image.</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> <span style="color: #008000">/// &lt;/summary&gt;</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #008000">/// &lt;param name=&quot;gfx&quot;&gt;Graphics object used for drawing.&lt;/param&gt;</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> <span style="color: #008000">/// &lt;param name=&quot;zoomScale&quot;&gt;Scale used for matrix.&lt;/param&gt;</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span> <span style="color: #0000ff">protected</span> <span style="color: #0000ff">virtual</span> <span style="color: #0000ff">void</span> SetupMainImageMatrix(Graphics gfx, <span style="color: #0000ff">float</span> zoomScale)</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span> {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>     gfx.ResetTransform();</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>&#160; </pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>     <span style="color: #008000">// Set up the transformation to handle zooming and panning.</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>     Matrix mx = <span style="color: #0000ff">new</span> Matrix();</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>&#160; </pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>     <span style="color: #008000">// Account for the scroll position.</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>     mx.Translate(AutoScrollPosition.X, AutoScrollPosition.Y);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>&#160; </pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span>     <span style="color: #008000">// Account for the zoom factor.</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span>     mx.Scale(zoomScale, zoomScale);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span>&#160; </pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span>     <span style="color: #008000">// Set the transform into the global transform for the specified Graphics context.</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span>     gfx.Transform = mx;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  21:</span>&#160; </pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  22:</span>     <span style="color: #008000">// Set the interpolation mode.</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  23:</span>     gfx.InterpolationMode = _interpolationMode;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  24:</span> }</pre>
  </div>
</div>

<p>To make thumbnail scaling work in the new release, I've taken some code and patterns found in <strong>CrystalPictureBox</strong>.&#160; In that class, I used a Matrix object and set the scale according to a property I called <strong>ZoomFactor</strong>.&#160; This enabled me to present an image in <strong>CrystalPictureBox</strong> at any scale I desired, like from 30% of full size to 300% of full size.</p>

<p><strong>CrystalImageGridView</strong> now has a property called <strong>ZoomFactor</strong>.&#160; Using this, the entire grid can be displayed at a percentage of the full sized grid.&#160; To implement an image grid that goes from small images to medium images to large images, you would just set the <strong>ZoomFactor</strong> in the image grid, and the object takes care of the rest.</p>

<p>How it works: </p>

<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="374" alt="Setting up CrystalImageGridView for large thumbnails" src="http://www.attilan.com/WindowsLiveWriter/ZoomingThumbnailImageswithCCrystalImageG_CEC5/ZoomFormSetting_3.png" width="604" border="0" /> </p>

<p>First, setup a Form and drop the <strong>CrystalImageGridView</strong> onto the form.&#160; Set the <strong>CellSize</strong> property to the largest possible size that you wish to display.&#160; In this case, I chose a cell size of 375 x 375.&#160; If you set it up this way, the thumbnailer object (internal to the grid) will make thumbnail images at this size, providing users with a crisp view.&#160; It's easier to downscale a larger image than it is to upscale a smaller image.&#160; Now, an alternative way to do this could have been a different pattern--where we send out a signal that we are changing the size and thumbnail the viewable images on the spot.&#160; Windows Explorer and several other programs do this.&#160; Perhaps in the future I will provide an alternative method like this.&#160; The advantage of this method is that the image scaling is pretty fast.&#160; The disadvantage is that the thumbnailed image requires more disk space at the largest possible size.</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">float</span>[] zoomFactor = { .30f, .45f, .60f, .75f, .90f, 1.0f };</pre>
  </div>
</div>

<p>The <strong>ZoomFactor</strong> property is set by a trackbar in my little example program (which will be in Crystal Toolkit 0.80).&#160; The zoom factors are predefined in array.&#160; At the lower end of the scale (represented by setting the trackbar all the way to the left) we have 30% of the full size 375x375, which is 125x125.&#160; At the upper end, we have 100% of the thumbnail size.&#160; There is a trackbar on the form with Minimum set to 0 and Maximum set to 5, to match the settings in the array.</p>

<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="516" alt="CrystalImageGridView with ZoomFactor at 30%" src="http://www.attilan.com/WindowsLiveWriter/ZoomingThumbnailImageswithCCrystalImageG_CEC5/ZoomDemo_125_6.png" width="700" border="0" />&#160; </p>

<p>When the program is launched, the default ZoomFactor is set to 0.30 (125x125).&#160; I've got about 24 thumbnails displaying here.&#160; Notice how the text for the image is still visible at this 30% setting, this was actually the trickiest part of the whole deal (and there may be bugs left to find in that regard).&#160; OK, I've got the Hulk selected in the middle of the screen, keep an eye on him.</p>

<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="513" alt="CrystalImageGridView with ZoomFactor at 50%" src="http://www.attilan.com/WindowsLiveWriter/ZoomingThumbnailImageswithCCrystalImageG_CEC5/ZoomDemo_50_3.png" width="700" border="0" /> </p>

<p>Here the ZoomFactor is set close to 50%.&#160; The grid has repositioned the images as the ZoomFactor increased in size.&#160; The Hulk remains selected, in the center of the grid so that the user can view his beautiful face.&#160; Is that a booger in his hose?&#160; Let's zoom it up further.</p>

<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="516" alt="CrystalImageGridView with ZoomFactor at 100%" src="http://www.attilan.com/WindowsLiveWriter/ZoomingThumbnailImageswithCCrystalImageG_CEC5/ZoomDemo_100_3.png" width="700" border="0" /> </p>

<p>Finally, here's what the CrystalImageGridView looks like with the ZoomFactor at 100% (375x375).&#160; We've got two images side by side, the Hulk is still selected and viewable.&#160; And it's not a booger, it's this wild Marvel character called Ant-Man, making a quick exit from the Hulk's gamma irradiated body.</p>

<p>With good luck, I should be posting Crystal Toolkit 0.80 with this feature this Memorial Day.&#160; Nuff said.</p>]]></description>
            <link>http://www.attilan.com/2008/05/scaling-thumbnail-images-with.php</link>
            <guid>http://www.attilan.com/2008/05/scaling-thumbnail-images-with.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Windows Forms</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalImageGridView</category>
            
            <pubDate>Fri, 23 May 2008 15:10:52 -0800</pubDate>
        </item>
        
        <item>
            <title>SVN, Windows Vista, and mysterious closed connections</title>
            <description><![CDATA[<p>Ever had one of those days when you spent fighting with your operating system when you should have been getting real work done?  I just had one of them.  My computer at home is much faster and better equipped to do development work than my work laptop.  We use SVN for source code control.  For SVN client access, we use <a href="http://www.syntevo.com/smartsvn/index.html">SmartSVN from SyntEvo</a>.  After setting up our repository URL in the SmartSVN, I was able to browse our repository folder structure, and begin to check out a project.  But after retrieving a few files, it would crap out with errors like "<strong>connection closed</strong>" or "<strong>svn: null</strong>".</p>

<p>When things like this go wrong, most people would just give up or go back to the laptop.  But this is the sort of the thing that makes me crazy until I find out what the problem is.  I had my laptop--which worked with the same SVN settings on my home network.  The difference was the work laptop was Windows XP SP 2--and my home desktop computer was Windows Vista.  A-ha!  Windows Firewall?  Turned it off, same thing.  McAfee Virus Scan?  Uninstalled it, same thing.  DLink router?  Disabled the firewall, allow network access, same thing.</p>

<p>Searched SmartSVN forums--no answer.  Tried TortoiseSVN--same problem.  Tried another product called Syncro SVN--again, same behavior.  I'm falling further behind on my deadline, when I give up and write to our terrific IT captain from <a href="http://www.ancientgeek.com/">Ancient Geek</a> that he was right--Vista sucks.</p>

<p>Luckily, I did, because he told me what the real problem was--the TCP/IP auto tuning feature that Vista has.  According to this article at ChapterZero:</p>

<p><em>Microsoft Windows Vista has auto-tuning enabled for TCP/IP which continually adjusts itself. It increases file transfer speed on the network but in some cases it may actually slow down everything which is accessing network. Auto-tuning also slows down network browsing of other machines on the network.</em></p>

<p>It's easy to check and see what your current TCP/IP receive tuning level is.  Open up a CMD window with admin priviliges and type:</p>

<p><strong>netsh interface tcp show global</strong></p>

<p>Then if it's on and you want to turn it off:</p>

<p><strong>netsh interface tcp set global autotuning=disabled</strong></p>

<p>More detailed steps are given for this at <a href="http://www.speedguide.net/faq_in_q.php?qid=247">SpeedGuide</a>.</p>

<p>No wonder I drove myself nuts.  I kept searching and searching for anything network related in the Control Panel and it wasn't there.  Now that I've disabled this feature, both SmartSVN and TortoiseSVN are working fine.  Thank you, <a href="http://www.ancientgeek.com/">Ancient Geek</a>!<br />
</p>]]></description>
            <link>http://www.attilan.com/2007/12/svn-windows-vista-and-mysterio.php</link>
            <guid>http://www.attilan.com/2007/12/svn-windows-vista-and-mysterio.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Windows Vista</category>
            
            
            <pubDate>Sun, 02 Dec 2007 21:10:55 -0800</pubDate>
        </item>
        
        <item>
            <title>Transparent Color in C# control: Bug fix details</title>
            <description><![CDATA[<p>I thought it might be interesting to document the recent code modifications to CrystalGradientControl to allow sub-classes (CrystalLabel and CrystalPictureBox) to have transparent backgrounds.</p>

<p>As most Windows Forms programmers know, setting the BackColor to Transparent is the way to allow transparent backgrounds in most controls.  I wanted to support the same convention.  However, setting the BackColor to Transparent result in a nasty message ("Control does not support transparent background colors").  To fix this, I had to call SetStyles to declare that my color does support transparency:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> CrystalGradientControl()
{
  SetStyle(ControlStyles.SupportsTransparentBackColor, 
           <span class="kwrd">true</span>);
}</pre>

<p>Next, I wanted to override the property (from the base class Control), BackColor.  Why?  Because when BackColor is set to Transparent, I needed to set an internal property called TransparentMode to True.  TransparentMode triggers a number of things best described on <a href="http://www.bobpowell.net/transcontrols.htm">Bob Powell's article on transparent controls</a>.  This was all I needed to do:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">override</span> Color BackColor
{
    get
    {
        <span class="kwrd">return</span> <span class="kwrd">base</span>.BackColor;
    }
    set
    {
        <span class="kwrd">if</span> (<span class="kwrd">base</span>.BackColor != <span class="kwrd">value</span>)
        {
          <span class="kwrd">base</span>.BackColor = <span class="kwrd">value</span>;
          TransparentMode = 
            (<span class="kwrd">base</span>.BackColor == Color.Transparent);
          <span class="kwrd">this</span>.InvalidateEx();
        }
    }
}</pre>

<p>Now my controls allowed the transparent color, but the background was still getting painted black.  Why?  Because in my override of OnPaintBackground, I needed to call the base class when TransparentMode was set to true, to allow the parent Form to repaint the background:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnPaintBackground
                    (PaintEventArgs pevent)
{
    <span class="kwrd">if</span> (TransparentMode)
    {
        <span class="kwrd">base</span>.OnPaintBackground(pevent);
        <span class="kwrd">return</span>;
    }

    PaintGradientBackground(pevent.Graphics);
}
</pre>

<p>There you have it, a few simple fixes.  When I first started this toolkit, I didn't know how programmers set the transparent color.  I made a mistake in having the TransparentMode property be public and totally ignoring BackColor.  Now I've hidden TransparentMode from the Forms designer and allow programmers to do it the traditional way.</p>]]></description>
            <link>http://www.attilan.com/2007/07/transparent-color-in-c-control.php</link>
            <guid>http://www.attilan.com/2007/07/transparent-color-in-c-control.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET Framework</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalGradientControl</category>
            
            <pubDate>Mon, 09 Jul 2007 01:11:11 -0800</pubDate>
        </item>
        
        <item>
            <title>Transparent CrystalLabel and CrystalPictureBox</title>
            <description><![CDATA[<p>CrystalLabel and CrystalPictureBox were not allowing Transparent backgrounds.  This is a bug that was fixed in <a href="http://www.attilan.com/2007/07/crystal_toolkit_alpha_release_10.php">Crystal Toolkit version 0.77</a>.  I have to admit that I am more focused on the gradient properties of these controls--doing the transparency thing was a side experiment.  I've been tempted to drop the transparent mode altogether (and I have done that in CrystalTrackBar, which has numerous problems).  However, I found a pretty simple fix to allow the Label and PictureBox controls to retain a transparent background.</p>

<p>How do you set these controls to have a Transparent background?  By default, you have the gradient mode set when you drag CrystalLabel and CrystalPictureBox onto your form:</p>

<p><img alt="gradient_control.jpg" src="http://www.attilan.com/gradient_control.jpg" width="450" height="341" /></p>

<p>To attain this gradient setting, you need to have BackColor set to Control, and then Color1 and Color2 make up the gradient blend of colors:</p>

<p><img alt="gradient_control_setting.jpg" src="http://www.attilan.com/gradient_control_setting.jpg" width="266" height="258" /></p>

<p>Now, if you want the Transparent background, simply set BackColor to Transparent (on the Web tab of the color property dialog).  This is the standard way to set transparency with other .NET controls.  When I started this toolkit, I was ignorant of that fact.  Internally within the CrystalGraidentControl class, setting BackColor to Transparent makes the TransparentMode property true.</p>

<p><img alt="transparent_control_setting.jpg" src="http://www.attilan.com/transparent_control_setting.jpg" width="269" height="249" /></p>

<p>The end result is that both the CrystalLabel and CrystalPictureBox controls have a transparent background and allow the wallpaper in the form to show through.  This sample code is in the <a href="http://www.attilan.com/2007/07/crystal_toolkit_alpha_release_10.php">CrystalToolkit 0.77</a>, called TestAttilanTransparent.</p>

<p><img alt="transparent_control.jpg" src="http://www.attilan.com/transparent_control.jpg" width="450" height="342" /><br />
</p>]]></description>
            <link>http://www.attilan.com/2007/07/transparent-crystallabel-and-c.php</link>
            <guid>http://www.attilan.com/2007/07/transparent-crystallabel-and-c.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalLabel</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalPictureBox</category>
            
            <pubDate>Sun, 08 Jul 2007 13:20:55 -0800</pubDate>
        </item>
        
        <item>
            <title>Crystal Toolkit: Alpha Release 0.77</title>
            <description><![CDATA[<p>Crystal Toolkit is a Windows Forms (.NET Framework 2.0) control library written in C#. This is the eighth release and contains the following updates:</p>
<p><strong><span style="TEXT-DECORATION: underline">Bug fixes.</span></strong></p>
<ol>
<li>
<p><strong>CrystalGradientControl-derived classes, including CrystalLabel and CrystalPictureBox (but not CrystalTrackBar)</strong>: Transparent backgrounds were not working previously.  To set a transparent background, set BackColor property to the Transparent color.  You can do this in design mode or programmatically. This makes TransparentMode=True.  When this occurs, Color1 and Color2 are ignored.  To get the Gradient color mode to work, set BackColor back to Control (or any other non-Transparent value) and then set Color1 and Color2 to the Gradient color scheme.</p>
</li>
<li>
<p><strong>CrystalThumbnailer:</strong> Exceptions are now caught when an error occurs when thumbnailing images.
</li>
<li>
<p><strong>CrystalImageGridView:</strong> Bug fixes for keyboard navigation. When images were selected and right-mouse click inside the middle of the selection, the selected image list is retained.
</li>
</ol>
<p>This release comes in a ZIP file. Simply unzip the contents to your hard drive, navigate to the root Attilan folder, and double click on <strong>CrystalDemo.sln</strong>. This solution file contains the Crystal Toolkit plus demo programs. Just build the solution (which compiles the CrystalToolkit library first) and run the demo programs to see how they work. You can run the demo programs without building the source by clicking on "<strong>StartDemo.bat</strong>" in the root Attilan folder or <strong>CrystalDemoLauncher.exe</strong> in Attilan\bin.</p>
<p>I've tested the demos under Windows XP SP2 and Windows Vista. Needless to say, buyers beware, this is alpha software and it's free open-source code: you get what you pay for! I'd welcome any feedback, bugs (or bug fixes), and thumb-bitmap replacements. Send email to richard [at] attilan {dot} com.</p>
<p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_077.zip">Crystal Toolkit 077 (zip file, 8 mb)
<br/></a></p>
]]></description>
            <link>http://www.attilan.com/2007/07/crystal-toolkit-alpha-release-10.php</link>
            <guid>http://www.attilan.com/2007/07/crystal-toolkit-alpha-release-10.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Downloads</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalImageGridView</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalLabel</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalPictureShow</category>
            
            <pubDate>Sun, 08 Jul 2007 12:54:47 -0800</pubDate>
        </item>
        
        <item>
            <title>Crystal Toolkit: Alpha Release 0.76</title>
            <description><![CDATA[<p>Crystal Toolkit is a Windows Forms (.NET Framework 2.0) control library written in C#. This is the eighth release and contains the following updates:</p>
<p><strong><span style="TEXT-DECORATION: underline">New features.</span></strong></p>
<ol>
<li>
<p><strong>CrystalPictureShowController</strong>: Allows you to tie the common elements of an image viewing application in one controller.  Create a form with CrystalImageGridView, CrystalPictureShow, a combo box and trackbar for image scaling, toolbar buttons for navigation.  Set all these elements in the controller and you are off and running.  You still need to handle the split container and certain events (like initiating and terminating full screen modes) but the sample program below will show you how to do that.</p>
<p><strong>CrystalComicShowController</strong>: Allows you to tie the common elements of a comic book viewing (reading CBZ or CBR archive files) application in one controller.  This may be the first C# toolkit designed to allow you to read <a href="http://en.wikipedia.org/wiki/CDisplay">CDisplay</a> compatible files.  Create a form with CrystalImageGridView, CrystalComicShow, a combo box and trackbar for image scaling, toolbar buttons for navigation.  Set all these elements in the controller and you are off and running.  The internal framework uses CrystalMemoryZipCollector for CBZ files and CrystalRarCollector for CBR files.</p>
</li>
</ol>
<p><strong><span style="TEXT-DECORATION: underline">Enhancements.</span></strong></p>
<ol>
<li>
<p><strong>CrystalCollector</strong>: Virtual methods moved from CrystalFileCollector to the base class.  Sorting methods, Copy, Move, Delete, Rename, Select operations are moved here so that all derived classes can use them.</p>
<p><strong>CrystalImageGridView</strong>: <strong>FocusedImage </strong> property added - returns the current focused image.  <strong>CenterCrystalImage</strong> public method added - centers the given image in the grid.</p>
</li>
</ol>
<p><strong><span style="TEXT-DECORATION: underline">Demo Programs Expanded.</span></strong></p>
<ol>
<li>
<p><strong>CrystalPictureShowController Demo</strong>: shows how to use the new controller to quickly develop an image grid viewer.  This sample also shows you how to put the main form into a menuless, toolbarless, fully zoomed mode that takes over the entire screen.  Just click on the Full Screen button.  The Slideshow mode has been expanded to include an options dialog to allow you to set certain options like Shuffle, Repeat, or SlideShow effect.</p>
</li>
<li>
<p><strong>CrystalComicShowController Demo</strong>: shows how to use the new controller, and in an indirect way, how to use CrystalToolkit to pull images out of compressed files.  To get the full benefit of this demo, you will need to have a CBR or CBZ file on your hard drive.  Run the demo program, click File\Open Comic Archive and open up the CDisplay compatible file.  You should see the thumbnails start to appear and then the app zooms into full screen mode.  Press ESC and you will see the sheet of thumbnails representing the comic book pages.</p>
</li>
</ol>
<p><strong><span style="TEXT-DECORATION: underline">Bug fixes.</span></strong></p>
<ol>
<li>
<p><strong>CrystalImageGridView</strong>: Right-mouse button no longer clears item selection.</p>
</li>
</ol>
<p>This release comes in a ZIP file. Simply unzip the contents to your hard drive, navigate to the root Attilan folder, and double click on <strong>CrystalDemo.sln</strong>. This solution file contains the Crystal Toolkit plus demo programs. Just build the solution (which compiles the CrystalToolkit library first) and run the demo programs to see how they work. You can run the demo programs without building the source by clicking on "<strong>StartDemo.bat</strong>" in the root Attilan folder or <strong>CrystalDemoLauncher.exe</strong> in Attilan\bin.</p>
<p>I've tested the demos under Windows XP SP2 and Windows Vista. Needless to say, buyers beware, this is alpha software and it's free open-source code: you get what you pay for! I'd welcome any feedback, bugs (or bug fixes), and thumb-bitmap replacements. Send email to richard [at] attilan {dot} com.</p>
<p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_076.zip">Crystal Toolkit 076 (zip file, 7 mb)
<br/></a></p>
]]></description>
            <link>http://www.attilan.com/2007/05/crystal-toolkit-alpha-release-9.php</link>
            <guid>http://www.attilan.com/2007/05/crystal-toolkit-alpha-release-9.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Downloads</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalComicShow</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalPictureShow</category>
            
            <pubDate>Sun, 13 May 2007 01:11:11 -0800</pubDate>
        </item>
        
        <item>
            <title>New Samples Illustrate How to Create Image Grid Viewers</title>
            <description><![CDATA[
<p>I added 4 new samples to the current <a href="http://www.attilan.com/2007/04/crystal_toolkit_alpha_release_8.php">Crystal Toolkit 0.75 release</a>, and cleaned up some of the old ones. First of all, I think it's important when users open a toolkit that they can see some sample programs right off the bat without compiling the code. I've placed a bin folder under the root Attilan, which contains the CrystalToolkit.dll and the sample programs. If you click on StartDemo.bat under Attilan or CrystalDemoLauncher under Attilan\bin, you will see the CrystalDemoLauncher program:</p>
<p><a href="http://www.attilan.com/117714369192.jpg"><img src="http://www.attilan.com/117714369192_tn.jpg" style="DISPLAY: inline; WIDTH: 500px; HEIGHT: 375px" title="Demo Launcher with Crystal Panel" height="375" width="500" alt="Demo Launcher with Crystal Panel" border="0" id="117714369192.jpg"/></a></p>
<p>The gradient background in the demo launcher is provided by CrystalPanel. I've been using this in many applications and it always helps make a Windows Forms program a bit more attractive. I think it looks even better when paired with the <a href="http://www.componentfactory.com/" target="_blank">KryptonLabel and KryptonLinkLabel controls at Component Factory</a>.</p>
<p>I wanted to provide a minimal program that shows how CrystalImageGridView works. The SimpleImageGridView demo program has about 140 lines of code in Form1.cs. This sample merely looks at your MyPictures folder and thumbnails all the images within it. If you have no images, click on File\Open Folder menu item and select another folder. Here's an example of how it looks--and hold on to your hat--I am going to show you images from actual photographs instead of comic books:</p>
<p><a href="http://www.attilan.com/117714371095.jpg"><img src="http://www.attilan.com/117714371095_tn.jpg" style="DISPLAY: inline; WIDTH: 500px; HEIGHT: 389px" title="SimpleImageGrid Demo with Roxy" height="389" width="500" alt="SimpleImageGrid Demo with Roxy" border="0" id="117714371095.jpg"/></a></p>
<p>This is our part-time labrador-mix, Roxie the Rocket dog. We take care of her when our friends are out of town. We love this dog, but it's the perfect situation because we get to take care of her and we get our own time as well.</p>
<p>I can't just leave this article without doing something comic-book related. Here's a Form that I recently implemented as a demo called WaitFormPictureShow. It's one of those "watch-me-spin while-you-wait" dialog/forms that you look at while the program is processing something. It does use a wonderful loading circle animation control written by Martin Gagne--<a href="http://www.codeproject.com/cs/miscctrl/mrg_loadingcircle.asp" target="_blank">download it here on CodeProject</a>. But in addition to that, there is a postage-stamp sized CrystalPictureShow control displaying images in a Fade Slideshow. I loaded up the images into CrystalMemoryCollector, from a project resource file filled with images from Marvel Value Stamps and DC Comics US Postage Stamps:</p>
<p><a href="http://www.attilan.com/117714374535.jpg"><img src="http://www.attilan.com/117714374535_tn.jpg" style="DISPLAY: inline; WIDTH: 424px; HEIGHT: 182px" title="Wait Form with Picture Show 1" height="182" width="424" alt="Wait Form with Picture Show 1" border="0" id="117714374535.jpg"/></a></p>
<p>The CrystalMemoryCollector loads both the full scale image and the thumbnail image--in this case, the same thing. CrystalPictureShow takes the CrystalMemoryCollector (not knowing anything special about it, other than it is derived from CrystalCollector) and displays the Slideshow using the Fade effect. In the code I've told the CrystalPictureShow object not to use its own thumbnailer, as the memory collector has everything loaded and ready to go:</p>
<p><a href="http://www.attilan.com/117714375626.jpg"><img src="http://www.attilan.com/117714375626_tn.jpg" style="DISPLAY: inline; WIDTH: 424px; HEIGHT: 182px" title="Wait Form with Picture Show 2" height="182" width="424" alt="Wait Form with Picture Show 2" border="0" id="117714375626.jpg"/></a></p>
<p>There you have it. I thnk this could be a nice wait dialog with regular photograph thumbnails if you chose to do so. <a href="http://www.attilan.com/2007/04/crystal_toolkit_alpha_release_8.php">Download the free Crystal Toolkit 0.75</a> if you want to try this kind of wackiness.</p>
]]></description>
            <link>http://www.attilan.com/2007/04/new-samples-illustrate-how-to.php</link>
            <guid>http://www.attilan.com/2007/04/new-samples-illustrate-how-to.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
            
            <pubDate>Sat, 21 Apr 2007 01:29:23 -0800</pubDate>
        </item>
        
        <item>
            <title>Crystal Toolkit: Alpha Release 0.75</title>
            <description><![CDATA[
<p>Crystal Toolkit is a Windows Forms (.NET Framework 2.0) control library written in C#. This is the seventh release and contains the following updates:</p>
<p><strong><span style="TEXT-DECORATION: underline">Enhancements.</span></strong></p>
<ol>
<li>
<p><strong>CrystalCollector</strong>: AddImage and AddImageItem methods allow you to add images without calling CollectImages and having it auto-magically thumbnail images. In using these methods, you pay a price in having to setup things correctly. See the demo program BorderSplitMode for more details about how this is used with CrystalMemoryCollector.</p>
</li>
</ol>
<p><strong><span style="TEXT-DECORATION: underline">Demo Programs Expanded.</span></strong></p>
<ol>
<li>
<p>Demo Launcher program starts all demos. Click on "<strong>StartDemo.bat</strong>" in the root Attilan folder or <strong>CrystalDemoLauncher.exe</strong> in Attilan\bin.</p>
</li>
<li>
<p><strong>Simple Image Grid Demo</strong>: A simple illustration of how to use CrystalImageGridView with the CrystalFileCollector to thumbnail disk-based images in a background thread.</p>
</li>
<li>
<p><strong>BorderSplitMode Demo</strong>: Use CrystalImageGridView and a derived Collector to assign each image item its own border color, <a href="http://www.attilan.com/2007/04/state_colors_with_bordersplitm.php">as I explained here in this article</a>.</p>
</li>
<li>
<p><strong>CrystalPictureBox Demo</strong>: Use CrystalPictureBox to display scrollable or ratio-stretched images.</p>
</li>
<li>
<p><strong>CrystalPictureShow Demo</strong>: Use CrystalImageGridView to navigate thumbnail images and then use CrystalPictureShow to display them and perform Slideshows.</p>
</li>
<li>
<p><strong>WaitForm PictureShow Demo</strong>: Use CrystalPictureShow to create a unique wait dialog.</p>
</li>
</ol>
<p><strong><span style="TEXT-DECORATION: underline">Bug fixes.</span></strong></p>
<ol>
<li>
<p><strong>CrystalTrackBar</strong>: SmallChange and LargeChange were implemented. Control was not behaving properly when nested inside a container like a Panel or GroupBox. I also fixed a bug where the thumb was not able to move between ticks, if you were going from 0 to 10, it would skip to 10. Now it will go 0, 1, 2, 3...10. In fixing CrystalTrackBar, I decided to prohibit TransparentMode. It wasn't working very well. I had no intention of making a TrackBar replacement, my goal was just to get a TrackBar on a ToolStrip. I've taken my old implementation of CrystalTrackBar and placed this into CrystalFixedTrackBar, which is used only by CrystalToolStripTrackBar. I'm afraid the TrackBar component will never be a full replacement in either case, but it works well enough in my Image Viewer application that I'm happy with it.</p>
</li>
<li>
<p><strong>CrystalImageGridView</strong>: UseAlpha was set to true by default. This is now set to false by default.</p>
</li>
<li>
<p><strong>CrystalComicShow</strong>: Normal "non-comic CDisplay" images were incorrectly displayed when going back using the left arrow key.</p>
</li>
</ol>
<p>This release comes in a ZIP file. Simply unzip the contents to your hard drive, navigate to the root Attilan folder, and double click on <strong>CrystalDemo.sln</strong>. This solution file contains the Crystal Toolkit plus demo programs. Just build the solution (which compiles the CrystalToolkit library first) and run the demo programs to see how they work. You can run the demo programs without building the source by clicking on "<strong>StartDemo.bat</strong>" in the root Attilan folder or <strong>CrystalDemoLauncher.exe</strong> in Attilan\bin.</p>
<p>I've tested the demos under Windows XP SP2 and Windows Vista. Needless to say, buyers beware, this is alpha software and it's free open-source code: you get what you pay for! I'd welcome any feedback, bugs (or bug fixes), and thumb-bitmap replacements. Send email to richard [at] attilan {dot} com.</p>
<p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_075.zip">Crystal Toolkit 075 (zip file, 4.2 mb)
<br/></a></p>
]]></description>
            <link>http://www.attilan.com/2007/04/crystal-toolkit-alpha-release-8.php</link>
            <guid>http://www.attilan.com/2007/04/crystal-toolkit-alpha-release-8.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Downloads</category>
            
            
            <pubDate>Sat, 21 Apr 2007 00:49:10 -0800</pubDate>
        </item>
        
        <item>
            <title>State colors with BorderSplitMode in CrystalImageGridView</title>
            <description><![CDATA[<p>By default, CrystalImageGridView allows you to display thumbnail images with a single border color (CellBorderColor property) that is displayed whenever the CrystalImageItem is selected. That's standard behavior, but a few months ago, I ran into a situation where I wanted to indicate a state for particular image items in the grid. At the time, the best way to handle was to give each CrystalImageItem a unique border color that could be displayed permanently, regardless of selection state. As a result, a range of items could have a red border, others could have a green border. You can create your own customized Collector object to assign these border colors. If you look at this example, I created a subclass from CrystalFileCollector and assigned border colors after all the Images were collected:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">class</span> MyCollector : CrystalFileCollector
{
    <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">bool</span> CollectImages()
    {
        <span class="kwrd">bool</span> result = <span class="kwrd">base</span>.CollectImages();

        <span class="kwrd">if</span> (result)
        {
            <span class="kwrd">int</span> index = 0;
            <span class="kwrd">foreach</span> (CrystalImageItem imageItem <span class="kwrd">in</span> GridModel)
            {
                index++;
                <span class="kwrd">if</span> ((index % 2) == 0)
                {
                    imageItem.BorderColor = Color.Red;
                }

                <span class="kwrd">if</span> ((index % 3) == 0)
                {
                    imageItem.BorderColor = Color.Green;
                }
            }
        }

        <span class="kwrd">return</span> result;
    }
}
</pre>

<p>That's kind of a cheesy example. You might want to examine the Tag property of CrystalImageItem, where you can store your own objects during the collection phase. However, for this simple example, it results in CrystalImageGridViewer displayed the following images with permanent border colors:</p>
<p><a href="http://www.attilan.com/117691385579.jpg"><img src="http://www.attilan.com/117691385579_tn.jpg" style="DISPLAY: inline; WIDTH: 500px; HEIGHT: 260px" title="BorderSplitMode" height="260" width="500" alt="BorderSplitMode" border="0" id="117691385579.jpg"/></a></p>
<p>That looks fine, but what happens when the images are selected? There's a new property which determines the selected border color in this special mode. The selected border color gets drawn inside the state border color. This is so the user can see that the image item is selected, but also recognize the status of the item. Here's what it looks like when the selected border color is set to Black:</p>
<p><a href="http://www.attilan.com/117691386096.jpg"><img src="http://www.attilan.com/117691386096_tn.jpg" style="DISPLAY: inline; WIDTH: 500px; HEIGHT: 252px" title="BorderSplitMode Selection Color" height="252" width="500" alt="BorderSplitMode Selection Color" border="0" id="117691386096.jpg"/></a></p>
<p>Achieving this in your own programs is easy. You will need to change a few properties in CrystalImageGridView in the Forms Designer within Visual Studio:</p>
<p><a href="http://www.attilan.com/117691391990.jpg"><img src="http://www.attilan.com/117691391990_tn.jpg" style="DISPLAY: inline; WIDTH: 239px; HEIGHT: 373px" title="BorderSplitMode Properties" height="373" width="239" alt="BorderSplitMode Properties" border="0" id="117691391990.jpg"/></a></p>
<ol>
<li>
<p>Set BorderSplitMode to True.</p>
</li>
<li>
<p>Set CellBorderColor to Transparent. (You will assign border colors programmatically through CrystalImageItem's BorderColor property.)</p>
</li>
<li>
<p>Set CellSplitColor to whatever you like for the inner selection border color.</p>
</li>
<li>
<p>Make sure BorderWidth is large enough. The inner and outer borders split this width, with the inner border taking up 1/3 of the size.</p>
</li>
</ol>
<p>In the next release of the toolkit, I will have a sample program that demonstrates this feature.</p>
]]></description>
            <link>http://www.attilan.com/2007/04/state-colors-with-bordersplitm.php</link>
            <guid>http://www.attilan.com/2007/04/state-colors-with-bordersplitm.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalFileCollector</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalImageGridView</category>
            
            <pubDate>Wed, 18 Apr 2007 01:11:22 -0800</pubDate>
        </item>
        
        <item>
            <title>C# Dynamic Sorting for Lazy Programmers</title>
            <description><![CDATA[<p>One of the things I wanted to achieve in <a href="http://www.attilan.com/2007/04/crystal_toolkit_alpha_release_7.php">Crystal Toolkit release 74</a> was the ability to sort my generic List&lt;&gt; of images (CrystalImageItem objects). I needed to be able to sort on many different properties within CrystalImageItem, and also to sort in ascending or descending order. Realizing that I probably needed to implement IComparer and IComparable, I decided that was way too much work, and my XBox Achivements score is really ridiculously low. A Google search on the topic lead me to <a href="http://www.codeproject.com/dotnet/dynamiclistsorting.asp" target="_blank">this CodeProject article by Johannes Hansen on Dynamic List sorting</a>. I found his approach intriguing, because he uses Reflection to key on properties within an object and use them as the basis for a compare operation. The resulting sort times are impressive, though I saw a couple of glitches reported on the CodeProject message board. Luckily, another programmer (Marc Brooks) took up the baton and released a <a href="http://musingmarc.blogspot.com/2006/02/dynamic-sorting-of-objects-using.html" target="_blank">C# library that includes a new, improved DynamicComparer</a>. I highly recommend downloading Marc's library as it contains some nifty C# utilities.</p>
<p>Getting DynamicComparer to work was very easy. First, I had to make sure that the properties within the CrystalImageItem object were public, so that Reflection could find them. No problem there, I had four properties, two strings and two dates within CrystalImageItem:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">class</span> CrystalImageItem
{
    <span class="kwrd">public</span> <span class="kwrd">string</span> ImageName
    ...
    <span class="kwrd">public</span> <span class="kwrd">string</span> ImageFormatString
    ...
    <span class="kwrd">public</span> DateTime LastWriteTime
    ...
    <span class="kwrd">public</span> DateTime CreationTime
    ...
</pre>
<p>To make it convenient to specify which property I wanted to sort, I created an enumerator called CrystalSortType:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">enum</span> CrystalSortType
{
    ImageName = 0,
    ImageType = 1,
    CreationTime = 2,
    LastWriteTime = 3
}
</pre>

<p>The CrystalFileCollector is the controller class that manages a CrystalImageGridView and a CrystalImageGridModel. I created a public method called SortCrystalList, which takes a CrystalSortType enumerator, a boolean to indicate ascending or descending sort, and a boolean that tells the controller to redraw the grid (inside CrystalImageGridView) when the sort is completed:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> SortCrystalList(CrystalSortType sortType, 
  <span class="kwrd">bool</span> ascendingOrder, <span class="kwrd">bool</span> reDrawGrid)
</pre>

<p>The protected SortCrystalList method translates the enumerator key to a string and calls a final overloaded method:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">protected</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> SortCrystalList(CrystalSortType sortType, 
                                        <span class="kwrd">bool</span> ascendingOrder)
{
    <span class="kwrd">string</span> orderBy = <span class="kwrd">string</span>.Empty;

    <span class="kwrd">switch</span> (sortType)
    {
        <span class="kwrd">case</span> CrystalSortType.ImageName:
            orderBy = <span class="str">"ImageName"</span>;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> CrystalSortType.ImageType:
            orderBy = <span class="str">"ImageFormatString"</span>;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> CrystalSortType.CreationTime:
            orderBy = <span class="str">"CreationTime"</span>;
            <span class="kwrd">break</span>;
        <span class="kwrd">case</span> CrystalSortType.LastWriteTime:
            orderBy = <span class="str">"LastWriteTime"</span>;
            <span class="kwrd">break</span>;
    }

    SortCrystalList(orderBy, ascendingOrder);
}</pre>

<p>The last version of SortCrystalList takes the string key, adds either ASC or DESC to the string (for ascending or descending sort) and creates the DynamicComparer. The List&lt;CrystalImageItem&gt; object inside the GridModel is sorted according to this key:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">protected</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> SortCrystalList(<span class="kwrd">string</span> orderBy, 
                                <span class="kwrd">bool</span> ascendingOrder)
{
    <span class="kwrd">if</span> (_gridModel == <span class="kwrd">null</span>)
        <span class="kwrd">return</span>;

    <span class="kwrd">if</span> (ascendingOrder)
        orderBy += <span class="str">" ASC"</span>;
    <span class="kwrd">else</span>
        orderBy += <span class="str">" DESC"</span>;

    <span class="rem">// Create the comparer for Person types and define </span>
    <span class="rem">// the sort fields.</span>
    DynamicComparer&lt;CrystalImageItem&gt; comparer = 
        <span class="kwrd">new</span> DynamicComparer&lt;CrystalImageItem&gt;(orderBy);

    <span class="rem">// Sort the list.</span>
    _gridModel.CrystalImageList.Sort(comparer.Compare);
}
</pre>

<p>By default, CrystalFileCollector sorts the internal list by the ImageName property in CrystalImageItem. When the dynamic comparer object is created, the orderBy key looks like "ImageName ASC". If you read Johannes article, you will see that properties can be combined for more interesting sorts like "FirstName, LastName ASC". This is rather like doing a query on your objects, and so far the performance has been really good. You can naturally see that <a href="http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx" target="_blank">the Linq Project</a> is going to make this sort of thing obsolete, but kudos to Johannes for coming up with this way back in December 2005.</p>
]]></description>
            <link>http://www.attilan.com/2007/04/c-dynamic-sorting-for-lazy-pro.php</link>
            <guid>http://www.attilan.com/2007/04/c-dynamic-sorting-for-lazy-pro.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET Framework</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET Tools and Websites</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalFileCollector</category>
            
            <pubDate>Tue, 17 Apr 2007 00:11:00 -0800</pubDate>
        </item>
        
        <item>
            <title>Crystal Toolkit: Alpha Release 0.74</title>
            <description><![CDATA[<p>Crystal Toolkit is a Windows Forms (.NET Framework 2.0) control library written in C#. This is the seventh release and contains updates for the following classes:</p>
<p><strong><span style="TEXT-DECORATION: underline">New in 0.74: Features.</span></strong></p>
<p>New controls: CrystalComicShow.</p>
<p>New controllers for images: CrystalMemoryCollector, CrystalZipCollector, CrystalRarCollector.</p>
<p>New controller options: SortCrystalList method and CrystalSortType enumerator.</p>
<p>New slideshow options: Shuffle and Repeat modes were added.  Slideshow options are now in CrystalSlideShowOptions, which will break older Form applications using the previous build.</p>
<ul>
<li><strong>CrystalComicShow:</strong> A subclass of CrystalPictureShow.   A control that display comic-book images from CDisplay archive files.  You can access CBR and CBZ files and see the thumbnailed images just like any picture folder.  No sample for this yet--it's part of the main application I'm working on for a free release later this year.</li> 
<li><strong>CrystalMemoryCollector:</strong> I needed a collector that didn't work off any disk-based files whatsoever.  This class needs to be fleshed out a bit more, but I intend to write a nice sample that shows how you can build a cool wait dialog using this controller.</li> 
<li><strong>CrystalZipCollector:</strong> This was built for CrystalComicShow, to enable me to display comic book images from a CBZ (zip) file.  It may have broader applications.  It uses ICSharpCode.SharpZipLib.dll, which is included in the open_source_code folder of CrystalToolkit.  <a href="http://www.icsharpcode.net/OpenSource/SharpZipLib/">You can download the full version of SharpZipLib here.</a></li> 
<li><strong>CrystalRarCollector:</strong> This was built for CrystalComicShow, to enable me to display comic book images from a CBR (rar) file.  It may have broader applications.  It uses unrar.cs, which is included in the open_source_code folder of CrystalToolkit.  To make this work with your application, you must include unrar.dll in your application folder.  <a href="http://www.rarlab.com/rar_add.htm">You can download unrar.cs and unrar.dll from RARLab.</a></li>
<li><strong>Controller sorting:</strong> CrystalFileCollector now contains a public method called SortCrystalList.  This takes an enum called CrystalSortType and allows you to sort on ImageName, ImageType, CreationDate or LastWriteTime.  You can sort using this type in either ascending or descending order.</a></li> 
<li><strong>Slideshow enhancments:</strong> The Slideshow options were taken out of CrystalPictureShow as individual properties.  They are now contained with the object CrystalSlideShowOptions, which is a new property within CrystalPictureShow.  Shuffle and Repeat modes were added to the slideshow options.  You can also begin a slideshow at any starting position within the current CrystalCollector.</a></li>  
<li><strong>To see how to build a C# image viewer with thumbnails slideshow application:</strong> Download the zip file in the link below and unzip to your hard drive.  Navigate to the Attilan folder.  Double click on CrystalDemo.sln.  Hit F5 to build CrystalToolkit and execute the demo program, CrystalImageGridDemo. </li> 
</ul>

<p>This release comes in a ZIP file. Simply unzip the contents to your hard drive, navigate to the root Attilan folder, and double click on CrystalDemo.sln. This solution file contains the Crystal Toolkit plus demo programs. Just build the solution (which compiles the CrystalToolkit library first) and run the demo programs to see how they work.</p>
<p>I've tested the demos under Windows XP SP2 and Windows Vista. Needless to say, buyers beware, this is alpha software and it's free open-source code: you get what you pay for! I'd welcome any feedback, bugs (or bug fixes), and thumb-bitmap replacements. Send email to richard [at] attilan {dot} com.</p>
<p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_074.zip">Crystal Toolkit 074 (zip file, 1.9mb)</a></p>
]]></description>
            <link>http://www.attilan.com/2007/04/crystal-toolkit-alpha-release-7.php</link>
            <guid>http://www.attilan.com/2007/04/crystal-toolkit-alpha-release-7.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Downloads</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalComicShow</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalPictureShow</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalRarCollector</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalZipCollector</category>
            
            <pubDate>Sun, 15 Apr 2007 11:11:11 -0800</pubDate>
        </item>
        
        <item>
            <title>Introducing CrystalPictureBox and CrystalPictureShow</title>
            <description><![CDATA[<p>Programming, to me, is like one big mashup, thanks to Google and all the much smarter programmers than me who are out there sharing their code. I've learned a lot of cool GDI+ tricks from various programmers and "borrowed" their open source code where I needed it for the Crystal Toolkit. But I think I've learned and lifted from one man in particular: <a href="http://www.bobpowell.net/tipstricks.htm" target="_blank">Bob Powell and his GDI tips and tricks website</a>. In trying to create the classes for a cool image viewer, I stumbled into the limitations of the PictureBox control, which Bob has railed against for a while. To prove that there was an alternative, <a href="http://www.bobpowell.net/zoompicbox.htm">he wrote the ZoomPicBox example</a>, which shows you how to live without it.</p>
<p><a href="http://www.attilan.com/117368095942.jpg"><img src="http://www.attilan.com/117368095942_tn.jpg" style="DISPLAY: inline; WIDTH: 500px; HEIGHT: 350px" title="CrystalPictureBox ImageSizeMode set to RatioStretch" height="350" width="500" alt="CrystalPictureBox ImageSizeMode set to RatioStretch" border="0" id="117368095942.jpg"/></a>
<br/>
CrystalPictureBox is a "crystalization" of ZoomPicBox. You can see it here in action in the CrystalImageGridDemo application. CrystalPictureShow (a derivative of CrystalPictureBox) is in the top splitter pane, while CrystalImageGridView is displaying the thumbnails from an image folder on the bottom. If you examine the painting code in CrystalPictureBox, you'll see that I retained Powell's technique of setting up a Matrix with a zoom factor, setting the Matrix in the Graphics object, and using DrawImage. One thing I added to the mix was the ability to center the image within the client rectangle. I did this by adjusting the starting location, based on the zoom factor. To use this mode, all you have to do is make sure the ImageSizeMode is set to RatioStretch in the CrystalPictureBox object.</p>
<p><a href="http://www.attilan.com/117368089415.jpg"><img src="http://www.attilan.com/117368089415_tn.jpg" style="DISPLAY: inline; WIDTH: 500px; HEIGHT: 360px" title="CrystalPictureBox ImageSizeMode set to Scrollable" height="360" width="500" alt="CrystalPictureBox ImageSizeMode set to Scrollable" border="0" id="117368089415.jpg"/></a>
<br/>
When the user starts dragging the trackbar on the lower toolbar, the zoom factor changes. Inside the code, I set ImageSizeMode to Scrollable and also set the zoom factor represented by the trackbar (or combo box). The result is a pretty nice and clean scaling of the image as the user drags the mouse. Give a salute to Captain America in all his glory for his unfortunate "death" (what a joke as I think he will be revived) was revealed this week. And let's hope that Silver Surfer looks as nice in the Fantastic Four movie as he does in this close-up.</p>
<p>CrystalPictureBox simply allows you to display images, zoom to a certain percentage of the original size, ratio stretch within the available rectangle, and gives you a cool gradient background.  The concept for Scrollable and RatioStretch size modes came from <a href="http://www.codeproject.com/cs/miscctrl/ratiostretchpicturebox1.asp">Gil Klod's Viewer user control on CodeProject</a>.  I got very used to switching between these two modes and decided to retain them.</p>
<p>CrystalPictureShow, derived from CrystalPictureBox, is more tightly integrated with CrystalImageGridModel to allow you to navigate through lists of CrystalImageItem objects. In the regular display mode, you can view the image in a window just like the above example. If you press the Slideshow button in the demo, you'll see the sample application take over your whole screen (making the form border, menu, toolbars, etc. disappear) and call CrystalPictureShow's StartSlideShow method.</p>
<p>There are four slideshow effects in this first release of CrystalPictureShow: Slide (image moves in from top, bottom, left or right), Fade (image slowly ghosts into the next one), Spin (second image spins and zooms from the current image), and Iris (second image zooms from the current image in an ellipitical form). There was no way that I could have done these without Bob Powell's help. He used to have a subscription based newsletter called Well Formed, and in a number of these he showed people how to do image transitions using GDI+. Unfortunately, Well Formed is not being published at the moment and there's no way to get them on his website. However, this is where being relentless and using Google searches pays off: I found <a href="http://groups.google.com/group/microsoft.public.dotnet.languages.vb/browse_thread/thread/7cab675da1e4fd61/c3d3db35faa8e242?lnk=st&amp;q=iris+spin&amp;rnum=1#c3d3db35faa8e242" target="_blank">this article on Google Groups where Mr. Powell graciously published a VB example program of the image transition effects</a>. Which I gratefully gobbled up and converted to C#.</p>
<p>Check out CrystalImageGridDemo for an example of all of these things in action (get the latest version of CrystalToolkit on the <a href="http://www.attilan.com/downloads/">Downloads</a> page). I feel like I owe Bob Powell several drinks and a fine dinner.</p>
]]></description>
            <link>http://www.attilan.com/2007/03/introducing-crystalpicturebox.php</link>
            <guid>http://www.attilan.com/2007/03/introducing-crystalpicturebox.php</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Crystal Toolkit</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Windows Forms</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalPictureBox</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">CrystalPictureShow</category>
            
            <pubDate>Sun, 11 Mar 2007 23:32:29 -0800</pubDate>
        </item>
        
    </channel>
</rss>
