<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>a geek trapped in a cool guy&#8217;s body</title>
	<atom:link href="https://jasonkemp.ca/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://jasonkemp.ca/blog</link>
	<description>Trapped online since 2004</description>
	<lastBuildDate>Tue, 21 Jun 2016 16:58:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.29</generator>
	<item>
		<title>Setting properties for WiX in MSBuild</title>
		<link>https://jasonkemp.ca/blog/setting-properties-for-wix-in-msbuild/</link>
		<comments>https://jasonkemp.ca/blog/setting-properties-for-wix-in-msbuild/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 03:07:40 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[WiX]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/setting-properties-for-wix-in-msbuild/</guid>
		<description><![CDATA[I recently had the pleasurable and painful experience of learning WiX to build a windows installer for a Windows Mobile application. The pain came first: there is quite a learning curve to both WiX and the underlying Windows Installer technology; and the documentation is a little thin on WiX 3, the latest version as I &#8230; <p class="link-more"><a href="https://jasonkemp.ca/blog/setting-properties-for-wix-in-msbuild/" class="more-link">Continue reading<span class="screen-reader-text"> "Setting properties for WiX in MSBuild"</span></a></p>]]></description>
				<content:encoded><![CDATA[<p>I recently had the pleasurable and painful experience of learning WiX to build a windows installer for a Windows Mobile application. The pain came first: there is quite a learning curve to both WiX and the underlying Windows Installer technology; and the documentation is a little thin on WiX 3, the latest version as I write this. But after about two weeks struggling, the switch flipped, the sun shone, the chorus of angels began singing &#8211; I understood how it worked and saw that its design is very well thought out. It became a joy to use WiX. <strong><em>And </em></strong>it&#8217;s free. <strong><em>And</em></strong> it has pretty good Visual Studio support.</p>
<p>That&#8217;s not to say there aren&#8217;t problems. The documentation is definitely a problem, one to which I&#8217;ll try to make a small contribution in solving. I intend to post more about WiX in the future, but for now, I&#8217;ll cover one small thing which is setting properties for your WiX project in an automated build with MSBuild. </p>
<p>Part of the pretty good Visual Studio support is it&#8217;s own MSBuild-based project file. It has custom tasks that wrap the underlying command-line utilities, candle, lit, light, etc. This makes it really easy to make it part of your daily build or CI builds. One thing that often gets taken over by the build process is setting the version number of your assemblies. Versioning is <em>especially</em> important when it comes to installers, so keeping the installer version in sync with the application version is definitely a good practice. </p>
<p>To do this with your WiX installer project, we first have turn the version value to a variable. (Forgive me if I use the incorrect terms here, I don&#8217;t know the formal WiX names for these things. I&#8217;ll gladly change it if someone corrects me.) </p>
<p>Suppose we have the following, default wxs file given to us by Votive in Visual Studio:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;?</span><span style="color: #800000">xml</span> <span style="color: #ff0000">version</span><span style="color: #0000ff">="1.0"</span> <span style="color: #ff0000">encoding</span><span style="color: #0000ff">="UTF-8"</span>?<span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">Wix</span> <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://schemas.microsoft.com/wix/2006/wi"</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">Product</span> <span style="color: #ff0000">Id</span><span style="color: #0000ff">="*"</span> 
            <span style="color: #ff0000">Name</span><span style="color: #0000ff">="WixProject1"</span> 
            <span style="color: #ff0000">Language</span><span style="color: #0000ff">="1033"</span> 
            <span style="color: #ff0000">Version</span><span style="color: #0000ff">="1.0.0.0"</span> 
            <span style="color: #ff0000">Manufacturer</span><span style="color: #0000ff">="WixProject1"</span> 
            <span style="color: #ff0000">UpgradeCode</span><span style="color: #0000ff">="c93e09b9-9e8f-444c-a35b-84beb2c3788f"</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">Package</span> <span style="color: #ff0000">InstallerVersion</span><span style="color: #0000ff">="200"</span> <span style="color: #ff0000">Compressed</span><span style="color: #0000ff">="yes"</span> <span style="color: #0000ff">/&gt;</span>

        <span style="color: #0000ff">&lt;</span><span style="color: #800000">Media</span> <span style="color: #ff0000">Id</span><span style="color: #0000ff">="1"</span> <span style="color: #ff0000">Cabinet</span><span style="color: #0000ff">="WixProject1.cab"</span> <span style="color: #ff0000">EmbedCab</span><span style="color: #0000ff">="yes"</span> <span style="color: #0000ff">/&gt;</span>

        <span style="color: #0000ff">&lt;</span><span style="color: #800000">Directory</span> <span style="color: #ff0000">Id</span><span style="color: #0000ff">="TARGETDIR"</span> <span style="color: #ff0000">Name</span><span style="color: #0000ff">="SourceDir"</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">Directory</span> <span style="color: #ff0000">Id</span><span style="color: #0000ff">="ProgramFilesFolder"</span><span style="color: #0000ff">&gt;</span>
                <span style="color: #0000ff">&lt;</span><span style="color: #800000">Directory</span> <span style="color: #ff0000">Id</span><span style="color: #0000ff">="INSTALLLOCATION"</span> <span style="color: #ff0000">Name</span><span style="color: #0000ff">="WixProject1"</span><span style="color: #0000ff">&gt;</span>
                    <span style="color: #008000">&lt;!-- TODO: Remove the comments around this Component element</span>
<span style="color: #008000">               and the ComponentRef below in order to add resources to this installer. --&gt;</span>
                    <span style="color: #008000">&lt;!-- &lt;Component Id="ProductComponent" Guid="51acaaef-c2fb-4ef3-a641-9475c81ac948"&gt; --&gt;</span>
                        <span style="color: #008000">&lt;!-- TODO: Insert files, registry keys, and other resources here. --&gt;</span>
                    <span style="color: #008000">&lt;!-- &lt;/Component&gt; --&gt;</span>
                <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Directory</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Directory</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Directory</span><span style="color: #0000ff">&gt;</span>

        <span style="color: #0000ff">&lt;</span><span style="color: #800000">Feature</span> <span style="color: #ff0000">Id</span><span style="color: #0000ff">="ProductFeature"</span> <span style="color: #ff0000">Title</span><span style="color: #0000ff">="WixProject1"</span> <span style="color: #ff0000">Level</span><span style="color: #0000ff">="1"</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #008000">&lt;!-- TODO: Remove the comments around this ComponentRef element</span>
<span style="color: #008000">         and the Component above in order to add resources to this installer. --&gt;</span>
            <span style="color: #008000">&lt;!-- &lt;ComponentRef Id="ProductComponent" /&gt; --&gt;</span>
        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Feature</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Product</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Wix</span><span style="color: #0000ff">&gt;</span>
</pre>
</div>
<p>The property we&#8217;re concerned with is the Version attribute on the Product element. Right now it&#8217;s set to 1.0.0.0. The first thing we need to do is change this into a variable so that we can set the value from elsewhere. To do that we change the Version attribute above into the following:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Product</span> <span style="color: #ff0000">Id</span><span style="color: #0000ff">="*"</span> 
         <span style="color: #ff0000">Name</span><span style="color: #0000ff">="WixProject1"</span> 
         <span style="color: #ff0000">Language</span><span style="color: #0000ff">="1033"</span> 
         <span style="color: #ff0000">Version</span><span style="color: #0000ff">="$(var.ProductVersion)"</span> 
         <span style="color: #ff0000">Manufacturer</span><span style="color: #0000ff">="WixProject1"</span> 
         <span style="color: #ff0000">UpgradeCode</span><span style="color: #0000ff">="c93e09b9-9e8f-444c-a35b-84beb2c3788f"</span><span style="color: #0000ff">&gt;</span>
...
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Product</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>This creates a preprocessor variable called ProductVersion (you can call it whatever you want). If you build the installer now, you get an error saying &#8220;Error&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; Undefined preprocessor variable &#8216;$(var.ProductVersion)&#8217;. &#8220;</p>
<p>Now we have to define that elsewhere. And where else but the project file!</p>
<p>To edit that, right click on the project node in solution explorer, select Unload Project&#8230; Then right click again and select Edit &lt;ProjectName&gt;.wixproj. You&#8217;ll get the proj file loaded as XML in the editor. Let me draw your attention to one of the PropertyGroups:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">PropertyGroup</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Configuration)|$(Platform)' == 'Debug|x86' "</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>bin\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>obj\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>Debug<span style="color: #0000ff">&lt;/</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>This is a property group that is only defined if the Configuration property is Debug and Platform is x86. You see that DefineConstants property set to Debug? That&#8217;s where we want to define our ProductVersion variable, like so:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">PropertyGroup</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Configuration)|$(Platform)' == 'Debug|x86' "</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>bin\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>obj\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>Debug;ProductVersion=1.0.0.0<span style="color: #0000ff">&lt;/</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>In general, you want to define all your properties in Name=Value; format. OK, we have that entered, so close the file, right click on the project node again in SOlution Explorer, select Reload Project. This makes Visual Studio read the project file again. Build again. No errors! Neat, eh?</p>
<p>Now we&#8217;ve managed to move setting the of the ProductVersion property into the MSBuild file, but remember what I said about that property group? It&#8217;s only defined in Debug builds. If we switched our project to Release, then we&#8217;d get the Undefined variable error again. (This is actually a big usability problem in VS, IMO; this happens all the time for many properties and settings).</p>
<p>What we <em>really</em> want is the ProductVersion property defined for all build configurations. But while we&#8217;re developing our installer, we want to use Visual Studio, so we don&#8217;t have to constantly go into the proj file to change things. No problem, I got you covered.</p>
<p>The good folks developing WiX for all of us obviously have our interests in mind by setting that Debug property by default, so we&#8217;re going to want to save that. We also want to define ProductVersion for Release builds. Let&#8217;s consider all the PropertyGroups in the wixproj file, the answer is practically shouting at us:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Configuration</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Configuration)' == '' "</span><span style="color: #0000ff">&gt;</span>Debug<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Configuration</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Platform</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Platform)' == '' "</span><span style="color: #0000ff">&gt;</span>x86<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Platform</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">ProductVersion</span><span style="color: #0000ff">&gt;</span>3.0<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ProductVersion</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">ProjectGuid</span><span style="color: #0000ff">&gt;</span>{9b84d861-ac5d-4559-bc9c-0e59cb95ad90}<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ProjectGuid</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">SchemaVersion</span><span style="color: #0000ff">&gt;</span>2.0<span style="color: #0000ff">&lt;/</span><span style="color: #800000">SchemaVersion</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">OutputName</span><span style="color: #0000ff">&gt;</span>WixProject1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">OutputName</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">OutputType</span><span style="color: #0000ff">&gt;</span>Package<span style="color: #0000ff">&lt;/</span><span style="color: #800000">OutputType</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">WixTargetsPath</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(WixTargetsPath)' == '' "</span><span style="color: #0000ff">&gt;</span>$(MSBuildExtensionsPath)\Microsoft\WiX\v3.0\Wix.targets<span style="color: #0000ff">&lt;/</span><span style="color: #800000">WixTargetsPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Name</span><span style="color: #0000ff">&gt;</span>WixProject1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Name</span><span style="color: #0000ff">&gt;</span>     
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">PropertyGroup</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Configuration)|$(Platform)' == 'Debug|x86' "</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>bin\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>obj\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>Debug;ProductVersion=1.0.0.0<span style="color: #0000ff">&lt;/</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">PropertyGroup</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Configuration)|$(Platform)' == 'Release|x86' "</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>bin\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>obj\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>First thing we should do is add the DefineConstants property with our ProductVersion property in Release:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">PropertyGroup</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Configuration)|$(Platform)' == 'Release|x86' "</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>bin\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>obj\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>ProductVersion=1.0.0.0<span style="color: #0000ff">&lt;/</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>Got it, now: check out the Configuration and Platform properties in the first PropertyGroup. See what they do? They define a default if empty. Now why couldn&#8217;t we do that? We&#8217;ll define another property in the first property group called Version (you can call it what you like):</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Version</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Version)' == '' "</span><span style="color: #0000ff">&gt;</span>1.0.0.0<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Version</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>Alright, one more step, we replace the value in our DefineConstants declarations. I&#8217;ll do the Debug version, you do the Release:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">PropertyGroup</span> <span style="color: #ff0000">Condition</span><span style="color: #0000ff">=" '$(Configuration)|$(Platform)' == 'Debug|x86' "</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>bin\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">OutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>obj\$(Configuration)\<span style="color: #0000ff">&lt;/</span><span style="color: #800000">IntermediateOutputPath</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>Debug;ProductVersion=$(Version)<span style="color: #0000ff">&lt;/</span><span style="color: #800000">DefineConstants</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>Got the Release section finished? Awesome. Reload the project. Build. Awesome.</p>
<p>It works!</p>
<p>Now, we can build this project on the command line and set any version we want.</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">msbuild installer.proj /p:Version=3.1.0.0
</pre>
</div>
<p>One thing to note though. Ideally, you&#8217;re going to mix and match your product assemblies and product installer. Well, maybe not, but if you have any code-based custom actions, you&#8217;re probably going to have a C# or VB project in you product installer solution. </p>
<p>The bad news is that the CSharp.targets file, the file with all the default C# build tasks <em>also</em> defines a DefineConstants property. It&#8217;s used for setting DEBUG and TRACE and all those. They conform to a certain format; one that doesn&#8217;t include Name=Value; formatting. So you get unnecessary warnings.</p>
<p>I&#8217;m not sure why they decided to reuse a well-known property name. Was it really so hard to type &lt;PreprocessorVariable&gt;?</p>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/setting-properties-for-wix-in-msbuild/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>CheckBox.Checked Data Binding Bug in .NET Compact Framework</title>
		<link>https://jasonkemp.ca/blog/checkboxchecked-data-binding-bug-in-net-compact-framework/</link>
		<comments>https://jasonkemp.ca/blog/checkboxchecked-data-binding-bug-in-net-compact-framework/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 01:57:55 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.NET databinding]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/checkboxchecked-data-binding-bug-in-net-compact-framework/</guid>
		<description><![CDATA[Have I mentioned lately how much I like data binding, lately? I use it everywhere I can: it makes writing UI code much easier. Anyway, working on a project at work I ran into the following problem: Consider this code: this.checkBox1.DataBindings.Add("Checked", this.myBindingSource, "MyBooleanProperty", true, DataSourceUpdateMode.OnPropertyChanged); This declares a data binding on checkBox1, a CheckBox control. &#8230; <p class="link-more"><a href="https://jasonkemp.ca/blog/checkboxchecked-data-binding-bug-in-net-compact-framework/" class="more-link">Continue reading<span class="screen-reader-text"> "CheckBox.Checked Data Binding Bug in .NET Compact Framework"</span></a></p>]]></description>
				<content:encoded><![CDATA[<p>Have I mentioned lately how much I like data binding, lately? I use it everywhere I can: it makes writing UI code much easier. Anyway, working on a project at work I ran into the following problem:</p>
<p>Consider this code: </p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">this</span>.checkBox1.DataBindings.Add(<span style="color: #006080">"Checked"</span>, <span style="color: #0000ff">this</span>.myBindingSource, <span style="color: #006080">"MyBooleanProperty"</span>,
                                 <span style="color: #0000ff">true</span>, DataSourceUpdateMode.OnPropertyChanged);</pre>
</div>
<p>This declares a data binding on checkBox1, a CheckBox control. It uses the giant overload taking arguments that, respectively, declare the name of the property on the Control to bind to, the source of the data property, the data property, a boolean for formatting, and a DataSourceUpdateMode enum value.</p>
<p>The DataSourceUpdateMode.OnPropertyChanged value means that as soon as the control&#8217;s Checked property changes, then change the MyBooleanProperty on the data source. OnPropertyChanged is not the default; the default is OnValidation which typically happens when the control loses focus. I&#8217;m a fan of PropertyChanged because there are problems with OnValidation when focus <em>doesn&#8217;t</em> change.</p>
<p>Anyway, if you bind to the Checked property on CheckBox, and select DataSourceUpdateMode.OnPropertyChanged, then it updates on validation.</p>
<p><strong><em><font size="4">BZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZT!</font></em></strong> Wrong! Bug!</p>
<p>Fortunately, there is a workaround. If you use the useless, and practically redundant, CheckState property on CheckBox, instead of Checked, then you get OnPropertyChanged updating. <strong>Important:<em> </em></strong>Make sure &#8216;true&#8217; is passed for the formattingEnabled parameter, otherwise the value expected by the control will be of type CheckState, an enum.</p>
<p>The following code works:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">this</span>.checkBox1.DataBindings.Add(<span style="color: #006080">"CheckState"</span>, <span style="color: #0000ff">this</span>.myBindingSource, <span style="color: #006080">"MyBooleanProperty"</span>, 
                                <span style="color: #0000ff">true</span>, DataSourceUpdateMode.OnPropertyChanged);</pre>
</div>
<p>Your welcome. </p>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/checkboxchecked-data-binding-bug-in-net-compact-framework/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The Missing .NET #8: Displaying Enums in Windows Forms</title>
		<link>https://jasonkemp.ca/blog/the-missing-net-8-displaying-enums-in-windows-forms/</link>
		<comments>https://jasonkemp.ca/blog/the-missing-net-8-displaying-enums-in-windows-forms/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 01:51:52 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Missing .NET]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/the-missing-net-8-displaying-enums-in-windows-forms/</guid>
		<description><![CDATA[The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a series of posts on stuff I find missing in .NET, &#8230; <p class="link-more"><a href="https://jasonkemp.ca/blog/the-missing-net-8-displaying-enums-in-windows-forms/" class="more-link">Continue reading<span class="screen-reader-text"> "The Missing .NET #8: Displaying Enums in Windows Forms"</span></a></p>]]></description>
				<content:encoded><![CDATA[<p class="details_inline">The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer. It could be a useful class, a technique, a good practice or documentation that <em>should</em> be in the framework but isn’t or isn’t widely publicized. <a href="http://www.ageektrapped.com/blog/category/missing-net/" rel="nofollow">Click here for a complete list of Missing .NET entries.</a></p>
<hr>
<p>I&#8217;m sure, Dear Reader, if you wait long enough, I&#8217;ll do all the exercises I leave to you in my posts. I wrote last time about <a href="http://www.ageektrapped.com/blog/the-missing-net-7-displaying-enums-in-wpf/">displaying enums in WPF using databinding</a>. I left it as an exercise to do this in Windows Forms and ASP.NET. Well, it turns out that I needed a Windows Forms version for more than just a programming exercise. So I figured I&#8217;d share something like it with all 5 of you regular readers.</p>
<p>In case you don&#8217;t want to click through to the WPF article, let me recap it here for you since we&#8217;ll be using some of the code from that article. I&#8217;m ambivalent towards enums; I often think they are less useful in many situations in which they are used than a custom class. I do, however, have little choice when it comes to using other libraries or .NET Framework code which may use them. One of the troublesome areas of enums is showing them in UI without going insane writing the same code over and over again with only the slight difference of the enum type to distinguish each version.&nbsp; Last time I used the first-rate data-binding in WPF to show enums in a WPF ComboBox. Then I handled the case where you don&#8217;t own the enum. I also dealt with the issues of internationalization and human readable text instead of the names of each enum value. In this article, I&#8217;ll use the somewhat less first-rate data-binding in Windows Forms to do the same thing.</p>
<p>The first thing we need is a way to mark our enum with the text we want in place of the value name. The perfect way to do that, as I said last time, is to use attributes. The class I presented last time is independent of UI frameworks, so I&#8217;ll use it again here. It&#8217;s reproduced below:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">using</span> System;

<span style="color: #0000ff">namespace</span> MissingNet.ComponentModel
{
   [AttributeUsage(AttributeTargets.Field)]
   <span style="color: #0000ff">public</span> <span style="color: #0000ff">sealed</span> <span style="color: #0000ff">class</span> DisplayStringAttribute : Attribute
   {
      <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> <span style="color: #0000ff">string</span> <span style="color: #0000ff">value</span>;
      <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Value
      {
         get { <span style="color: #0000ff">return</span> <span style="color: #0000ff">value</span>; }
      }

      <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> ResourceKey { get; set; }

      <span style="color: #0000ff">public</span> DisplayStringAttribute(<span style="color: #0000ff">string</span> <span style="color: #0000ff">value</span>)
      {
         <span style="color: #0000ff">this</span>.<span style="color: #0000ff">value</span> = <span style="color: #0000ff">value</span>;
      }

      <span style="color: #0000ff">public</span> DisplayStringAttribute()
      {
      }
   }
}</pre>
</div>
<p>We can apply this to the values of our custom enum, like so: </p>
<p>&nbsp; </p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">enum</span> MyEnum
{
   [DisplayString(<span style="color: #006080">"My Value"</span>)]
    Value,
   [DisplayString(<span style="color: #006080">"This means On"</span>)]
    On,
   [DisplayString(<span style="color: #006080">"Off means not On"</span>)]
    Off,
   [DisplayString(<span style="color: #006080">"The great unknown"</span>)]
    Unknown,
   [DisplayString(<span style="color: #006080">"I ain't got none"</span>)]
    None
}</pre>
</div>
<p>Doesn’t look as pretty as an unadorned enum, but commercial quality code often looks less attractive than you’re typical code snippet on MSDN. If we want to internationalize our app, we can have different display strings for different languages by setting the ResourceKey property instead of the value constructor: </p>
<p>&nbsp; </p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">enum</span> MyEnum
{
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_Value"</span>)] Value,
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_On"</span>)] On,
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_Off"</span>)] Off,
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_Unknown"</span>)] Unknown,
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_None"</span>)] None
}</pre>
</div>
<p>Don’t forget to add the strings to your resx file for each language! </p>
<p>Now that we&#8217;ve reviewed how to associate the display strings with the enum values, we need a way to get that data into the UI. For that I&#8217;ll be using one of the unsung heroes of the .NET 2.0 WinForms improvements: BindingSource. </p>
<p>Earlier I called the data-binding in WinForms less than first-rate. It&#8217;s only in comparison to WPF, which isn&#8217;t really fair: WPF was designed from the ground up with data-binding as a feature. By contrast, Windows Forms is an elegant OO wrapper around the flat Win32 API, an API that is ancient in computer years. It&#8217;s so old they didn&#8217;t even have data when it was designed. So there is nothing as elegant as, say, DataContext in Windows Forms, but it&#8217;s still world&#8217;s better than the alternative of doing it all yourself.</p>
<div class="captionedimg imgcenter"><img title="If Win32 were a Star Wars character" height="300" alt="If Win32 were a Star Wars character" src="https://jasonkemp.ca/blog/wp-content/uploads/img/TheMis.NET8DisplayingEnumsinWindowsForms_C477/win32.jpg" width="400"></p>
<p class="caption">If Win32 were a Star Wars character: really powerful, but really, really old</p>
</div>
<p>They faked it pretty good in .NET 1.1 for simple databinding (simple in the Windows Forms data binding sense of just hooking up to a property); complex databinding (binding to a list or collection or DataSet) was a bit more onerous if you modified the collection independent of the Form that was displaying it. In .NET 2.0, they improved things tremendously by following the old adage: You can at least partially solve any problem in computer science with one more level of indirection. [The full quote, attributed to <a href="http://en.wikipedia.org/wiki/David_Wheeler_(computer_scientist)">David Wheeler</a> is, &#8220;Any problem in computer science can be solved with another layer of indirection. But that usually will create another problem.&#8221;]</p>
<p>And that level of indirection takes the form of the BindingSource. To describe the BindingSource, let me quote directly from the excellent book on the subject of Windows Forms databinding, <em><a href="http://www.amazon.com/gp/product/032126892X?ie=UTF8&amp;tag=jaskemca09-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=032126892X">Data Binding with Windows Forms 2.0</a></em>, by Brian Noyes:</p>
<blockquote>
<p>The BindingSource component solves a number of tricky problems that surfaced with the approach of directly binding data sources to controls in .NET 1.X. It provides a layer of indirection between a data source and bound controls that makes a number of things easier. Additionally, it surfaces important control points and access to the underlying data source in a way that saves you from having to delve into the data-binding mechanisms of a form the way you had to in the past. A binding source also gives you a single API to program against from the form&#8217;s perspective, and lets a lot of your form code remain decoupled from the specific data source type. This prevents you from having to adapt your programmatic coding patterns to each different type of data that your application works with&#8230; [p111-112]</p>
</blockquote>
<p>Sounds perfect for our needs, doesn&#8217;t it? Displaying enums, from a Windows Forms data-binding perspective, is actually fairly easy: it&#8217;s a read-only data source with read-only items, so there is no need to deal with adding, removing or editing. In fact the only tough part is filling the &#8220;list&#8221; with the entries. We&#8217;ve already done something similar with in WPF.</p>
<p>Here&#8217;s the EnumBindingSource class:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> EnumBindingSource : BindingSource
{
  <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> <span style="color: #0000ff">object</span> dataSource;
  <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> PropertyInfo property;

  <span style="color: #0000ff">public</span> EnumBindingSource(<span style="color: #0000ff">object</span> dataSource, <span style="color: #0000ff">string</span> propertyName)
  {
     <span style="color: #0000ff">this</span>.dataSource = dataSource;
     <span style="color: #0000ff">this</span>.property = dataSource.GetType().GetProperty(propertyName);
     Type enumType = property.PropertyType;
     FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
     List&lt;NameEnumPair&gt; source = <span style="color: #0000ff">new</span> List&lt;NameEnumPair&gt;(fields.Length);
     <span style="color: #0000ff">foreach</span> (FieldInfo f <span style="color: #0000ff">in</span> fields)
     {
        DisplayStringAttribute[] a = (DisplayStringAttribute[])f.GetCustomAttributes(<span style="color: #0000ff">typeof</span>(DisplayStringAttribute), <span style="color: #0000ff">false</span>);
        <span style="color: #0000ff">string</span> displayString = GetDisplayStringValue(a, enumType);
        <span style="color: #0000ff">object</span> enumValue = f.GetValue(<span style="color: #0000ff">null</span>);
        NameEnumPair pair = <span style="color: #0000ff">new</span> NameEnumPair(displayString, enumValue);
        source.Add(pair);
     }
     <span style="color: #0000ff">int</span> index = source.FindIndex(<span style="color: #0000ff">value</span> =&gt; <span style="color: #0000ff">value</span>.Value.Equals(property.GetValue(dataSource, <span style="color: #0000ff">null</span>)));
     <span style="color: #0000ff">this</span>.DataSource = source;
     <span style="color: #0000ff">this</span>.Position = index;
  }

  <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">bool</span> AllowEdit
  {
     get { <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span>; }
  }

  <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">bool</span> AllowNew
  {
     get { <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span>; }
     set { <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> NotSupportedException();}
  }

  <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">bool</span> AllowRemove
  {
     get { <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span>; }
  }

  <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnCurrentChanged(EventArgs e)
  {
     <span style="color: #0000ff">base</span>.OnCurrentChanged(e);
     <span style="color: #008000">//set the value</span>
     NameEnumPair <span style="color: #0000ff">value</span> = (NameEnumPair)<span style="color: #0000ff">this</span>.Current;
     property.SetValue(dataSource, <span style="color: #0000ff">value</span>.Value, <span style="color: #0000ff">null</span>);
  }

  <span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">string</span> GetDisplayStringValue(DisplayStringAttribute[] a, Type type)
  {
     <span style="color: #0000ff">if</span> (a == <span style="color: #0000ff">null</span> || a.Length == 0) <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
     DisplayStringAttribute dsa = a[0];
     <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">string</span>.IsNullOrEmpty(dsa.ResourceKey))
     {
        ResourceManager rm = <span style="color: #0000ff">new</span> ResourceManager(type);
        <span style="color: #0000ff">return</span> rm.GetString(dsa.ResourceKey);
     }
     <span style="color: #0000ff">return</span> dsa.Value;
  }

  <span style="color: #0000ff">private</span> <span style="color: #0000ff">class</span> NameEnumPair
  {
     <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> <span style="color: #0000ff">string</span> displayName;
     <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> <span style="color: #0000ff">object</span> <span style="color: #0000ff">value</span>;

     <span style="color: #0000ff">public</span> NameEnumPair(<span style="color: #0000ff">string</span> displayName, <span style="color: #0000ff">object</span> <span style="color: #0000ff">value</span>)
     {
        <span style="color: #0000ff">this</span>.displayName = displayName;
        <span style="color: #0000ff">this</span>.<span style="color: #0000ff">value</span> = <span style="color: #0000ff">value</span>;
     }

     <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> DisplayName
     {
        [DebuggerStepThrough]
        get { <span style="color: #0000ff">return</span> displayName; }
     }

     <span style="color: #0000ff">public</span> <span style="color: #0000ff">object</span> Value
     {
        [DebuggerStepThrough]
        get { <span style="color: #0000ff">return</span> <span style="color: #0000ff">value</span>; }
     }

     <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">string</span> ToString()
     {
        <span style="color: #0000ff">return</span> DisplayName;
     }
  }
}</pre>
</div>
<p>All the work happens in the constructor: we use reflection to get the type of the property passed in, get the enum values in the type, read the DisplayStringAttribute values, add them to a list, set the DataSource property, and we&#8217;re done. I&#8217;ve overridden the AllowXxx properties to make this an immutable BindingSource; there are more properties to override to lock this down as a framework type, but this is a good start. If I were really hardcore, I&#8217;d implement all the interfaces that BindingSource does myself, but I don&#8217;t see the value.</p>
<p>So, this works for enums that <em>you</em> own, but like I said in the WPF article, that is really rare. What you need is a way to declare the strings for enums that you don&#8217;t own. Again, using the WPF implmentation as a reference, we merely need to create a class that will contain the data and set it appropriately. But here, we don&#8217;t have the requirement to support XAML, so we have a bit more freedom. Since this is pretty much an immutable type, setting it in the constructor is the way to go. I just need an overloaded constructor. We also need a type to hold the data we want to set. We already have that type with the nested class NameEnumPair, we just need to make it public, and probably move it to the outer scope, as most .NET types are wont to do.</p>
<p>Here&#8217;re the new constructors:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> EnumBindingSource(<span style="color: #0000ff">object</span> dataSource, <span style="color: #0000ff">string</span> propertyName)
   : <span style="color: #0000ff">this</span>(dataSource, propertyName, <span style="color: #0000ff">null</span>)
{
}

<span style="color: #0000ff">public</span> EnumBindingSource(<span style="color: #0000ff">object</span> dataSource, <span style="color: #0000ff">string</span> propertyName, IEnumerable&lt;NameEnumPair&gt; overriddenDisplayValues)
{
   <span style="color: #0000ff">this</span>.dataSource = dataSource;
   <span style="color: #0000ff">this</span>.property = dataSource.GetType().GetProperty(propertyName);
   List&lt;NameEnumPair&gt; source;
   <span style="color: #0000ff">if</span> (overriddenDisplayValues == <span style="color: #0000ff">null</span>)
   {
      Type enumType = property.PropertyType;
      FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
      source = <span style="color: #0000ff">new</span> List&lt;NameEnumPair&gt;(fields.Length);
      <span style="color: #0000ff">foreach</span> (FieldInfo f <span style="color: #0000ff">in</span> fields)
      {
         DisplayStringAttribute[] a = (DisplayStringAttribute[])f.GetCustomAttributes(<span style="color: #0000ff">typeof</span>(DisplayStringAttribute), <span style="color: #0000ff">false</span>);
         <span style="color: #0000ff">string</span> displayString = GetDisplayStringValue(a, enumType);
         <span style="color: #0000ff">object</span> enumValue = f.GetValue(<span style="color: #0000ff">null</span>);
         NameEnumPair pair = <span style="color: #0000ff">new</span> NameEnumPair(displayString, enumValue);
         source.Add(pair);
      }
   }
   <span style="color: #0000ff">else</span>
   {
      source = <span style="color: #0000ff">new</span> List&lt;NameEnumPair&gt;(overriddenDisplayValues);
   }
   <span style="color: #0000ff">int</span> index = source.FindIndex(<span style="color: #0000ff">value</span> =&gt; <span style="color: #0000ff">value</span>.Value.Equals(property.GetValue(dataSource, <span style="color: #0000ff">null</span>)));
   <span style="color: #0000ff">this</span>.DataSource = source;
   <span style="color: #0000ff">this</span>.Position = index;
}</pre>
</div>
<p>Now we have a way to display enums in ComboBoxes in Windows Forms. Client code looks like the following:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyCustomClass
{
  <span style="color: #0000ff">public</span> MyEnum MyEnumProperty { get; set; }

  <span style="color: #0000ff">public</span> MyCustomClass()
  {
     MyEnumProperty = MyEnum.On;
  }
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">partial</span> <span style="color: #0000ff">class</span> Form1 : Form
{
  <span style="color: #0000ff">public</span> Form1()
  {
     InitializeComponent();
     MyCustomClass myCustomObject = <span style="color: #0000ff">new</span> MyCustomClass();
     <span style="color: #0000ff">this</span>.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
     <span style="color: #0000ff">this</span>.comboBox1.DataSource = <span style="color: #0000ff">new</span> EnumBindingSource(myCustomObject, <span style="color: #006080">"MyEnumProperty"</span>);
  }
}</pre>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/the-missing-net-8-displaying-enums-in-windows-forms/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Keep it DRAFT-y</title>
		<link>https://jasonkemp.ca/blog/keep-it-draft-y/</link>
		<comments>https://jasonkemp.ca/blog/keep-it-draft-y/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 01:19:44 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Rants]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[.NET ListView ColumnHeader]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/keep-it-draft-y/</guid>
		<description><![CDATA[The other day I was grabbing screenshots from an app I&#8217;m working on. I noticed a huge visual problem with a a list in the product: in a one-column ListView in Details view, each item&#8217;s text was truncated, as though the column&#8217;s width was just left to the default of 20 pixels (this is in &#8230; <p class="link-more"><a href="https://jasonkemp.ca/blog/keep-it-draft-y/" class="more-link">Continue reading<span class="screen-reader-text"> "Keep it DRAFT-y"</span></a></p>]]></description>
				<content:encoded><![CDATA[<p>The other day I was grabbing screenshots from an app I&#8217;m working on. I noticed a huge visual problem with a a list in the product: in a one-column ListView in Details view, each item&#8217;s text was truncated, as though the column&#8217;s width was just left to the default of 20 pixels (this is in .NET CF, but the problem below applies to the full framework WinForms as well). This is code I inherited, mind you! <em>I </em>certainly wouldn&#8217;t have coded it this way (No sir, nah-uh), but I found the offending code that that was trying to set the column width to the largest item; something like this:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> ArrangeColumnWidth()
{
    <span style="color: #008000">//this is called after all the items have been added</span>
    <span style="color: #0000ff">using</span> (Graphics g = <span style="color: #0000ff">this</span>.listView.CreateGraphics())
    {
        <span style="color: #0000ff">int</span> maxWidth = 0;
        <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">object</span> item <span style="color: #0000ff">in</span> <span style="color: #0000ff">this</span>.listView.Items)
        {
            SizeF s = g.MeasureString(item.ToString());
            <span style="color: #0000ff">if</span> (s.Width &gt; maxWidth)
                maxWidth = s.Width;
        }
        <span style="color: #0000ff">this</span>.listView.Columns[0].Width = maxWidth;
    }
}</pre>
</div>
<p>Pretty standard find-the-max code, right? Except it wasn&#8217;t working. Since I knew there would always be one column, and we&#8217;d never change out of Details view, I, without thinking too hard about it, changed the above code to the following:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> ArrangeColumnWidth()
{
    <span style="color: #0000ff">this</span>.listView.Columns[0].Width = <span style="color: #0000ff">this</span>.listView.Width;
}</pre>
</div>
<p>&#8220;There! That should do it,&#8221; I thought — in the few seconds that it took me to write it. Of course, you&#8217;ve just read that, and thought, &#8220;What a fool! Anyone can see that if there are enough items in the ListView to cause scrolling vertically, then the column width will be too big, so you&#8217;ll get a horizontal scroll bar also. Duh! Everyone knows that. What was he thinking?&#8221; </p>
<p>And you&#8217;d be right.</p>
<p>But sometimes, when I&#8217;m in the flow, I have really fast edit, compile, run cycles. The first run after the above edit showed me the problem that you astute readers already found.</p>
<p>At this point, in my younger days, I&#8217;d bash away at determining the width of a standard scroll bar and hardcoding that number in my arithmetic. But I&#8217;ve learned the following refrain from using .NET since it came out: <a href="http://www.ageektrapped.com/blog/its-in-the-framework-dummy/">It&#8217;s in the Framework, Dummy!</a></p>
<p>So, I did a Google search, found a forum post, read it, couldn&#8217;t believe the solution was so simple, then went to the MSDN docs to confirm that it was true. <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.columnheader.width.aspx">It was!</a> If you set the ColumnHeader.Width value to -1, it will size to the largest item. If you set the ColumnHeader.Width value to -2, it will size the header to the header text. It&#8217;s all right there on MSDN!</p>
<p>I didn&#8217;t know this little tidbit. So, I re-wrote the code. I got rid of the ArrangeColumnWidth() method altogether and now when I create the column, I set it&#8217;s width to -1. Problem solved!</p>
<p>Two things occurred to me when I read about those helpful values.</p>
<p>The first is that that is some old-ass .NET code. Microsoft doesn&#8217;t write .NET code like that anymore. Instead, I think it would be something like the following:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">enum</span> ColumnWidthStyle
{
    Normal,
    SizeToMaximumItem,
    SizeToColumnHeader
}

ColumnHeader c = <span style="color: #0000ff">new</span> ColumnHeader();
c.WidthStyle = ColumnWidthStyle.SizeToMaximumItem;</pre>
</div>
<p>That code is more verbose, sure; but it&#8217;s way more discoverable, especially with IntelliSense. It&#8217;s also more readable; imagine coming back to this code a few months later: it would still make sense. The way we&#8217;re stuck with is essentially a magic number, a vestigial bump from the dark ol&#8217; days of Win32 programming. I have no doubt that the ColumnHeader class is managed spackle over the Win32 equivalent, so we get those negative width numbers for free.</p>
<p>Even with the awkwardness of the API as it is, I&#8217;m still going to use it. That&#8217;s one method I don&#8217;t have to write. The whole point of using the .NET framework is that it does a lot for you. And yet&#8230;</p>
<p>I still see commercial code shipping with reams and reams of classes and methods that duplicate functionality in the Framework. Why!?! </p>
<p>We&#8217;ve all heard the principle of DRY (Don&#8217;t Repeat Yourself). I&#8217;ve got my own corollary, the DRAFT principle: Don&#8217;t Repeat A Framework Type. .NET, J2EE, Rails, Django, CPAN, whatever language and framework you prefer: assume they solve all your problems, learn them, use them, abuse them. And only if they are truly lacking should you write your own.</p>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/keep-it-draft-y/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to Save XAML as an Image</title>
		<link>https://jasonkemp.ca/blog/how-to-save-xaml-as-an-image/</link>
		<comments>https://jasonkemp.ca/blog/how-to-save-xaml-as-an-image/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 02:03:26 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Note to self...]]></category>
		<category><![CDATA[.NET WPF PNG IMO OMG]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/how-to-save-xaml-as-an-image/</guid>
		<description><![CDATA[Here&#8217;s a quick note to self that you may enjoy. I suck at art. Didn&#8217;t use to always, but it requires too much brain power. But I&#8217;m not bad at getting WPF to draw what I want. I had a logo in mind for this site and used WPF to generate it after unsuccessfully getting &#8230; <p class="link-more"><a href="https://jasonkemp.ca/blog/how-to-save-xaml-as-an-image/" class="more-link">Continue reading<span class="screen-reader-text"> "How to Save XAML as an Image"</span></a></p>]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s a quick note to self that you may enjoy. I suck at art. Didn&#8217;t use to always, but it requires too much brain power. But I&#8217;m not bad at getting WPF to draw what I want. I had a logo in mind for this site and used WPF to generate it after unsuccessfully getting Paint.NET to do the same.</p>
<p>I recently needed to use this code again, but forgot how I solved it. So, rather than hunt it down on Google again, I came home and loaded up ye olde Windows Live Writer to write this post.</p>
<p>To save the XAML you want as an image, put the elements you want to save into a canvas element called canvas. Then run the following code.</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> CommandBinding_Executed(<span style="color: #0000ff">object</span> sender, ExecutedRoutedEventArgs e)
{
   Rect rect = <span style="color: #0000ff">new</span> Rect(canvas.RenderSize);
   RenderTargetBitmap rtb = <span style="color: #0000ff">new</span> RenderTargetBitmap((<span style="color: #0000ff">int</span>)rect.Right,
     (<span style="color: #0000ff">int</span>)rect.Bottom, 96d, 96d, System.Windows.Media.PixelFormats.Default);
   rtb.Render(canvas);
   <span style="color: #008000">//endcode as PNG</span>
   BitmapEncoder pngEncoder = <span style="color: #0000ff">new</span> PngBitmapEncoder();
   pngEncoder.Frames.Add(BitmapFrame.Create(rtb));

   <span style="color: #008000">//save to memory stream</span>
   System.IO.MemoryStream ms = <span style="color: #0000ff">new</span> System.IO.MemoryStream();

   pngEncoder.Save(ms);
   ms.Close();
   System.IO.File.WriteAllBytes(<span style="color: #006080">"logo.png"</span>, ms.ToArray());
   Console.WriteLine(<span style="color: #006080">"Done"</span>);
}</pre>
</div>
<p>I hooked up a key binding to a command to execute this code, but you could use a button click too. It&#8217;ll save the elements in canvas to a file in the same folder as the executable, called logo.png, but you can change that if you want. You can also you a different encoder if you like. They&#8217;re in System.Windows.Media.Imaging.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/how-to-save-xaml-as-an-image/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Missing .NET #7: Displaying Enums in WPF</title>
		<link>https://jasonkemp.ca/blog/the-missing-net-7-displaying-enums-in-wpf/</link>
		<comments>https://jasonkemp.ca/blog/the-missing-net-7-displaying-enums-in-wpf/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 01:52:31 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Missing .NET]]></category>
		<category><![CDATA[.NET enums WPF]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/the-missing-net-7-displaying-enums-in-wpf/</guid>
		<description><![CDATA[Enums are here to stay and we have to deal with them in various ways; displaying them to the user is one way they have to be dealt with. I'll give a treatment of how to display an enum in WPF in this post. You'll see that displaying them in all situations is non-trivial.]]></description>
				<content:encoded><![CDATA[<p class="details_inline">The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer. It could be a useful class, a technique, a good practice or documentation that <em>should</em> be in the framework but isn’t or isn’t widely publicized. <a href="http://www.ageektrapped.com/blog/category/missing-net/" rel="nofollow">Click here for a complete list of Missing .NET entries.</a></p>
<hr>
<p>I&#8217;m ambivalent towards enums. They are a succinct way of providing a list of choices that don&#8217;t change that much. But, I think they are overused, often in situations that don&#8217;t lend themselves well to enums. For example, the HttpStatusCode enum in System.Net. It should probably explicitly be a list of constant integers, because that&#8217;s the way the status code is thought of to HTTP programmers, well, at least one. Consider the two code snippets below. Which one is more readable?</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">void</span> ProcessResponse(WebResponse r)
{
    <span style="color: #0000ff">if</span> (r.StatusCode &gt;= HttpStatusCode.BadRequest)
    {
        <span style="color: #008000">// handle response</span>
    }
}

<span style="color: #0000ff">void</span> ProcessResponse(WebResponse r)
{
    <span style="color: #0000ff">if</span> (r.StatusCode &gt;= 400)
    {
    <span style="color: #008000">// handle request</span>
    }
}</pre>
</div>
<p>Yeah, yeah: you&#8217;re not supposed to use magic numbers, but it&#8217;s not like <a href="http://www.ietf.org/html.charters/httpbis-charter.html">HTTPbis</a> is going to redo all the status codes. It&#8217;s a safe bet that the status code with the value 400 will always mean &#8220;Bad Request&#8221;. </p>
<p>Anyway, Enums are here to stay and we have to deal with them in various ways; displaying them to the user is one way they have to be dealt with. I&#8217;ll give a treatment of how to display an enum in WPF in this post. You&#8217;ll see that displaying them in all situations is non-trivial.</p>
<p>So, let&#8217;s say you want to display a list of the values for your custom enum in a ComboBox in WPF; how do you do it? Well,&nbsp; you could mess around yourself and test your WPF databinding knowledge, but no one has any patience for that nowadays. <a href="http://www.google.ca/search?q=enum+wpf+combobox" rel="nofollow">Let&#8217;s Google it!</a> The goal of most WPF code is to do it all in XAML. So a possible solution to the problem is the following XAML snippet (<a href="http://blogs.msdn.com/wpfsdk/archive/2007/02/22/displaying-enum-values-using-data-binding.aspx">copied from this post</a> from the WPF SDK blog):</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Window</span>
  <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
  <span style="color: #ff0000">xmlns:x</span><span style="color: #0000ff">="http://schemas.microsoft.com/winfx/2006/xaml"</span>
  <span style="color: #ff0000">xmlns:sys</span><span style="color: #0000ff">="clr-namespace:System;assembly=mscorlib"</span>
  <span style="color: #ff0000">SizeToContent</span><span style="color: #0000ff">="WidthAndHeight"</span>
  <span style="color: #ff0000">Title</span><span style="color: #0000ff">="Show Enums in a ListBox using Binding"</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Window.Resources</span><span style="color: #0000ff">&gt;</span>
    <strong><span style="color: #0000ff">&lt;</span><span style="color: #800000">ObjectDataProvider</span> <span style="color: #ff0000">MethodName</span><span style="color: #0000ff">="GetValues"</span>
                        <span style="color: #ff0000">ObjectType</span><span style="color: #0000ff">="{x:Type sys:Enum}"</span>
                        <span style="color: #ff0000">x:Key</span><span style="color: #0000ff">="AlignmentValues"</span><span style="color: #0000ff">&gt;</span>
      <span style="color: #0000ff">&lt;</span><span style="color: #800000">ObjectDataProvider.MethodParameters</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">x:Type</span> <span style="color: #ff0000">TypeName</span><span style="color: #0000ff">="HorizontalAlignment"</span> <span style="color: #0000ff">/&gt;</span>
      <span style="color: #0000ff">&lt;/</span><span style="color: #800000">ObjectDataProvider.MethodParameters</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">ObjectDataProvider</span><span style="color: #0000ff">&gt;</span></strong>
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window.Resources</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Border</span> <span style="color: #ff0000">Margin</span><span style="color: #0000ff">="10"</span> <span style="color: #ff0000">BorderBrush</span><span style="color: #0000ff">="Aqua"</span>
          <span style="color: #ff0000">BorderThickness</span><span style="color: #0000ff">="3"</span> <span style="color: #ff0000">Padding</span><span style="color: #0000ff">="8"</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">StackPanel</span> <span style="color: #ff0000">Width</span><span style="color: #0000ff">="300"</span><span style="color: #0000ff">&gt;</span>
      <span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBlock</span><span style="color: #0000ff">&gt;</span>Choose the HorizontalAlignment
                 value of the Button:<span style="color: #0000ff">&lt;/</span><span style="color: #800000">TextBlock</span><span style="color: #0000ff">&gt;</span>
      <span style="color: #0000ff">&lt;</span><span style="color: #800000">ListBox</span> <span style="color: #ff0000">Name</span><span style="color: #0000ff">="myComboBox"</span> <span style="color: #ff0000">SelectedIndex</span><span style="color: #0000ff">="0"</span> <span style="color: #ff0000">Margin</span><span style="color: #0000ff">="8"</span>
               <span style="color: #ff0000">ItemsSource</span><span style="color: #0000ff">="{Binding Source={StaticResource
                                             AlignmentValues}}"</span><span style="color: #0000ff">/&gt;</span>
      <span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span> <span style="color: #ff0000">Content</span><span style="color: #0000ff">="Click Me!"</span>
              <span style="color: #ff0000">HorizontalAlignment</span><span style="color: #0000ff">="{Binding ElementName=myComboBox,
                                            Path=SelectedItem}"</span><span style="color: #0000ff">/&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">StackPanel</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Border</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>The real magic happens in the bolded text above, the ObjectDataProvider. It calls the GetValues() method on the Enum type. The MethodParameters element contains the actual enum type to display. This is the common sample that you&#8217;ll see throughout the web. A couple problems no one seems to address with this solution, though.</p>
<p>The first is the what actually gets shown to the user. For simple one-word values, like the HorizontalAlignment enum used in the XAML sample above (Center, Justify, Left, Right), it&#8217;s not a problem — if you&#8217;re only coding for the English language. But what about the HttpStatusCode enum? It&#8217;ll show up with the Pascal casing BadRequest or RequestedRangeNotSatisfiable rather than &#8220;Bad Request&#8221; or &#8220;Requested Range Not Satisfiable&#8221;. That&#8217;s acceptable if your audience is a bunch of nerdy programmers (&#8220;I actually prefer no spaces, it makes 2.4321% more efficient so I can devote more time to WoW!&#8221; Nerd.), but if you&#8217;re doing this for real people, you&#8217;re going to want a nice grammatically- correct string to show up. You might want even more detail in the string: &#8220;Bad Request (400)&#8221;, say.</p>
<p>Second, this solution ignores localization. If you just show the name of the enum value, you get whatever language the programmer speaks. That&#8217;s fine if you only plan on shipping your product to your country, but what if you are big in Japan? You&#8217;re going to want to translate that bad boy to Japanese!</p>
<div class="captionedimg imgleft"><img title="Japan's calling. Are you going to answer?" height="244" alt="Japan's calling. Are you going to answer?" src="http://www.ageektrapped.com/blog/wp-content/uploads/img/TheMissing.NET7DisplayingEnumsinWPF_DB27/tom_waits_listening.jpg" width="400"> </p>
<p class="caption">Japan&#8217;s calling. Are you going to answer?</p>
</div>
<p>Let&#8217;s solve that problem. </p>
<p>Let&#8217;s first assume that we own the enum type. We have a web product and a WPF product; we use our custom enum type in both products. We want to display the same thing for the enum values in both places. If that&#8217;s the case, we want the display strings to move around with the enum. How are we going to do that? Well, we have extra data that we want to move around with a type, perfect for &#8230; Attributes!</p>
<p>The simplest attribute class that will work takes a string that will be displayed in place of the enum value. But we don&#8217;t want the simplest class that will work. We want one that will also support localization. Still pretty simple and it looks like this:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[AttributeUsage(AttributeTargets.Field)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">sealed</span> <span style="color: #0000ff">class</span> DisplayStringAttribute : Attribute
{
   <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> <span style="color: #0000ff">string</span> <span style="color: #0000ff">value</span>;
   <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Value
   {
      get { <span style="color: #0000ff">return</span> <span style="color: #0000ff">value</span>; }
   }

   <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> ResourceKey { get; set; }

   <span style="color: #0000ff">public</span> DisplayStringAttribute(<span style="color: #0000ff">string</span> v)
   {
      <span style="color: #0000ff">this</span>.<span style="color: #0000ff">value</span> = v;
   }

   <span style="color: #0000ff">public</span> DisplayStringAttribute()
   {
   }
}</pre>
</div>
<p>We can apply this to the values of our custom enum, like so:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">enum</span> MyEnum
{
   [DisplayString(<span style="color: #006080">"My Value"</span>)] 
    Value,
   [DisplayString(<span style="color: #006080">"This means On"</span>)]
    On,
   [DisplayString(<span style="color: #006080">"Off means not On"</span>)]
    Off,
   [DisplayString(<span style="color: #006080">"The great unknown"</span>)]
    Unknown,
   [DisplayString(<span style="color: #006080">"I ain't got none"</span>)]
    None
}</pre>
</div>
<p>Doesn&#8217;t look as pretty as an unadorned enum, but commercial quality code often looks less attractive than you&#8217;re typical code snippet on MSDN. If we want to internationalize our app, we can have different display strings for different languages by setting the ResourceKey property instead of the value constructor:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">enum</span> MyEnum
{
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_Value"</span>)] Value,
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_On"</span>)] On,
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_Off"</span>)] Off,
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_Unknown"</span>)] Unknown,
   [DisplayString(ResourceKey=<span style="color: #006080">"MyEnum_None"</span>)] None
}</pre>
</div>
<div>&nbsp;</div>
<div>Don&#8217;t forget to add the strings to your resx file for each language!</div>
<div>&nbsp;</div>
<div>So we have our strings established, now we need a class that will read that data, and convert it to something that can be displayed. I&#8217;ll solve that problem for WPF specifically, but there is no reason you can&#8217;t do it for Winforms or the Web also, dear reader. It&#8217;s a good lesson in learning how to support UI frameworks and reflection</div>
<div>&nbsp;</div>
<div>If you&#8217;re designing for WPF, a huge consideration is the ability to express your code in XAML. With my solution below, you&#8217;ll be able to declare these enum displayers in XAML; but as you&#8217;ll see, it makes the code a little less elegant.</div>
<div>&nbsp;</div>
<div>Here are the requirements that my EnumDisplayer class must fulfill:</div>
<ul>
<li>read the DisplayStringAttribute values applied to our enum class; or
<li>load the resource string based on the ResourceKey in the DisplayStringAttribute; and
<li>be expressible in XAML, both declaring one and as a databinding source.</li>
</ul>
<p>Let&#8217;s take care of the third item first, since it will shape the public API more than the other two. </p>
<p>It is an enum&#8217;s nature to be static and constant, hence a class that aids in displaying it to the user is also likely to be static. We&#8217;ll also be using the EnumDisplayer to convert enum values and as a datasource. Before we can do anything though, we need to know the enum type we&#8217;ll be displaying. Ideally, this would mean passing the enum type in the constructor; because of the XAML requirement, however we need a property of type Type. We&#8217;ll add a constructor that takes a Type parameter as a convenience for those that like to write everything in code. So our initial public API looks thus:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> EnumDisplayer : IValueConverter
{
  <span style="color: #0000ff">private</span> Type type;
  <span style="color: #0000ff">private</span> IDictionary displayValues;
  <span style="color: #0000ff">private</span> IDictionary reverseValues;
    
  <span style="color: #0000ff">public</span> EnumDisplayer()
  {
  }

  <span style="color: #0000ff">public</span> EnumDisplayer(Type type)
  {
     <span style="color: #0000ff">this</span>.Type = type;
  }

  <span style="color: #0000ff">public</span> Type Type
  {
     get { <span style="color: #0000ff">return</span> type; }
     set
     {
        <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">value</span>.IsEnum)
           <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> ArgumentException(<span style="color: #006080">"parameter is not an Enumermated type"</span>, <span style="color: #006080">"value"</span>);
        <span style="color: #0000ff">this</span>.type = <span style="color: #0000ff">value</span>;        
     }
  }

  <span style="color: #0000ff">public</span> ReadOnlyCollection&lt;<span style="color: #0000ff">string</span>&gt; DisplayNames
  {
     get
     {
        <span style="color: #0000ff">this</span>.displayValues =...
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> List&lt;<span style="color: #0000ff">string</span>&gt;((IEnumerable&lt;<span style="color: #0000ff">string</span>&gt;)displayValues.Values).AsReadOnly();
     }
  }
  
  <span style="color: #0000ff">object</span> IValueConverter.Convert(<span style="color: #0000ff">object</span> <span style="color: #0000ff">value</span>, Type targetType, <span style="color: #0000ff">object</span> parameter, CultureInfo culture)
  {
     <span style="color: #0000ff">return</span> displayValues[<span style="color: #0000ff">value</span>];
  }

  <span style="color: #0000ff">object</span> IValueConverter.ConvertBack(<span style="color: #0000ff">object</span> <span style="color: #0000ff">value</span>, Type targetType, <span style="color: #0000ff">object</span> parameter, CultureInfo culture)
  {
     <span style="color: #0000ff">return</span> reverseValues[<span style="color: #0000ff">value</span>];
  }
}</pre>
</div>
<p>Pretty straightforward public API: two properties, one being the type to generate strings for, and the other, the strings that we generated. The IValueConverter interface is implemented explicitly. The reverseValues dictionary maps the reverse of displayValues: displayValues goes from enum type to string, reverseValues goes from string to enum. This means that each enum value must have a unique display string; hardly unreasonable, since they have to have a unique name within the enum anyway.</p>
<p>The above public API allows us to declare an EnumDisplayer in XAML like so:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Application.Resources</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">sm:EnumDisplayer</span> <span style="color: #ff0000">Type</span><span style="color: #0000ff">="{x:Type FlickrNet:ContentType}"</span> <span style="color: #ff0000">x:Key</span><span style="color: #0000ff">="contentTypes"</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Application.Resources</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>And use it as a data source and value converter:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">ComboBox</span> <span style="color: #ff0000">ItemsSource</span><span style="color: #0000ff">="{Binding Source={StaticResource contentTypes},Path=DisplayNames}"</span> 
          <span style="color: #ff0000">SelectedValue</span><span style="color: #0000ff">="{Binding Path=Batch.Photos/ContentType, 
                          Converter={StaticResource contentTypes}}"</span> <span style="color: #0000ff">/&gt;</span></pre>
</div>
<p>Well, that&#8217;s just awesome!</p>
<p>Let&#8217;s go back a bit and expand on that &#8216;&#8230;&#8217; in the code for EnumDisplayer. That&#8217;s where all the real work happens. Since I don&#8217;t know the type at compile time, I use reflection to generate my two IDictionary instances when the DisplayValues property is first accessed. I also inspect the enum type provided for DisplayString attributes. All that code is below. It&#8217;s nothing special: most of it I found on the internet if I didn&#8217;t already know how to do it.</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> ReadOnlyCollection&lt;<span style="color: #0000ff">string</span>&gt; DisplayNames
{
 get
 {
    Type displayValuesType = <span style="color: #0000ff">typeof</span>(Dictionary&lt;,&gt;)
                                .GetGenericTypeDefinition().MakeGenericType(<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>),type);
    <span style="color: #0000ff">this</span>.displayValues = (IDictionary) Activator.CreateInstance(displayValuesType);
       
    <span style="color: #0000ff">this</span>.reverseValues =
       (IDictionary)Activator.CreateInstance(<span style="color: #0000ff">typeof</span>(Dictionary&lt;,&gt;)
                .GetGenericTypeDefinition()
                .MakeGenericType(type, <span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>)));

    var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
    <span style="color: #0000ff">foreach</span> (var field <span style="color: #0000ff">in</span> fields)
    {
       DisplayStringAttribute[] a = (DisplayStringAttribute[])
                                   field.GetCustomAttributes(<span style="color: #0000ff">typeof</span>(DisplayStringAttribute), <span style="color: #0000ff">false</span>);

       <span style="color: #0000ff">string</span> displayString = GetDisplayStringValue(a);
       <span style="color: #0000ff">object</span> enumValue = field.GetValue(<span style="color: #0000ff">null</span>);

       <span style="color: #0000ff">if</span> (displayString == <span style="color: #0000ff">null</span>)
       {
          displayString = GetBackupDisplayStringValue(enumValue);
       }
       <span style="color: #0000ff">if</span> (displayString != <span style="color: #0000ff">null</span>)
       {
          displayValues.Add(enumValue, displayString);
          reverseValues.Add(displayString, enumValue);
       }
    }
    <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> List&lt;<span style="color: #0000ff">string</span>&gt;((IEnumerable&lt;<span style="color: #0000ff">string</span>&gt;)displayValues.Values).AsReadOnly();
 }
}

<span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> GetDisplayStringValue(DisplayStringAttribute[] a)
{
     <span style="color: #0000ff">if</span> (a == <span style="color: #0000ff">null</span> || a.Length == 0) <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
     DisplayStringAttribute dsa = a[0];
     <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">string</span>.IsNullOrEmpty(dsa.ResourceKey))
     {
        ResourceManager rm = <span style="color: #0000ff">new</span> ResourceManager(type);
        <span style="color: #0000ff">return</span> rm.GetString(dsa.ResourceKey);
     }
     <span style="color: #0000ff">return</span> dsa.Value;
}</pre>
</div>
<p>Reflection code is always so ugly. I warned you it wasn&#8217;t pretty! See what framework developers have to go through to make code usable? So what&#8217;s happening here?</p>
<p>First, I dynamically create the two dictionaries as generic types. That begs the question: &#8220;Jason, why didn&#8217;t you use generics, wouldn&#8217;t that have been way easier? You&#8217;re such a pedantic loser!&#8221;</p>
<p>Good question. I couldn&#8217;t use them because of that third requirement that I imposed upon myself: XAML. There&#8217;s no easy way to declare a generic type in XAML, so I couldn&#8217;t use them. </p>
<p>Moving along: Next I grab the custom attributes, look for my DisplayStringAttribute and get the value from it in the helper method GetDisplayStringValue(). Notice I prefer the ResourceKey property before the Value property.</p>
<p>Then I add them to the dictionary and the reverseDictionary.</p>
<p>Astute readers should be asking this question by now: what about that call to GetBackupDisplayStringValue? </p>
<p>Right you are, Dear Reader! You&#8217;re so smart.</p>
<p>Alright, let&#8217;s go way back to the top of the article and address one of my assumptions: I assumed that I owned the enum type. That&#8217;s a great assumption to make when you&#8217;re coming up with trivial code examples for a blog post, but what about the real world? I got a mortgage! And WoW bills! And a flight to Japan to pay for!</p>
<p>It&#8217;s not an assumption that holds up under scrutiny. In fact, the chances you&#8217;ll be using an enum you own is probably slimmer than not owning the type. We all know <em>everyone</em> will be using the awesome DisplayStringAttribute once this blog post is published, but what about enums that were created B. DSA. (Before DisplayStringAttribute). Don&#8217;t worry, I got you covered.</p>
<p>To do that, and make it accessible in XAML, we need two things: a collection of enum display overrides and a way to tell the XAML parser that children of the EnumDisplayer get added to that collection. Here&#8217;s the rest of the implementation.</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[ContentProperty(<span style="color: #006080">"OverriddenDisplayEntries"</span>)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> EnumDisplayer : IValueConverter
{
   <span style="color: #0000ff">private</span> Type type;
   <span style="color: #0000ff">private</span> IDictionary displayValues;
   <span style="color: #0000ff">private</span> IDictionary reverseValues;
   <span style="color: #0000ff">private</span> List&lt;EnumDisplayEntry&gt; overriddenDisplayEntries;
   
    ...

   <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> GetBackupDisplayStringValue(<span style="color: #0000ff">object</span> enumValue)
   {
      <span style="color: #0000ff">if</span> (overriddenDisplayEntries != <span style="color: #0000ff">null</span> &amp;&amp; overriddenDisplayEntries.Count &gt; 0)
      {
         EnumDisplayEntry foundEntry = overriddenDisplayEntries.Find(<span style="color: #0000ff">delegate</span>(EnumDisplayEntry entry)
                                          {
                                             <span style="color: #0000ff">object</span> e = Enum.Parse(type, entry.EnumValue);
                                             <span style="color: #0000ff">return</span> enumValue.Equals(e);
                                          });
         <span style="color: #0000ff">if</span> (foundEntry != <span style="color: #0000ff">null</span>)
         {
            <span style="color: #0000ff">if</span> (foundEntry.ExcludeFromDisplay) <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
            <span style="color: #0000ff">return</span> foundEntry.DisplayString;
            
         }
      }
      <span style="color: #0000ff">return</span> Enum.GetName(type, enumValue);
   }
   
   <span style="color: #0000ff">public</span> List&lt;EnumDisplayEntry&gt; OverriddenDisplayEntries
   {
      get
      {
         <span style="color: #0000ff">if</span> (overriddenDisplayEntries == <span style="color: #0000ff">null</span>)
            overriddenDisplayEntries = <span style="color: #0000ff">new</span> List&lt;EnumDisplayEntry&gt;();
         <span style="color: #0000ff">return</span> overriddenDisplayEntries;
      }
   }
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> EnumDisplayEntry
{
   <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> EnumValue { get; set; }
   <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> DisplayString {  get; set; }
   <span style="color: #0000ff">public</span> <span style="color: #0000ff">bool</span> ExcludeFromDisplay { get; set; }
}</pre>
</div>
<p>We decorate our EnumDisplayer class with the ContentProperty attribute that tells the XAML parser that anything contained in an EnumDisplayer element gets added to that property. Then we also need the property which is a List&lt;EnumDisplayEntry&gt;. The EnumDisplayEntry is a way to map an enum value to a new display string. The GetBackupDisplayStringValue() method is pretty straightforward: query the list for the given enum value to return the string or not if you want to exclude from being displayed. I suppose I should prefer the overridden value to the one provided in the DisplayStringAttribute but I&#8217;m jonesing for Guitar Hero, so I&#8217;m going to wrap up.</p>
<p>The above code enables you to provide your own strings for enum values, which we can express in XAML:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">sm:EnumDisplayer</span> <span style="color: #ff0000">Type</span><span style="color: #0000ff">="{x:Type FlickrNet:ContentType}"</span> <span style="color: #ff0000">x:Key</span><span style="color: #0000ff">="contentTypes"</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">sm:EnumDisplayEntry</span> <span style="color: #ff0000">EnumValue</span><span style="color: #0000ff">="Photo"</span> <span style="color: #ff0000">DisplayString</span><span style="color: #0000ff">="Photo (Default)"</span><span style="color: #0000ff">/&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">sm:EnumDisplayEntry</span> <span style="color: #ff0000">EnumValue</span><span style="color: #0000ff">="Screenshot"</span> <span style="color: #ff0000">DisplayString</span><span style="color: #0000ff">="Screenshot"</span><span style="color: #0000ff">/&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">sm:EnumDisplayEntry</span> <span style="color: #ff0000">EnumValue</span><span style="color: #0000ff">="Other"</span> <span style="color: #ff0000">DisplayString</span><span style="color: #0000ff">="Other"</span><span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">sm:EnumDisplayer</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>Admittedly, these aren&#8217;t the most imaginative strings for these enum values, but that&#8217;s an actual snippet of XAML from an actual app.</p>
<p>There are still some things to address: WinForms and ASP.NET should be supported. Also, what about Flags enums? How should those be handled? Enums are surprising in their difficultly to show in UI properly. With the enum displayer class we have a good starting point for making a non-trivial problem of displaying enum values somewhat easier in XAML. </p>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/the-missing-net-7-displaying-enums-in-wpf/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Unable to set TestContext property for my class (.NET Compact Framework)</title>
		<link>https://jasonkemp.ca/blog/unable-to-set-testcontext-property-for-my-class-net-compact-framework/</link>
		<comments>https://jasonkemp.ca/blog/unable-to-set-testcontext-property-for-my-class-net-compact-framework/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 12:28:21 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[netcf]]></category>
		<category><![CDATA[windowsmobile]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/?p=230</guid>
		<description><![CDATA[Suppose you&#8217;re using Visual Studio 2008 and you&#8217;ve just found out that Microsoft added unit test support for the Compact Framework on devices and emulators. Neat-o! So you add one to your project thinking, this&#8217;ll be fantastic. Then it doesn&#8217;t work. You get the following cryptic error: Unable to set TestContext property for the class &#8230; <p class="link-more"><a href="https://jasonkemp.ca/blog/unable-to-set-testcontext-property-for-my-class-net-compact-framework/" class="more-link">Continue reading<span class="screen-reader-text"> "Unable to set TestContext property for my class (.NET Compact Framework)"</span></a></p>]]></description>
				<content:encoded><![CDATA[<p>Suppose you&#8217;re using Visual Studio 2008 and you&#8217;ve just found out that Microsoft added unit test support for the Compact Framework on devices and emulators. Neat-o!</p>
<p>So you add one to your project thinking, <em>this&#8217;ll be fantastic</em>.</p>
<p>Then it doesn&#8217;t work.</p>
<p>You get the following cryptic error:</p>
<p><code>Unable to set TestContext property for the class {class}. Error:  System.ArgumentException: Object of type 'Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapterContext' cannot be converted to type 'Microsoft.VisualStudio.TestTools.UnitTesting.TestContext'</code></p>
<p>&#8220;So,&#8221; you think, &#8220;I obviously did something wrong, but it&#8217;s not apparent to me what I did. I will check the Google.&#8221;</p>
<p>But Google only shows you what to do for the full framework.<footnote>The answer for the full framework is to delete your reference to Microsoft.VisualStudio.QualityTools.UnitTestFramework, then search for it again in the Add Reference dialog. Microsoft forgot to update all the project templates for VS08, so all of the esoteric projects point to the assemblies for <em>VS 2005</em>. Quality tool, my ass.</footnote> The full framework instructions don&#8217;t make any sense for your awesome Compact Framework assembly. Uh oh, now what are you going to do?</p>
<p>Maybe it&#8217;s your project that&#8217;s screwed up. So you start a new one to see if it works. It doesn&#8217;t, but you get a different error: References root node unavailable. You might as well search the google for that one and then you get <a href="http://forums.msdn.microsoft.com/en-US/msbuild/thread/da8f1958-156f-4a65-bd1e-cf352e027a6d/">this forum post</a> that repeats the solution over and over:</p>
<p><span style="font-size:400%;line-height:150%"><strong>Restart the IDE.</strong></span></p>
<p>You figure it can&#8217;t hurt, so you try it.</p>
<p>And it works.</p>
<p>You can now use unit tests for .NET CF projects, but you&#8217;re no longer smiling about it.</p>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/unable-to-set-testcontext-property-for-my-class-net-compact-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The WPF Application Class: Overview and Gotcha</title>
		<link>https://jasonkemp.ca/blog/the-wpf-application-class-overview-and-gotcha/</link>
		<comments>https://jasonkemp.ca/blog/the-wpf-application-class-overview-and-gotcha/#comments</comments>
		<pubDate>Fri, 01 Aug 2008 13:59:01 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.NET WPF]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/the-wpf-application-class-overview-and-gotcha/</guid>
		<description><![CDATA[I&#8217;ve written often lately about WPF, including BabySmash posts and Missing .NET articles. I&#8217;ve decided to do a complete app using WPF. I&#8217;ve dabbled here and there with the concepts, but I&#8217;ve decided I don&#8217;t really know the framework that well. I still have to look up how to do something basic like master-detail data &#8230; <p class="link-more"><a href="https://jasonkemp.ca/blog/the-wpf-application-class-overview-and-gotcha/" class="more-link">Continue reading<span class="screen-reader-text"> "The WPF Application Class: Overview and Gotcha"</span></a></p>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve written often lately about WPF, including <a href="http://www.ageektrapped.com/blog/tag/babysmash">BabySmash posts</a> and <a href="http://www.ageektrapped.com/blog/category/missing-net/">Missing .NET articles</a>. I&#8217;ve decided to do a complete app using WPF. I&#8217;ve dabbled here and there with the concepts, but I&#8217;ve decided I don&#8217;t really know the framework that well. I still have to look up how to do something basic like master-detail data binding. So I set out to do something fairly basic and (barely) doable by one person &#8211; kind of what <a href="http://www.hanselman.com/blog">Scott Hanselman</a> is doing with <a href="http://www.babysmash.com">BabySmash</a>, but a little more traditional, so I can take advantage of more of WPF. I shan&#8217;t disclose the function of the app for now, because it&#8217;s no where near ready. I will, however, document some things I run into, either because they were so useful, but not really advertised, or because I&#8217;ve found sharp rocks in the shallows and must warn others. This post is a bit of both.</p>
<p>If you use Visual Studio, this is obscured from you, but every WPF application must contain the equivalent of the following Main</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[STAThread]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Main(<span style="color: #0000ff">string</span>[] args)
{
    Application app = <span style="color: #0000ff">new</span> Application();
    Window win = <span style="color: #0000ff">new</span> Window();
    win.Show();
    app.Run();    
}</pre>
</div>
<p>Without the <a href="http://msdn.microsoft.com/en-us/library/ms743714.aspx">Application</a> class, the above program will end right after you run it. The magic in Application.Run() is that it sets up a Win32 message pump so that your whiz bang WPF <em>objet d&#8217;art</em> can interact with the rest of Windows, and not exit immediately. There is a surprising amount going on in those four lines of code. Let me explain the big things, before I tell you about the subtlety I found.</p>
<p>There can only be one Application object per process. After the first line of code in the snippet above is run, you can access the static Application.Current property. Doing a test in the Immediate window in Visual Studio to check equality of app and Application.Current will yield true. You can access this anywhere in your app, which makes it really handy.</p>
<p>Let&#8217;s continue with executing the second line.</p>
<p>Once the win instance is created, if we were to inspect the app object again, we&#8217;d see a few things have changed: the MainWindow property is now non-null — it&#8217;s pointing to the win instance; also, the Windows collection will have a Count of 1. For every other window created during the lifetime of the application, the Windows collection will be added to.</p>
<p>Quite a lot has happened in just two lines of code!</p>
<p>The other two lines are obvious; a lot happens when they execute too, but they&#8217;re peripheral to the discussion, so let&#8217;s move on.</p>
<p>This is a common pattern. Microsoft recognized this and codified it into a pattern. The Application class is designed to be inherited, and a WPF app that doesn&#8217;t show a window is a very boring thing. If you create a new WPF application project in VS, you don&#8217;t have to write that Main method above; it&#8217;s all done for you with code gen in the inherited Application object. You don&#8217;t even need to explicitly instantiate a Window instance: VS points the Application.StartupUri property to the XAML file defining your main window.</p>
<p>Now that&#8217;s great for one-off demos or simple applications that do the equivalent of turn a light on and off. But, in my experience as a Windows developer, if you want to do anything complicated, your application will have all sorts of configuration to do; or you have to log in to a service to do anything useful; or whatever. Suppose a developer had to code a scenario to show a dialog on the first run of the app to do some absolutely necessary, can&#8217;t-run-the-app-without-it configuration. To develop that scenario, one would have to eschew the StartupUri property for something slightly more complex.</p>
<p>The Application class also has a number of important events concerned with application lifetime. One of them is the Startup event. A naive developer would handle the previously mentioned scenario of a config dialog in that event handler, like so:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyApp : Application
{
    <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnStartup(<span style="color: #0000ff">object</span> sender, StartUpEventArgs e)
    {
        <span style="color: #0000ff">if</span> (firstRun)
        {
            MyConfigDialog dialog = <span style="color: #0000ff">new</span> MyConfigDialog();
            <span style="color: #0000ff">if</span> (!dialog.ShowDialog().Value)
            {
                <span style="color: #0000ff">this</span>.Shutdown();
            }
        }
        MyMainWindow window = <span style="color: #0000ff">new</span> MyMainWindow();
        window.Show();
    }
}</pre>
</div>
<p>If firstRun is true, and you click OK on the dialog, so that ShowDialog() returns true, then the app will shutdown. I know what you&#8217;re thinking:</p>
<p>Huh?</p>
<p>I&#8217;m not sure, myself: this may be a bug. But here&#8217;s what&#8217;s going on: if this is the first run of the app, then the dialog is shown. It&#8217;s the first Window class created. Therefore, the Application.MainWindow property is set to the dialog instance. When ShowDialog() returns, the dialog is closed. Therefore, Application.MainWindow is null. It&#8217;s like that MyMainWindow instance is invisible or something. He could be screaming at the top of his lungs at Application: &#8220;HEY, LOOK AT ME! I&#8217;VE GOT SOMETHING TO SHOW YOU!&#8221;</p>
<p>Then Application just turns around and exits the building.</p>
<p>&#8220;ASSH&#8211; wait a minute! I&#8217;m invisible! I don&#8217;t need that stupid App instance. I&#8217;m going to rob a bank! I&#8217;ll be rich and the ladies will love me.&#8221; Then he falls on the floor lifeless, &#8217;cause the whole process died. Poor MyMainWindow.<footnote>What, you don&#8217;t anthropomorphize your objects?</footnote></p>
<p>You could also set the MainWindow property yourself, apparently, at any time you want to. But this fails too:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyApp : Application
{
    <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnStartup(<span style="color: #0000ff">object</span> sender, StartUpEventArgs e)
    {
        <span style="color: #0000ff">if</span> (firstRun)
        {
            MyConfigDialog dialog = <span style="color: #0000ff">new</span> MyConfigDialog();
            <span style="color: #0000ff">if</span> (!dialog.ShowDialog().Value)
            {
                <span style="color: #0000ff">this</span>.Shutdown();
            }
        }
        MyMainWindow window = <span style="color: #0000ff">new</span> MyMainWindow();
        <span style="color: #008000">//guess what? this doesn't work!</span>
        <span style="color: #0000ff">this</span>.MainWindow = window;
        window.Show();
    }
}</pre>
</div>
<p>I&#8217;m seriously baffled by this. Looking around in <a href="http://www.aisto.com/roeder/dotnet/">Reflector</a>, the code I&#8217;m looking at says it shouldn&#8217;t act like this. I also don&#8217;t touch Application.ShutdownMode (I&#8217;ve tested this with OnLastWindowClose and with OnMainWindowClose). Anyway, to workaround the issue, simply ensure that MainWindow is instantiated first:</p>
<div>
<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, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyApp : Application
{
    <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnStartUp(<span style="color: #0000ff">object</span> sender, StartUpEventArgs e)
    {
        <span style="color: #008000">//this works! </span>
        MainWindow window = <span style="color: #0000ff">new</span> MainWindow();
        <span style="color: #0000ff">if</span> (firstRun)
        {
            MyConfigDialog dialog = <span style="color: #0000ff">new</span> MyConfigDialog();
            <span style="color: #0000ff">if</span> (!dialog.ShowDialog().Value)
            {
                <span style="color: #0000ff">this</span>.Shutdown();
            }
        }
        window.Show();
    }
}</pre>
</div>
<p>The Application class is a much needed addition to Windows programming. A cross between the ASP.NET Application and Session classes and the WinForms Application class, it provides a property bag, application lifetime events, application-wide resources, an entry point, a Win32 message pump and access to the application&#8217;s windows including the Main Window. Architecturally, I find this class very appealing, but that&#8217;s a topic for another post.</p>
<p>Just watch out for trying to be fancy with extra windows.</p>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/the-wpf-application-class-overview-and-gotcha/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Exporting Blog Posts from Subtext in BlogML</title>
		<link>https://jasonkemp.ca/blog/exporting-blog-posts-from-subtext-in-blogml/</link>
		<pubDate>Wed, 16 Jul 2008 18:48:30 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.NET subtext]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/exporting-blog-posts-from-subtext-in-blogml/</guid>
		<description><![CDATA[I&#8217;ve recently been asked for more detail on how I extracted my blog posts from Subtext. I hacked my solution together in a few nights of hacking. Once I got it working, I completely flushed all memory of what I did. But I was asked a whole two times, dear readers! With that overwhelming curiosity, &#8230; <p class="link-more"><a href="https://jasonkemp.ca/blog/exporting-blog-posts-from-subtext-in-blogml/" class="more-link">Continue reading<span class="screen-reader-text"> "Exporting Blog Posts from Subtext in BlogML"</span></a></p>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve recently been asked for more detail on how I extracted my blog posts from Subtext. I hacked my solution together in a few nights of hacking. Once I got it working, I completely flushed all memory of what I did. But I was asked a whole two times, dear readers! With that overwhelming curiosity, I have no choice but to respond. For background, please read the previous post on what I did generally to <a href="http://www.ageektrapped.com/blog/subtext-to-wordpress-converting-blog-engines/">convert from Subtext to WordPress</a>.</p>
<p>I&#8217;m told that the BlogML export always fails in Subtext, which is the same problem I had. If I recall, it would look like it succeeded, but the XML file you got back would be empty. I was using a version that ran on .NET 1.1 (I think around 1.5, but I&#8217;m not sure), but the technique I outline below should work for Subtext 1.9.5. I&#8217;ll explain (with some code!) how I got around that and it will hopefully help some people out. I had one single-user blog running on Subtext; Multi-user may need far more attention. You <em>will</em> have to get your hands dirty in the code; and by the end of it, you&#8217;ll be more familiar with Subtext than you ever wanted to be. <strong>I&#8217;m writing this from memory</strong>, so take whatever I say as a guide rather than gospel. I no longer have a subtext blog set up so I can&#8217;t rerun this to see why I made the changes I made. If you&#8217;re really determined, you&#8217;ll find a way to get your data. I am willing to help anyone extract their posts from Subtext, though. Just contact me through this post, or through the <a href="http://www.ageektrapped.com/blog/contact">contact form</a>. Maybe we can make this a little more robust to help others.</p>
<p>When I first tried to export using the web interface, as I mentioned, I&#8217;d get an XML file, but it would be empty. Bummer! My first thought was that I had to figure out the right query for the database to extract all the posts. Then I would have to format all the posts into some kind of XML format to import into my new blog engine, WordPress. That&#8217;s a daunting task when you don&#8217;t deal with databases much. Luckily, I played some video games instead of bashing on and realized there was an easier way: using the BlogML exporter in Subtext!</p>
<p>I don&#8217;t remember exactly how I came to my solution &#8212; maybe I bombed around the code and concluded that the reason it was failing had little to do with the BlogML code? &#8212; but it worked, and this was the type of quick one-off problem to which one of my favourite sayings applied: <strong>If it&#8217;s stupid and it works, it isn&#8217;t stupid.<em> </em></strong></p>
<p>So here&#8217;s what I did. I created a ConsoleApplication1 project, referenced just enough of the subtext assemblies (Subtext.BlogML, Subtext.Framework and Subtext.Extensibility) to instantiate their BlogMLWriter and write out the BlogML to disk using an XmlTextWriter. Then I hacked the subtext code to make it compile and run without exceptions. Like I said last time, this solution is not pretty or perfect. To make matters worse, the subtext code I used in my hacked solution was not the same code that my blog was running, so the database versions didn&#8217;t match up. Column names had been changed or added; stored procedures had been renamed or added to. This made me do some seriously weird things like tweak stored procedures and DataReaders and I think install stored procedures that weren&#8217;t there. I did the types of things that shouldn&#8217;t really be recorded for posterity on a blog, you know?</p>
<p>Here&#8217;s the only code in my ConsoleApplication1 project:</p>
<div>
<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: #0000ff">class</span> Program
{
    <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Main(<span style="color: #0000ff">string</span>[] args)
    {            
        IBlogMLProvider provider = <span style="color: #0000ff">new</span> Subtext.ImportExport.SubtextBlogMLProvider();

        provider.ConnectionString = <span style="color: #006080">&quot;yourConnectionString&quot;</span>;
        <span style="color: #0000ff">if</span> (provider.GetBlogMlContext() == <span style="color: #0000ff">null</span>)
        {
            Console.WriteLine(<span style="color: #006080">&quot;ERror'd&quot;</span>);
            <span style="color: #0000ff">return</span>;
        }
        BlogMLWriter writer = BlogMLWriter.Create(provider);

        <span style="color: #0000ff">using</span> (XmlTextWriter xmlWriter = <span style="color: #0000ff">new</span> XmlTextWriter(<span style="color: #006080">&quot;blog.xml&quot;</span>, Encoding.UTF8))
        {
            xmlWriter.Formatting = Formatting.Indented;
            writer.Write(xmlWriter);
            xmlWriter.Flush();
        }
        Console.WriteLine(<span style="color: #006080">&quot;It worked?!&quot;</span>);
    }
}</pre>
</div>
<p>Looks pretty simple, eh? Too bad all the changes are buried deep in completely unrelated classes. I copied the subtext web.config and renamed it app.config. You have to set your connection string in two places in the config file as well as in the Program.cs file shown above (search for &#8216;yourConnectionString&#8217;). Also, since we&#8217;re running code written for ASP.NET in a console app, some things simply will not work, like HttpContext.Current. You&#8217;ll be shown them quickly after running the first time. </p>
<p>Below is an example of one of the changes I had to make:</p>
<div>
<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: #0000ff">private</span> <span style="color: #0000ff">static</span> SqlParameter BlogIdParam
{
    get
    {
        <span style="color: #0000ff">int</span> blogId;
        <span style="color: #008000">//if (InstallationManager.IsInHostAdminDirectory)</span>
        <span style="color: #008000">//    blogId = NullValue.NullInt32;</span>
        <span style="color: #008000">//else</span>
            blogId = 0;

        <span style="color: #0000ff">return</span> DataHelper.MakeInParam(<span style="color: #006080">&quot;@BlogId&quot;</span>, SqlDbType.Int, 4, DataHelper.CheckNull(blogId));
    }
}</pre>
</div>
<p>This is in Subtext.Framework\Data\SqlDataProvider.cs. See the commented code? InstallationManager, through a number of indirections (like, I don&#8217;t know, 57; Subtext is <em>way</em> over-architected) uses HttpContext.Current, so I commented that out. I may have even hardcoded blogId to 0, I don&#8217;t remember.</p>
<p>You can download the ConsoleApplication1 project below and try it out if you wish. </p>
<p>Now, if you want to convert BlogML to the WordPress export format&#8230;</p>
<div class="wlWriterSmartContent" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:109be568-6726-48bc-b310-547a48c8f9cc" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<p><div><a href="http://www.ageektrapped.com/blog/wp-content/uploads/img/ExportingBlogPostsfromSubtextinBlogML_13F61/ConsoleApplication1.zip" target="_self">ConsoleApplication1.zip</a></div>
</p>
</div>
]]></content:encoded>
			</item>
		<item>
		<title>The Missing .NET #6: Version Tolerant Serialization</title>
		<link>https://jasonkemp.ca/blog/the-missing-net-6-version-tolerant-serialization/</link>
		<comments>https://jasonkemp.ca/blog/the-missing-net-6-version-tolerant-serialization/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 18:27:23 +0000</pubDate>
		<dc:creator><![CDATA[Jason Kemp]]></dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Missing .NET]]></category>
		<category><![CDATA[BCL .NET]]></category>

		<guid isPermaLink="false">http://www.ageektrapped.com/blog/the-missing-net-6-version-tolerant-serialization/</guid>
		<description><![CDATA[In .NET 1.1, serialization (binary serialization, to be clear) is a bit hairy when you're successful enough to ship multiple versions of your product and you don't consider versioning until the first bug report about serialization problems. Changing the type, by either adding or removing fields, in .NET 1.1 causes previous versions of your type to lose their mind. The only way to deal with it was to implement ISerializable, which is fraught with problems, not the least of which is it makes you entirely responsible for serialization and deserialization of the whole type for ever and ever. When we found this out, this mass hysteria gripped us, so every serializable type had to implement ISerializable, even it were new to the next version, which is now a maintenance nightmare. We also got sloppy and applied the same boilerplate serialization code to every type. So we didn't handle it well, but you didn't really have a choice in .NET 1.1.]]></description>
				<content:encoded><![CDATA[<p class="details_inline">The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don&#8217;t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer. It could be a useful class, a technique, a good practice or documentation that <em>should</em> be in the framework but isn&#8217;t or isn&#8217;t widely publicized. <a href="http://www.ageektrapped.com/blog/category/missing-net/" rel="nofollow">Click here for a complete list of Missing .NET entries.</a></p>
<hr />
<p>I work on a .NET application that now runs on 2.0 but was written for 1.1. It&#8217;s bit like a farmer&#8217;s son who moved to the city and still does things as if he was on the farm. Like mow his two-square-meter lawn with a ride-on mower, &quot;just like daddy used to back home.&quot; That&#8217;s fine, it gets the job done, but, <em>dude</em>, there&#8217;s a better way. Get a push mower, damn it.</p>
<div class="captionedimg imgright"><img height="240" alt="Getting it back in the garage is a real bitch" title="Getting it back in the garage is a real bitch" src="http://www.ageektrapped.com/blog/wp-content/uploads/img/TheMiss.NET6VersionTolerantSerialization_CA3C/mower_3.jpg" width="180" /> </p>
<p class="caption">Getting it back in the garage is a real bitch</p>
</div>
<p>In .NET 1.1, serialization (binary serialization, to be clear) is a bit hairy when you&#8217;re successful enough to ship multiple versions of your product and you don&#8217;t consider versioning until the first bug report about serialization problems. Changing the type, by either adding or removing fields, in .NET 1.1 causes previous versions of your type to lose their mind. The only way to deal with it at all was to implement ISerializable, which is fraught with problems, not the least of which is it makes you entirely responsible for serialization and deserialization of the whole type for ever and ever. </p>
<p>Now that we&#8217;re running on .NET 2.0, we have more options. Microsoft changed the behaviour so that it&#8217;s version tolerant by default &#8211; no more exceptions on new fields. But there is other awesome stuff besides, so we can have more control over the whole process.</p>
<p>Suppose we had the following serializable type:</p>
<div>
<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: #008000">//Version 1</span>
[Serializable]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyClass
{
  <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> myString;

  <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> MyString
  {
     get { <span style="color: #0000ff">return</span> myString; }
     set { myString = <span style="color: #0000ff">value</span>; }
  }
}</pre>
</div>
<p>You ship your software. MyClass is used to great success; in fact, it made you the most successful MyClass maker in the world. For version 2, you&#8217;ve promised big things for your customers. After all the design work your new, improved MyClass becomes the following:</p>
<div>
<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: #008000">//Version 2</span>
[Serializable]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyClass
{
  <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> myString;
  <span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span> myInt;

  <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> MyString
  {
     get { <span style="color: #0000ff">return</span> myString; }
     set { myString = <span style="color: #0000ff">value</span>; }
  }

  <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> MyInt
  {
     get { <span style="color: #0000ff">return</span> myInt; }
     set { myInt = <span style="color: #0000ff">value</span>; }
  }
}</pre>
</div>
<p>Oooh, look at all the new features! </p>
<p>MyClass Maker version 2 gets in to QA to test upgrading. All the MyClass version 1 instances upgrade just fine, but you had the good fortune to run on .NET 2.0, which by default doesn&#8217;t throw exceptions when there is a field for which the serialized instance does not have data. It just works; Microsoft put serialization in the <a href="http://blogs.msdn.com/brada/archive/2003/10/02/50420.aspx">Pit of Success</a> in .NET 2.0.</p>
<p>But QA came back to Dev with the complaint that after upgrading the MyClass instance didn&#8217;t show off the awesomeness of the new features. They think the default value of the new field should be something else. Since you&#8217;ve just been reading up on <a href="http://msdn.microsoft.com/en-us/library/ms229752.aspx">Version Tolerant Serialization</a>, you know just what to do. </p>
<p>What we need is a way to influence deserialization. With .NET 2.0, Microsoft introduced four attributes that deal with serialization process: OnSerializingAttribute, OnSerializedAttribute, OnDeserializingAttribute, OnDeserializedAttribute.</p>
<p>To set a default value for myInt, we create a method with a specific signature and apply the OnDeserializingAttribute to it <footnote>You could also set the default where you declare the variable if <em>all </em>new instances have the same default</footnote>, like so:</p>
<div>
<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">[OnDeserializing]
<span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> SetMyIntDefault(StreamingContext sc)
{
   myInt = 42;
}</pre>
</div>
<p>If you implement ISerializable as well, this method is called before the deserialization constructor. Only one method per class can be marked with each of these attributes. We set the default value in the OnDeserializing method so that, if there is a myInt value in the serialized instance, the default value gets overwritten with the serialized value.</p>
<p>Your marketer just came back from a conference. He really likes this social aspect to these new-fangled web 2.0 applications. Now you&#8217;re required to enable sharing of MyClass instances among users. Trouble is, we can&#8217;t guarantee everyone is using the most up-to-date version and marketing won&#8217;t let us force upgrades. It&#8217;s OK, we can deal with that. We just have to tweak our new MyClass version; we&#8217;ll mark the myInt field declaration with the OptionalFieldAttribute, so that the serializer will know not to explode if it&#8217;s not there. <footnote>I&#8217;m not sure whether this is necessary because during my testing for this article, the presence or absence of OptionalField didn&#8217;t seem to matter. But it could be because I was lazy: I didn&#8217;t test from 1.1 to 2.0.</footnote></p>
<div>
<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">[Serializable]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyClass
{
   <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> myString;
   [OptionalField(VersionAdded=2)]
   <span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span> myInt;

   <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> MyString
   {
      get { <span style="color: #0000ff">return</span> myString; }
      set { myString = <span style="color: #0000ff">value</span>; }
   }

   <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> MyInt
   {
      get { <span style="color: #0000ff">return</span> myInt; }
      set { myInt = <span style="color: #0000ff">value</span>; }
   }

   [OnDeserializing]
   <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> SetMyIntDefault(StreamingContext sc)
   {
      myInt = 42;
   }
}</pre>
</div>
<p>Because I&#8217;m a good little developer that reads documentation, I included the VersionAdded property in my OptionalField declaration. This is for &quot;future compatibility with new serializers in the framework.&quot; I&#8217;m not sure there will <em>be</em> other serializers in the framework since the CLR hasn&#8217;t changed since 2.0, as well as the whole confusing red bits/green bits thing. But you know what assuming does, right? So I put it in.</p>
<p>One thing I tried in my experimentation was the following: suppose you have a ton of types that implement ISerializable because they&#8217;re legacy 1.1 types. As long as you keep the convention of your keys being the same as the name of the field, then you can move the ISerializable implementation to the dustbin. It seems to just work, although I&#8217;d test it a little more thoroughly. Suppose MyClass version 1 looked like the below code. In Version 2, you could delete the ISerializable stuff.</p>
<div>
<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">[Serializable]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> MyClass : ISerializable
{
   <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> myString;

   <span style="color: #0000ff">public</span> MyClass()
   {
   }

   <span style="color: #0000ff">protected</span> MyClass(SerializationInfo info, StreamingContext context)
   {
      myString = info.GetString(<span style="color: #006080">&quot;myString&quot;</span>);
   }

   <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> MyString
   {
      get { <span style="color: #0000ff">return</span> myString; }
      set { myString = <span style="color: #0000ff">value</span>; }
   }

   <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> GetObjectData(SerializationInfo info, StreamingContext context)
   {
      info.AddValue(<span style="color: #006080">&quot;myString&quot;</span>, myString);
   }
}</pre>
</div>
<p>Deleting code you don&#8217;t need anymore feels so good. Release yourself from the bonds of ISerializable!</p>
<p>There are so many unsung improvements in the BCL in .NET 2.0 that I&#8217;m <em>still</em> finding them nearly four years later. The above improvements to serialization move it from cumbersome chore fraught with peril to those who dare master it to the magic of &quot;it just works.&quot; Serialization code is hard to get right, so I&#8217;m glad Microsoft took most of the onerous stuff off our hands. I&#8217;d encourage you to take a look at the <a href="http://msdn.microsoft.com/en-us/library/ms229752.aspx">MSDN article on Version Tolerant Serialization</a> for all the details on this stuff. I&#8217;ll leave this article with their recommended practices for creating serializable types.</p>
<blockquote>
<p>To ensure proper versioning behavior, follow these rules when modifying a type from version to version:</p>
<ul>
<li>
<p>Never remove a serialized field.</p>
</li>
<li>
<p>Never apply the <a href="http://www.gorillatraining.com/en-us/library/system.nonserializedattribute.aspx">NonSerializedAttribute</a> attribute to a field if the attribute was not applied to the field in the previous version.</p>
</li>
<li>
<p>Never change the name or the type of a serialized field.</p>
</li>
<li>
<p>When adding a new serialized field, apply the OptionalFieldAttribute attribute.</p>
</li>
<li>
<p>When removing a NonSerializedAttribute attribute from a field (that was not serializable in a previous version), apply the OptionalFieldAttribute attribute.</p>
</li>
<li>
<p>For all optional fields, set meaningful defaults using the serialization callbacks unless 0 or null as defaults are acceptable.</p>
</li>
</ul>
<p>To ensure that a type will be compatible with future serialization engines, follow these guidelines:</p>
<ul>
<li>
<p>Always set the VersionAdded property on the OptionalFieldAttribute attribute correctly.</p>
</li>
<li>
<p>Avoid branched versioning.</p>
</li>
</ul>
</blockquote>
<p>Well, actually, let me leave by adding one more: <strong>Don&#8217;t implement ISerializable when introducing new types on a .NET 2.0 or greater project.</strong> If you can&#8217;t serialize your types with the above attributes, you&#8217;re doing it wrong.</p>
]]></content:encoded>
			<wfw:commentRss>https://jasonkemp.ca/blog/the-missing-net-6-version-tolerant-serialization/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
