<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>I Got Rhythm</title><link>http://arbel.net/blog/default.aspx</link><description>Ælij (Eli) Arbel&amp;#39;s blog (.NET, WPF and more)</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/arbelnet" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Local values in DependencyObjects</title><link>http://feedproxy.google.com/~r/arbelnet/~3/EGGmF_0POvM/local-values-in-dependencyobjects.aspx</link><pubDate>Wed, 04 Nov 2009 21:38:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:632</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><comments>http://arbel.net/blog/archive/2009/11/04/local-values-in-dependencyobjects.aspx#comments</comments><description>&lt;p&gt;If you&amp;rsquo;re writing a custom control in WPF, you may have encountered a very annoying bug: if you set the value of a DependencyProperty in your implementation code, the local value will trump any changes that you may try to apply to this property using bindings, styles, etc. You can read more about this in &lt;a href="http://blogs.msdn.com/vinsibal/archive/2009/03/24/the-control-local-values-bug.aspx"&gt;this post&lt;/a&gt; in Vincent Sibal&amp;rsquo;s blog.&lt;/p&gt;
&lt;p&gt;WPF 4 introduces a solution for this problem: the DependencyObject.SetCurrentValue() method. It allows changing the value of a DP without affecting the BaseValueSource. Vincent has a &lt;a href="http://blogs.msdn.com/vinsibal/archive/2009/05/21/the-control-local-values-bug-solution-and-new-wpf-4-0-related-apis.aspx"&gt;nice post&lt;/a&gt; explaining this as well. As he says, a control author should generally use this method instead of SetValue().&lt;/p&gt;
&lt;p&gt;However, if you&amp;rsquo;re still working on a .NET 3-3.5 app, and are encountering this issue, fear not! For there is a workaround, albeit slightly cumbersome. This magic lies within the power of &lt;b&gt;coercion&lt;/b&gt;. Like the new SetCurrentValue(), the good old CoreceValue() method does not change the BaseValueSource. So, instead of setting the value directly, put some logic in the coercion callback of your DP. Your bindings and styles will continue to work after that.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve changed the sample from Vincent&amp;rsquo;s post to use this workaround (take a look at the CustomControl.CoerceTitle() method).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=632" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/EGGmF_0POvM" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.06.32/ControlLocalValuesSample.zip" length="13769" type="application/x-zip-compressed" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/.net+4/default.aspx">.net 4</category><feedburner:origLink>http://arbel.net/blog/archive/2009/11/04/local-values-in-dependencyobjects.aspx</feedburner:origLink></item><item><title>Hey La, Hey La, ClearType’s Back</title><link>http://feedproxy.google.com/~r/arbelnet/~3/tgKKLxykxPE/hey-la-hey-la-cleartype-s-back.aspx</link><pubDate>Wed, 04 Nov 2009 20:35:20 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:631</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><comments>http://arbel.net/blog/archive/2009/11/04/hey-la-hey-la-cleartype-s-back.aspx#comments</comments><description>&lt;p&gt;One of the most referenced posts in this blog is the one dealing with the &lt;a href="http://arbel.net/blog/archive/2007/02/02/give-me-back-my-cleartype.aspx"&gt;ClearType issues&lt;/a&gt;. Those of you who shared my pain will be glad to hear that Microsoft has delivered on its promise: WPF is getting a new text rendering stack in v4, which has the ability to render ClearType (and even aliased text) in every scenario. The new stack is also supposed to match the GDI text renderer, which means that small text will be much more readable.&lt;/p&gt;  &lt;p&gt;You can &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx"&gt;download&lt;/a&gt; Visual Studio 2010 Beta 2 and give it a try. I’m sure you’ll be pleased with the result.&lt;/p&gt;  &lt;p&gt;For more information, head on to &lt;a href="http://blogs.msdn.com/text/archive/2009/08/24/wpf-4-0-text-stack-improvements.aspx"&gt;this post&lt;/a&gt; at the WPF Text blog.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;As a side note, I’ve started working as a Senior .NET Consultant for &lt;a href="http://www.sela.co.il/"&gt;Sela Group&lt;/a&gt;. Hopefully you’ll be seeing a lot more posts this year.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=631" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/tgKKLxykxPE" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/cleartype/default.aspx">cleartype</category><category domain="http://arbel.net/blog/archive/tags/.net+4/default.aspx">.net 4</category><feedburner:origLink>http://arbel.net/blog/archive/2009/11/04/hey-la-hey-la-cleartype-s-back.aspx</feedburner:origLink></item><item><title>Presenting PresentationHost</title><link>http://feedproxy.google.com/~r/arbelnet/~3/2NbWKD56J-k/presenting-presentationhost.aspx</link><pubDate>Mon, 09 Feb 2009 14:26:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:593</guid><dc:creator>aelij</dc:creator><slash:comments>2</slash:comments><comments>http://arbel.net/blog/archive/2009/02/09/presenting-presentationhost.aspx#comments</comments><description>&lt;p&gt;I always prefer simpler solutions. The solution I proposed on my &lt;a href="http://arbel.net/blog/archive/2009/02/06/casper-to-the-rescue.aspx"&gt;previous post&lt;/a&gt; was not that simple, and was not complete. It may still be useful for other stuff, but for the purpose of preserving ClearType while using DWM, I just have to admit it has too many issues.&lt;/p&gt;
&lt;p&gt;The idea of using another window stayed in my head, and then I realized I could use a child window. WPF already has a mechanism for hosting Windows Forms and ActiveX controls. They derive from &lt;b&gt;HwndHost&lt;/b&gt;,which allows creating a window handle and embedding it within the WPF visual tree.&lt;/p&gt;
&lt;p&gt;My control, &lt;b&gt;PresentationHost&lt;/b&gt;, does just that. It hosts an &lt;b&gt;HwndSource&lt;/b&gt;, which provides the infrastructure of WPF windows. You give the HwndSource a root visual to display, and since it is a separate window within the main window, whose composition background remains opaque, ClearType works just fine. You don&amp;rsquo;t have to modify anything in the Ribbon. Even routed commands work transparently!&lt;/p&gt;
&lt;p&gt;The one downside I can think of is that everything inside the host is not part of the visual tree of the window. I did make sure it&amp;rsquo;s a part of the logical tree, so there&amp;rsquo;s a way to get into elements inside the host. XAML name references also work as usual.&lt;/p&gt;
&lt;p&gt;Again, to compile/run the sample, you&amp;rsquo;ll have to obtain the Ribbon assembly separately from the &lt;a href="http://msdn.microsoft.com/en-us/office/aa973809.aspx"&gt;Office UI Licensing&lt;/a&gt; site.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=593" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/2NbWKD56J-k" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.05.93/PresentationHostDemo.zip" length="16115" type="application/zip" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/cleartype/default.aspx">cleartype</category><category domain="http://arbel.net/blog/archive/tags/win7/default.aspx">win7</category><category domain="http://arbel.net/blog/archive/tags/vista/default.aspx">vista</category><category domain="http://arbel.net/blog/archive/tags/dwm/default.aspx">dwm</category><feedburner:origLink>http://arbel.net/blog/archive/2009/02/09/presenting-presentationhost.aspx</feedburner:origLink></item><item><title>Casper to the Rescue!</title><link>http://feedproxy.google.com/~r/arbelnet/~3/a0DEL5UulrU/casper-to-the-rescue.aspx</link><pubDate>Fri, 06 Feb 2009 14:39:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:592</guid><dc:creator>aelij</dc:creator><slash:comments>1</slash:comments><comments>http://arbel.net/blog/archive/2009/02/06/casper-to-the-rescue.aspx#comments</comments><description>&lt;p&gt;WPF has ClearType &lt;a href="http://arbel.net/blog/archive/2007/02/02/give-me-back-my-cleartype.aspx"&gt;issues&lt;/a&gt;. Hopefully some of them will be solved in the upcoming .NET 4.0. Meanwhile, however, I have concocted a nifty solution to one of the scenarios &amp;ndash; placing stuff on the Aero Glass DWM frame.&lt;/p&gt;
&lt;p&gt;When you extend the DWM frame in a WPF application you must set the HwndTarget.BackgroundColor property to Transparent, which turns off ClearType for the entire window.&lt;/p&gt;
&lt;p&gt;Most of the Ribbon implementations do this so they could place the application menu (the round button) halfway on the window title, as well as the quick access toolbar. Since Ribbon-based applications are mostly document-oriented, this is particularly bad, since it completely botches the text readability of the app.&lt;/p&gt;
&lt;p&gt;I had an idea how to solve this a while ago, and just didn&amp;rsquo;t have the time to code it. Now I&amp;rsquo;m working on a project that actually uses a Ribbon, and I wanted my app to be readable even on Vista (and 7 ;), while retaining the nice glassy look.&lt;/p&gt;
&lt;h2&gt;Introducing GhostContentPresenter&lt;/h2&gt;
&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Casper_the_Friendly_Ghost"&gt;Ghost&lt;/a&gt; Content Presenter is a custom control which displays arbitrary WPF content, with a special twist: the content is positioned as if it&amp;rsquo;s part of the visual tree where the GCP is added, but in actuality it is rendered in a Popup, whose position and size are kept synchronized with the parent Window.&lt;/p&gt;
&lt;p&gt;I needed to make a couple of changes to the Popup: make it non-top-most and make the Window that contains the GCP its owner. This way, the Popup will always be above the Window, but never above other windows.&lt;/p&gt;
&lt;p&gt;Now, all I had to do is retemplate the Ribbon control (I used the Microsoft &lt;a href="http://www.codeplex.com/wpf/Wiki/View.aspx?title=WPF Ribbon Preview"&gt;CTP&lt;/a&gt;) to use GhostContentPresenters (MS should really provide the XAML for the Ribbon).&lt;/p&gt;
&lt;p&gt;There are still a few issues left to sort out: (1) Writing the title text (it needs to be offset according to the quick access toolbar, whose width is dynamic, and I didn&amp;rsquo;t want to use another GCP just for it, though it&amp;rsquo;s possible). (2) The Popups appear a split of a second before the Window when restoring a minimized window because of the DWM effect. (3) Binding to commands cannot be done the same way, since routed commands (which use routed events), bubble up the visual tree, and the Popup is not part of it. One solution would be to hook the commands statically using CommandManager.RegisterClassCommandBinding().&lt;/p&gt;
&lt;p&gt;Let me know if you think of other original uses for the GCP (remember the popup can even appear beyond the window borders!) It will be included in the next version of &lt;a href="http://codeplex.com/wpfcontrib/"&gt;WPF Contrib&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;PS &amp;ndash; I&amp;rsquo;m sorry I can&amp;rsquo;t include a working demo this time. You&amp;rsquo;ll have to obtain the Ribbon assembly separately from the &lt;a href="http://msdn.microsoft.com/en-us/office/aa973809.aspx"&gt;Office UI Licensing&lt;/a&gt; site.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; I&amp;rsquo;ve added a timer to deal with the DWM effect delays (controlled by the IsDelayEnabled property). It&amp;rsquo;s a hack, but it works. Also, I&amp;rsquo;ve added an IsGhosting property, that when set to &lt;b&gt;false&lt;/b&gt; causes the GCP to behave like a regular ContentPresenter.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=592" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/a0DEL5UulrU" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.05.92/GhostContentPresenterDemo.zip" length="43977" type="application/x-zip-compressed" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/cleartype/default.aspx">cleartype</category><category domain="http://arbel.net/blog/archive/tags/ribbon/default.aspx">ribbon</category><category domain="http://arbel.net/blog/archive/tags/win7/default.aspx">win7</category><category domain="http://arbel.net/blog/archive/tags/vista/default.aspx">vista</category><category domain="http://arbel.net/blog/archive/tags/dwm/default.aspx">dwm</category><feedburner:origLink>http://arbel.net/blog/archive/2009/02/06/casper-to-the-rescue.aspx</feedburner:origLink></item><item><title>Normality Restored</title><link>http://feedproxy.google.com/~r/arbelnet/~3/Z2Tj25P9avA/normality-restored.aspx</link><pubDate>Tue, 27 Jan 2009 10:05:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:555</guid><dc:creator>aelij</dc:creator><slash:comments>1</slash:comments><comments>http://arbel.net/blog/archive/2009/01/27/normality-restored.aspx#comments</comments><description>&lt;p&gt;The past 24 hours have been a blogger&amp;rsquo;s nightmare for me. I wanted to upgrade my GoDaddy&amp;rsquo;s hosting account to IIS 7. Unfortunately, they do not have any upgrade option, so you have to call their customer service, cancel your current hosting account, create a new one and build everything from scratch.&lt;/p&gt;
&lt;p&gt;What this means, of course, is that you have to backup your current website yourself. I created a backup of the SQL database, and used FileZilla to transfer all the files to my computer. Now, here&amp;rsquo;s where my stupidity comes in: When FileZilla finished the transfer I assumed all was OK. I quickly browsed the root directory and saw that all the sub directories were there, but I forgot to verify the most important thing: the database backup. It seems the wretched FTP software reports errors into a tab at the bottom, that doesn&amp;rsquo;t even get focus if there were any. Talk about trustful computing.&lt;/p&gt;
&lt;p&gt;I realized my grave mistake only after the old account was gone, when I went to upload the website to its new location. I immediately called GoDaddy. It was a matter of minutes since the account was cancelled, yet they informed me that the restore fee would be &lt;b&gt;$150&lt;/b&gt;! That&amp;rsquo;s how much it costs me to host the entire site for&amp;nbsp; &lt;b&gt;two years&lt;/b&gt;! I told them I&amp;rsquo;d get back to them.&lt;/p&gt;
&lt;p&gt;What could I do? Well, it was Google who came to the rescue. Google indexes my blog. Google has cache! So I wrote a small program which fetched the cached pages (per post, since I wanted to restore the comments as well) and parsed them into a simple data structure, which I serialized into an XML file. That was the easy part. The hard part was using the cumbersome Community Server API to repost everything.&lt;/p&gt;
&lt;p&gt;As a side note, GoDaddy does have one useful tool, which I only found later (and which might have saved me all this trouble): You can compress/uncompress files using their file manager. Had I compressed the entire site with the DB backups into a single file, I never would&amp;rsquo;ve missed anything. And the transfer is much faster that way.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s finally over and &lt;a href="http://en.wikipedia.org/wiki/Infinite_Improbability_Drive"&gt;normality&lt;/a&gt; has been restored. The old posts&amp;rsquo; unique IDs may have changed because of this debacle, so I&amp;rsquo;m deeply sorry if some of them have been duplicated in your RSS reader. I have attached the code I used, should anyone ever need it (it&amp;rsquo;s a bit messier than my usual standards). I also added the two config files you need in order to setup Community Server 2008.5 as a single user blog (spent a few hours digging that one up).&lt;/p&gt;
&lt;p&gt;Morals of the story:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Never trust an FTP software for backup. Verify it again and again.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/TANSTAAFL"&gt;TANSTAAFL&lt;/a&gt;. GoDaddy is cheap, but I just discovered a major disadvantage.&lt;/li&gt;
&lt;li&gt;You should backup your website regularly on your own. Don&amp;rsquo;t rely only on your hosting provider.&lt;/li&gt;
&lt;li&gt;Being the good Atheist that I am, I have accepted Google as my personal savior.&lt;/li&gt;
&lt;li&gt;URLs are important. I worked extra hard so that all of the old URLs would remain the same.&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=555" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/Z2Tj25P9avA" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.05.55/RestoreBlog.zip" length="5783" type="application/zip" /><category domain="http://arbel.net/blog/archive/tags/blog/default.aspx">blog</category><category domain="http://arbel.net/blog/archive/tags/google/default.aspx">google</category><category domain="http://arbel.net/blog/archive/tags/restore/default.aspx">restore</category><category domain="http://arbel.net/blog/archive/tags/cache/default.aspx">cache</category><feedburner:origLink>http://arbel.net/blog/archive/2009/01/27/normality-restored.aspx</feedburner:origLink></item><item><title>Theme Manager: A Hackly Hack</title><link>http://feedproxy.google.com/~r/arbelnet/~3/rKSwfVi_0ZU/theme-manager-a-hackly-hack.aspx</link><pubDate>Sun, 28 Dec 2008 19:47:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:537</guid><dc:creator>aelij</dc:creator><slash:comments>1</slash:comments><comments>http://arbel.net/blog/archive/2008/12/28/theme-manager-a-hackly-hack.aspx#comments</comments><description>&lt;p&gt;One of the most popular posts in this blog is the &lt;a href="http://arbel.net/blog/archive/2006/11/03/Forcing-WPF-to-use-a-specific-Windows-theme.aspx"&gt;one&lt;/a&gt; explaining how to override the system theme and get the Vista look on non-Vista systems. This is possible because WPF ships with the theme files for all operation systems (well, all Microsoft OSs that WPF works on, i.e. XP, XP Media Center and Vista) and due to the fact that WPF doesn&amp;rsquo;t really use the system resources to get the OS theme, but rather relies on a private implementation of them that resides in the PresentationFramework.{Classic, Luna, Royale, Aero} assemblies.&lt;/p&gt;
&lt;p&gt;The solution offered in the aforementioned post loads a selected theme dictionary from one of these assemblies to the Application resource dictionary. While this is enough to modify the theme for all the built-in controls, you may encounter problems in the following scenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&amp;rsquo;re using third-party controls that have their own themes for each of the system themes. Many of these controls have a method of bypassing the system theme. (For example, see the &lt;a href="http://doc.xceedsoft.com/products/XceedWpfDataGrid/Xceed.Wpf.DataGrid%7EXceed.Wpf.DataGrid.Views.ViewBase%7ETheme.html"&gt;Theme&lt;/a&gt; property on the Xceed DataGrid.)&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;re writing a theme for your own control. Resources in the &lt;i&gt;Themes&lt;/i&gt; folder do not go through the same lookup chain as other resources, so when you&amp;rsquo;re using built-in controls there, their theme may not be affected by the Application resource dictionary.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As an experiment , I&amp;rsquo;ve decided to hack into the bowels of WPF and force it to recognize a different theme as the system theme. I must say this is one of the ugliest hacks I&amp;rsquo;ve ever done. The result is the class &lt;i&gt;ThemeManager&lt;/i&gt;, which exposes a single static method:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;ChangeTheme(&lt;span style="color:blue;"&gt;string &lt;/span&gt;themeName, &lt;span style="color:blue;"&gt;string &lt;/span&gt;themeColor);&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Examples of theme name and color pairs: { &amp;ldquo;luna&amp;rdquo;, &amp;ldquo;homestead&amp;rdquo; }, { &amp;ldquo;royale&amp;rdquo;, &amp;ldquo;normalcolor&amp;rdquo; }, { &amp;ldquo;classic&amp;rdquo;, &amp;ldquo;&amp;rdquo; }. If you pass two empty strings, the default system theme will return. You can also invent a new theme of your own, give it a name and load it this way. I haven&amp;rsquo;t tried it, but it should work, as long as you conform to the theme dictionary location conventions.&lt;/p&gt;
&lt;p&gt;I also hooked into the message loop and am intercepting the theme change message that is sent to all windows. This blocks WPF from attempting to apply a new theme when the system theme changes.&lt;/p&gt;
&lt;p&gt;Needless to say I&amp;rsquo;m using &lt;b&gt;tons&lt;/b&gt; of reflection and it&amp;rsquo;s likely to break in the next version, so &lt;b&gt;don&amp;rsquo;t use it&lt;/b&gt;. I think this should have been part of the API to begin with.&lt;/p&gt;
&lt;p&gt;PS &amp;ndash; A helpful tip for the theme author: you can find the sources (XAML) for all the themes in the Windows SDK samples (look in WPFSamples.zip/Core/{Classic, Luna, Royale, Aero}Theme.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: Apparently this still works in .NET 4 (as of Beta 2).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=537" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/rKSwfVi_0ZU" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.05.37/ThemeMangerDemo.zip" length="23075" type="application/zip" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/.net+4/default.aspx">.net 4</category><feedburner:origLink>http://arbel.net/blog/archive/2008/12/28/theme-manager-a-hackly-hack.aspx</feedburner:origLink></item><item><title>New Release of WPF Contrib</title><link>http://feedproxy.google.com/~r/arbelnet/~3/em6WS49ZNCY/new-release-of-wpf-contrib.aspx</link><pubDate>Wed, 05 Nov 2008 20:02:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:511</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><comments>http://arbel.net/blog/archive/2008/11/05/new-release-of-wpf-contrib.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve released a new version of &lt;a href="http://codeplex.com/wpfcontrib/"&gt;WPF Contrib&lt;/a&gt; (October 2008, although it&amp;#39;s released in November. I changed the release name a few times, so I decided to leave it like that. I&amp;#39;m only late by a few days. :)&lt;/p&gt;  &lt;p&gt;It contains quite a few fixes and new features. Read about it in the project wiki. There are some breaking changes, which, unlike Microsoft, I can easily make, since I don&amp;#39;t really have a huge user base. Although, many of the new features in TaskDialog were motivated by user requests. Many of the new controls and classes already appeared in articles in this blog.&lt;/p&gt;  &lt;p&gt;I&amp;#39;ve also set up an XBAP demo (only for features that work in partial trust):&lt;/p&gt;  &lt;p&gt;&lt;a title="http://arbel.net/wpfcontrib/AvalonLibraryTestBrowser.xbap" href="http://arbel.net/wpfcontrib/AvalonLibraryTestBrowser.xbap"&gt;http://arbel.net/wpfcontrib/AvalonLibraryTestBrowser.xbap&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As always, I would like to hear from you if you have suggestions and bugs.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=511" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/em6WS49ZNCY" height="1" width="1"/&gt;</description><feedburner:origLink>http://arbel.net/blog/archive/2008/11/05/new-release-of-wpf-contrib.aspx</feedburner:origLink></item><item><title>Activator 2: XAML and Generics Day</title><link>http://feedproxy.google.com/~r/arbelnet/~3/y9_F_9SPPkc/activator-2-xaml-and-generics-day.aspx</link><pubDate>Mon, 27 Oct 2008 09:38:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:412</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><comments>http://arbel.net/blog/archive/2008/10/27/activator-2-xaml-and-generics-day.aspx#comments</comments><description>&lt;p&gt;First of all, you didn't miss part one. Just thought it was a funny &lt;a href="http://en.wikipedia.org/wiki/Terminator_2"&gt;reference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I'm currently working on a new release of &lt;a href="http://codeplex.com/wpfcontrib"&gt;WPF Contrib&lt;/a&gt;. In my TaskDialog class, I used a few classes I derived from ItemsControl (which I'm considering deleting in this version, but that's another debate). The reason I created them was so that you could add any item to the ItemsControl and it would be wrapped in some specific ContentControl, such as a Button. But if you added a Button, it would know that it doesn't need wrapping (this is what the IsItemItsOwnContainerOverride() and GetContainerForItemOverride() methods do).&lt;/p&gt;
&lt;p&gt;I had three classes which were exactly the same, aside from the type of the ContentControl. Generics would very much fit here, but unfortunately, XAML has a &lt;a href="http://msdn.microsoft.com/en-us/library/ms750476.aspx"&gt;very limited&lt;/a&gt; support for it (it seems the new .NET 4.0 XAML stack &lt;a href="http://channel9.msdn.com/pdc2008/TL36/"&gt;will improve&lt;/a&gt; this, and much more). As an exercise I decided to try and extend XAML so it will support generics - on a basic level.&lt;/p&gt;
&lt;p&gt;XAML can be extended using &lt;b&gt;MarkupExtension&lt;/b&gt;s. These are classes that have a single method, ProvideValue(), that when XAML (or BAML) is loaded, create objects according to some custom logic. You're surely familiar with the TypeExtension (x:Type), which returns a System.Type from the specified qualified string. What I've done is create two new extensions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An alternative &lt;b&gt;TypeExtension&lt;/b&gt; that supports type arguments. The following is equivalent to &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;):&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;{&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Type &lt;/span&gt;gen&lt;span style="color:blue;"&gt;:&lt;/span&gt;List&lt;span style="color:blue;"&gt;, {&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Type &lt;/span&gt;gen&lt;span style="color:blue;"&gt;:&lt;/span&gt;List&lt;span style="color:blue;"&gt;, {&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Type &lt;/span&gt;gen&lt;span style="color:blue;"&gt;:&lt;/span&gt;KeyValuePair&lt;span style="color:blue;"&gt;, &lt;/span&gt;sys&lt;span style="color:blue;"&gt;:&lt;/span&gt;String&lt;span style="color:blue;"&gt;, &lt;/span&gt;sys&lt;span style="color:blue;"&gt;:&lt;/span&gt;Int32&lt;span style="color:blue;"&gt;}}}&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Note that you don't have to (but can) specify gen:List&lt;b&gt;&lt;span style="color: #ff8000;"&gt;`1&lt;/span&gt;&lt;/b&gt;. The number of type arguments will be inferred. The constructors support up to 4 type arguments. In the unlikely case that you need more than that, you can use the unabbreviated form and specify the arguments as sub-elements.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;An &lt;b&gt;ActivatorExtension&lt;/b&gt; that accepts a type (either generic or not) and a list of property-value pairs. For example, this will create an instance of ItemsControl&amp;lt;CheckBox&amp;gt; (a generic variation of ItemsControl I have in the demo), and assign some of its properties, including a binding:&lt;/li&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;ActivatorExtension &lt;/span&gt;x&lt;span style="color:blue;"&gt;:&lt;/span&gt;Name&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:maroon;"&gt;"ic" &lt;/span&gt;Type&lt;span style="color:blue;"&gt;="{&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Type &lt;/span&gt;t&lt;span style="color:blue;"&gt;:&lt;/span&gt;ItemsControl&lt;span style="color:blue;"&gt;, {&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Type &lt;/span&gt;CheckBox&lt;span style="color:blue;"&gt;}}&lt;/span&gt;&lt;span style="color:maroon;"&gt;"&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Setter &lt;/span&gt;Name&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:maroon;"&gt;"Name" &lt;/span&gt;Value&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:maroon;"&gt;"ic" &lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Setter &lt;/span&gt;Name&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:maroon;"&gt;"Background" &lt;/span&gt;Value&lt;span style="color:blue;"&gt;="{&lt;/span&gt;&lt;span style="color:teal;"&gt;Binding &lt;/span&gt;ElementName&lt;span style="color:blue;"&gt;=&lt;/span&gt;tb&lt;span style="color:blue;"&gt;, &lt;/span&gt;Path&lt;span style="color:blue;"&gt;=&lt;/span&gt;Text&lt;span style="color:blue;"&gt;}&lt;/span&gt;&lt;span style="color:maroon;"&gt;" &lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Setter &lt;/span&gt;Name&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:maroon;"&gt;"ItemsSource"&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;ArrayExtension &lt;/span&gt;Type&lt;span style="color:blue;"&gt;="{&lt;/span&gt;&lt;span style="color:teal;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Type &lt;/span&gt;sys&lt;span style="color:blue;"&gt;:&lt;/span&gt;String&lt;span style="color:blue;"&gt;}&lt;/span&gt;&lt;span style="color:maroon;"&gt;"&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;sys&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;String&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;one&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:teal;"&gt;sys&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;String&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;sys&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;String&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;two&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:teal;"&gt;sys&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;String&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;sys&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;String&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;three&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:teal;"&gt;sys&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;String&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:teal;"&gt;sys&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;String&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;four&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:teal;"&gt;sys&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;String&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color:teal;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;ArrayExtension&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;Setter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:teal;"&gt;t&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:teal;"&gt;ActivatorExtension&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;/ul&gt;
&lt;p&gt;There are, however, a few severe limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;b&gt;Name&lt;/b&gt; property has no effect, either on the extension or as a property. Not only does the XAML compiler not generate a member for it in the partial class, but the FrameworkElement.FindName() method also doesn't work. In templates, however, FindName() will return the &lt;i&gt;extension itself&lt;/i&gt;, not the constructed object (if you add the x:Name attribute to it). This can be a big problem if you want to use an activated object as a template part.&lt;/li&gt;
&lt;li&gt;Special treatment has been given for bindings to work in property values. Other expressions, such as DynamicResource or TemplateBinding, will not.&lt;/li&gt;
&lt;li&gt;XamlWriter.Save() fails to save an object that contains an activator with a generic type (which makes sense since XAML does not support generics, and after it's loaded, the MarkupExtension is gone.)&lt;/li&gt;
&lt;li&gt;The ActivatorExtension cannot be used as the root of a template (fails at compile time). This can be easily circumvented though, by surrounding it with a Decorator.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As I said in the beginning, this was just an experiment I wanted to share, and in no way should be viewed as a production-quality solution. I will, however, be adding the TypeExtension to the upcoming drop of WPF Contrib. It can be used to specify DataTemplate resource keys for generic types.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=412" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/y9_F_9SPPkc" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.04.12/ActivatorDemo.zip" length="21512" type="application/zip" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/xaml/default.aspx">xaml</category><category domain="http://arbel.net/blog/archive/tags/generics/default.aspx">generics</category><feedburner:origLink>http://arbel.net/blog/archive/2008/10/27/activator-2-xaml-and-generics-day.aspx</feedburner:origLink></item><item><title>License</title><link>http://feedproxy.google.com/~r/arbelnet/~3/-wkc_12ATE4/license-page.aspx</link><pubDate>Sun, 26 Oct 2008 15:54:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:496</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><comments>http://arbel.net/blog/archive/2008/10/26/license-page.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve added a &lt;a href="http://arbel.net/blog/pages/license.aspx"&gt;license page&lt;/a&gt; to my blog.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;As indicated there, all code (unless noted otherwise) is released under the &lt;a href="http://en.wikipedia.org/wiki/MIT_License"&gt;MIT license&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=496" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/-wkc_12ATE4" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/license/default.aspx">license</category><feedburner:origLink>http://arbel.net/blog/archive/2008/10/26/license-page.aspx</feedburner:origLink></item><item><title>Improper use of InteropBitmap can cause a memory leak</title><link>http://feedproxy.google.com/~r/arbelnet/~3/3O4Q2E1sFeA/improper-use-of-interopbitmap-can-cause-a-memory-leak.aspx</link><pubDate>Wed, 22 Oct 2008 10:29:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:492</guid><dc:creator>aelij</dc:creator><slash:comments>2</slash:comments><comments>http://arbel.net/blog/archive/2008/10/22/improper-use-of-interopbitmap-can-cause-a-memory-leak.aspx#comments</comments><description>&lt;p&gt;I've been using InteropBitmap in my &lt;a href="http://arbel.net/blog/archive/2008/08/18/good-old-gdi-or-unblur-thy-text.aspx"&gt;GdiTextBlock&lt;/a&gt;. The control creates a new GDI+ Bitmap every measure pass, which it then converts to a WPF BitmapSource using the Imaging.CreateBitmapSourceFromHBitmap() method (this method returns an InteropBitmap).&lt;/p&gt;
&lt;p&gt;After playing with the control for a while I noticed that the process' working set is constantly increasing. I realized I must have a problem with my bitmap conversion. So, I set out to seek an alternative solution, and I came up with a simple way of creating a BitmapSource directly from a GDI+ Bitmap. (See attached. I've also updated the GdiTextBlock post.)&lt;/p&gt;
&lt;p&gt;After some more digging, I found out that the leakage was entirely &lt;i&gt;my fault&lt;/i&gt;. To use the CreateBitmapSourceFromHBitmap() method, you have to convert the GDI+ bitmap to an HBITMAP by calling the Bitmap.GetHbitmap() method. Its documentation clearly states that "&lt;i&gt;You are responsible for calling the GDI DeleteObject method to free the memory used by the GDI bitmap object.&lt;/i&gt;" Well, there you have it.&lt;/p&gt;
&lt;p&gt;I decided to benchmark the two options. Here are the results:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family: Consolas;"&gt;Interop Bitmap No Delete        &lt;br /&gt;------------------------         &lt;br /&gt;Time: 00:00:01.5989544, Process Memory: 396,936 KB &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Consolas;"&gt;Interop Bitmap With Delete        &lt;br /&gt;--------------------------         &lt;br /&gt;Time: 00:00:01.5158545, Process Memory: 9,056 KB &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Consolas;"&gt;Alternate        &lt;br /&gt;---------         &lt;br /&gt;Time: 00:00:00.5108011, Process Memory: 9,080 KB&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It would seem that the alternate method is preferable even after deleting the HBITMAP. I think the reason for the (time) overhead is that the GDI+ bitmap needs to be converted to an HBITMAP, and then converted to a WPF bitmap, while in the alternate method, we skip the middleman.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Side note:&lt;/b&gt; I'm using a new .NET 3.5 SP1 feature, which allows forcing a garbage collection using the GC.Collect() method (which has a few new overloads as well). Can be pretty useful for benchmarking or debugging.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=492" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/3O4Q2E1sFeA" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.04.92/InteropBitmapLeak.zip" length="15586" type="application/zip" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><feedburner:origLink>http://arbel.net/blog/archive/2008/10/22/improper-use-of-interopbitmap-can-cause-a-memory-leak.aspx</feedburner:origLink></item><item><title>Shady Pixels</title><link>http://feedproxy.google.com/~r/arbelnet/~3/rGtiti8vRzY/shady-pixels.aspx</link><pubDate>Sun, 19 Oct 2008 18:06:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:523</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><comments>http://arbel.net/blog/archive/2008/10/19/shady-pixels.aspx#comments</comments><description>&lt;p&gt;In my &lt;a href="http://arbel.net/blog/archive/2008/09/17/in-the-zune.aspx"&gt;previous post&lt;/a&gt; I mentioned the new Zune 3.0 visualizations. I really liked them, so I decided to try and create them using WPF's new (3.5 SP1) Effects.&lt;/p&gt;
&lt;p&gt;A while ago I &lt;a href="http://arbel.net/blog/archive/2007/02/09/bitmapeffect-begone.aspx"&gt;wrote&lt;/a&gt; about BitmapEffects, and why you should try to avoid them. Effects replace BitmapEffect with an elegant, hardware-accelerated API. An Effect is comprised of a class that derives from ShaderEffect and another file written in &lt;a href="http://en.wikipedia.org/wiki/High_Level_Shader_Language"&gt;HLSL&lt;/a&gt; (High Level Shader Language), which is a C derivative. What you're basically writing is a function that receives the coordinates of a pixel and returns a color - a &lt;b&gt;pixel shader&lt;/b&gt;. If you want to learn how to write one, I suggest checking out Greg Schechter's &lt;a href="http://blogs.msdn.com/greg_schechter/archive/2008/05/09/a-series-on-gpu-based-effects-for-wpf.aspx"&gt;series&lt;/a&gt;. You should also have a look at the &lt;a href="https://www.codeplex.com/wpffx"&gt;WPF Effects Library&lt;/a&gt;, which has a host of ready to use effects, and also shows a great way of using effects to create transitions.&lt;/p&gt;
&lt;p&gt;Now, for my Zune mimic. I created two effects: Blend (which blends one element with another) and PointLight (which colorizes an element and adds two light orbs). I also added a few animations to the demo app, which made it look more like Zune. The result is quite pleasant.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/ShadyPixels_136A9/PointLightDemo_thumb.png" style="border:0px none;" alt="PointLightDemo" width="244" border="0" height="244" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Although I'm quite satisfied with the API, there are a few things that aren't so good:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Debugging effects is not trivial.&lt;/li&gt;
&lt;li&gt;Using multi-input effects on a few UIElements is cumbersome. You have to use a VisualBrush. There should be a way to apply an effect like Blend by specifying the two (or more) elements it's supposed to work on.&lt;/li&gt;
&lt;li&gt;You cannot apply an effect to the background of a Visual. What I mean is that creating an effect like Glass in Vista is impossible. If I apply a BlurEffect on a semi-transparent surface, only the contents of that surface will be blurred, and not what's visible through it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To compile the attached project, you will need the Shader Build Task and Templates, available at &lt;a href="http://www.codeplex.com/wpf/"&gt;codeplex.com/wpf&lt;/a&gt; (WPF Futures release).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=523" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/rGtiti8vRzY" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.05.23/PointLightDemo.zip" length="31509" type="application/zip" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><feedburner:origLink>http://arbel.net/blog/archive/2008/10/19/shady-pixels.aspx</feedburner:origLink></item><item><title>In the Zune</title><link>http://feedproxy.google.com/~r/arbelnet/~3/twlxMgaZSMc/in-the-zune.aspx</link><pubDate>Wed, 17 Sep 2008 12:06:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:493</guid><dc:creator>aelij</dc:creator><slash:comments>2</slash:comments><comments>http://arbel.net/blog/archive/2008/09/17/in-the-zune.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m loving the new &lt;a href="http://www.zune.net/en-us/products/zunesoftware/"&gt;Zune 3.0&lt;/a&gt; client software. V1 was terrible. Just an ugly version of Windows Media Player. V2 was completely rewritten using a Microsoft internal platform called UIX, which is based on Media Center. Although it&amp;#39;s still .NET, I was slightly disappointed they didn&amp;#39;t use WPF.&lt;/p&gt;  &lt;p&gt;Anyhow, it&amp;#39;s still a great piece of software, very fluent and intuitive, and it looks cool with all sorts of smooth animations. In V3 they added a few nifty features, such as new Now Playing visualizations. It downloads photos and data (such as number of plays) from the web, and performs a very attractive pan, zoom and tint effect on them. Here are a few shots:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/IntheZune_EEF8/zune_vis1_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="167" alt="zune_vis1" src="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/IntheZune_EEF8/zune_vis1_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;a href="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/IntheZune_EEF8/zune_vis2_2.jpg"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="167" alt="zune_vis2" src="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/IntheZune_EEF8/zune_vis2_thumb.jpg" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In addition, there&amp;#39;s the Mix View, which allows you to effectively view related albums and artists. You can play, buy or get more info directly from this view:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/IntheZune_EEF8/zune_mixview_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="167" alt="zune_mixview" src="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/IntheZune_EEF8/zune_mixview_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I&amp;#39;ve had my Zune (30GB) for over a year now, and it has gone through a lot. It&amp;#39;s quite battered. A month ago, it fell on the pavement and suffered a nearly-lethal blow. What really blows is that the device is fully functional, but the display is cracked, with a large black stain in the middle:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/IntheZune_EEF8/DSC02243.jpg"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="184" alt="DSC02243" src="http://arbel.net/blog/blogs/aelij/WindowsLiveWriter/IntheZune_EEF8/DSC02243_thumb.jpg" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So now I&amp;#39;m considering buying the new (flash memory-based) 16GB Zune. The new 3.0 firmware also has a few new features I like: browse the marketplace wirelessly and games. What I&amp;#39;m still missing is support for international fonts (mainly Hebrew) and search (the marketplace has it - with a great interface.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=493" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/twlxMgaZSMc" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/zune/default.aspx">zune</category><category domain="http://arbel.net/blog/archive/tags/personal/default.aspx">personal</category><feedburner:origLink>http://arbel.net/blog/archive/2008/09/17/in-the-zune.aspx</feedburner:origLink></item><item><title>Good Old GDI+ (or: Unblur Thy Text)</title><link>http://feedproxy.google.com/~r/arbelnet/~3/zROoh8YN9CM/good-old-gdi-or-unblur-thy-text.aspx</link><pubDate>Mon, 18 Aug 2008 10:35:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:483</guid><dc:creator>aelij</dc:creator><slash:comments>1</slash:comments><comments>http://arbel.net/blog/archive/2008/08/18/good-old-gdi-or-unblur-thy-text.aspx#comments</comments><description>&lt;p&gt;It's been a while since I've done anything with GDI+ (i.e. System.Drawing). System.Windows (i.e. WPF) is so much more powerful.&lt;/p&gt;
&lt;p&gt;However, there's one area where it seems the good old GDI+ can still surpass it's shiny new successor: text.&lt;/p&gt;
&lt;p&gt;There have been many complaints about text rendering in WPF. I &lt;a href="http://arbel.net/blog/archive/2007/02/02/give-me-back-my-cleartype.aspx"&gt;wrote&lt;/a&gt; about some of them myself. You can find a lot of questions on the WPF forum (&lt;a href="http://forums.msdn.microsoft.com/en-US/wpf/thread/1ad9a62a-d1a4-4ca2-a950-3b7bf5240de5/"&gt;to&lt;/a&gt; &lt;a href="http://forums.msdn.microsoft.com/en-US/wpf/thread/5289ee56-6d06-4f66-84f2-69865b6dc401/"&gt;name&lt;/a&gt; &lt;a href="http://forums.msdn.microsoft.com/en-US/wpf/thread/9e79812a-5fcc-4287-8e70-55e905b408b2"&gt;a&lt;/a&gt; &lt;a href="http://forums.msdn.microsoft.com/en-US/wpf/thread/1c8d8627-a527-4d5e-8ae3-575867e7ea47/"&gt;few&lt;/a&gt;), but not a lot of answers.&lt;/p&gt;
&lt;p&gt;The main issue is that small text is blurry and unreadable. When asked how to render &lt;b&gt;aliased&lt;/b&gt; text in WPF, the answer was: it's impossible. However, I recently encountered a whitepaper on windowsclient.net called "&lt;a href="http://windowsclient.net/wpf/white-papers/wpftextclarity.aspx"&gt;Text Clarity in WPF&lt;/a&gt;", which suggests a way to do just that. It's worth a read, even though the aliased text solution provided there is not usable (they use FormattedText, convert it to a Geometry and render the Geometry aliased using RenderOptions.SetEdgeMode() - which indeed renders aliased text, but it's not quite legible.)&lt;/p&gt;
&lt;p&gt;As you may have already guessed, my solution - &lt;b&gt;GdiTextBlock&lt;/b&gt; - relies on GDI+. We render a bitmap that contains the text and display it. As you may know, rendering bitmaps in WPF also has it's problems, which is why I use the &lt;a href="http://blogs.msdn.com/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx"&gt;Bitmap control&lt;/a&gt; in order to prevent bitmaps from becoming blurry as well.&lt;/p&gt;
&lt;p&gt;Also, in order to maintain compatibility with WPF's TextBlock, and to avoid forcing the consumers of the control to add a reference to the System.Drawing assembly, the properties and their types are all the same as TextBlock's (in fact, the dependency properties are registered using DependencyProperty.AddOwner(), which also ensures that value inheritance down the visual tree works.) CoerceValueCallback is used in many places since GDI+ doesn't support all the options available in WPF (e.g. FontStyles.Oblique, non-solid Foreground, TextAlignment.Justify.) While I've included a property called TextQuality, which allows you to set the TextRenderingHint, you'll see that only the default (SingleBitPerPixelGridFit) provides legible results.&lt;/p&gt;
&lt;p&gt;One last note about performance - this solution is not quite optimal. It creates a bitmap every measure pass. I haven't done any real performance tests, so I can't tell you what the real penalty is. Use it at your own discretion.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update: &lt;/b&gt;Fixed a small bug and added size and color selectors to demo app.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Another Update:&lt;/b&gt; Fixed a leak when using InteropBitmap. See &lt;a href="http://arbel.net/blog/archive/2008/10/22/improper-use-of-interopbitmap-can-cause-a-memory-leak.aspx"&gt;this post&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=483" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/zROoh8YN9CM" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.04.83/GdiTextBlock.zip" length="25357" type="application/zip" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/windows+forms/default.aspx">windows forms</category><feedburner:origLink>http://arbel.net/blog/archive/2008/08/18/good-old-gdi-or-unblur-thy-text.aspx</feedburner:origLink></item><item><title>Writing Methods and Classes in LINQPad</title><link>http://feedproxy.google.com/~r/arbelnet/~3/3WZ-QRIBSv4/writing-methods-and-classes-in-linqpad.aspx</link><pubDate>Mon, 18 Aug 2008 08:54:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:546</guid><dc:creator>aelij</dc:creator><slash:comments>2</slash:comments><comments>http://arbel.net/blog/archive/2008/08/18/writing-methods-and-classes-in-linqpad.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.linqpad.net/"&gt;LINQPad&lt;/a&gt; is a very useful code snippet IDE. I use it all the time to test small pieces of code. It&amp;#39;s much more convenient than opening a new Visual Studio console application. It also formats the results very nicely.&lt;/p&gt;  &lt;p&gt;What seems to be missing in LINQPad is a way to add methods or classes. After digging a bit with reflector, I came up with a simple way:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Choose &amp;quot;C# Statement(s)&amp;quot; in the Type drop-down.&lt;/li&gt;    &lt;li&gt;Write the code that LINQPad should execute.&lt;/li&gt;    &lt;li&gt;Put a closing curly-bracket (&amp;quot;}&amp;quot;) at the end.&lt;/li&gt;    &lt;li&gt;Write as many classes and methods as you like.&lt;/li&gt;    &lt;li&gt;On the last class/method, omit closing curly-bracket.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;LINQPad simply compiles the code you&amp;#39;re writing there, wrapping it in a class and a single method, which it then executes. By adding the closing bracket, we&amp;#39;re actually ending the method it defines, and start writing our own methods and classes. Since a closing bracket will be added at the end of the code block, we omit it from our code.&lt;/p&gt;  &lt;p&gt;If you want your classes to be proper (not inner), you will need to put two closing curly-brackets, and then define your class. This is important if you want to define extension methods (which must reside in a static, non-inner class).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=546" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/3WZ-QRIBSv4" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/c_2300_/default.aspx">c#</category><category domain="http://arbel.net/blog/archive/tags/tips/default.aspx">tips</category><feedburner:origLink>http://arbel.net/blog/archive/2008/08/18/writing-methods-and-classes-in-linqpad.aspx</feedburner:origLink></item><item><title>C# Partial Specialization With Extension Methods</title><link>http://feedproxy.google.com/~r/arbelnet/~3/Ln7gFKI1AKc/c-partial-specialization-with-extension-methods.aspx</link><pubDate>Thu, 22 Nov 2007 06:46:00 GMT</pubDate><guid isPermaLink="false">527a1023-13c3-4baa-b4d4-b68feed83570:423</guid><dc:creator>aelij</dc:creator><slash:comments>3</slash:comments><comments>http://arbel.net/blog/archive/2007/11/21/c-partial-specialization-with-extension-methods.aspx#comments</comments><description>&lt;p&gt;One of the things C# generics lacks (&lt;a href="http://msdn2.microsoft.com/en-us/library/c6cyy67b.aspx"&gt;compared&lt;/a&gt; to C++ templates) is &lt;a href="http://msdn2.microsoft.com/en-us/library/c401y1kb.aspx"&gt;specialization&lt;/a&gt; (neither explicit nor partial). This can be very useful in some cases where you want to perform something differently for a specific &lt;i&gt;T&lt;/i&gt; in a &lt;i&gt;Class&amp;lt;T&amp;gt;&lt;/i&gt;.&lt;/p&gt; &lt;p&gt;With C# 3.0, there is a relatively easy way to achieve this, albeit not optimal, for reasons I&amp;#39;ll specify later on. Take a look at the following piece of code:&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:10pt;line-height:115%;font-family:consolas;"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span&gt;SomeClass&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;readonly&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; items = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt;();&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;internal&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; AddInternal(T item)&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;items.Add(item);&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span&gt;EditorBrowsable&lt;/span&gt;(&lt;span&gt;EditorBrowsableState&lt;/span&gt;.Never)]&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span&gt;SomeClassExtensions&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Add&amp;lt;T&amp;gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt; &lt;span&gt;SomeClass&lt;/span&gt;&amp;lt;T&amp;gt; c, T item)&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;c.AddInternal(item);&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Add(&lt;span style="color:blue;"&gt;this&lt;/span&gt; &lt;span&gt;SomeClass&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; c, &lt;span style="color:blue;"&gt;int&lt;/span&gt; item)&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (item &amp;lt;= 0)&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;throw&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;ArgumentOutOfRangeException&lt;/span&gt;(&lt;span&gt;&amp;quot;item&amp;quot;&lt;/span&gt;, &lt;span&gt;&amp;quot;Value must be a positive integer.&amp;quot;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.Add&lt;span style="color:blue;"&gt;&lt;/span&gt;Internal(item);&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom:0pt;line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="line-height:8pt;"&gt;&lt;span style="font-size:10pt;font-family:consolas;"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Instead of placing the &lt;b&gt;Add&lt;/b&gt; method in SomeClass&amp;lt;T&amp;gt;, we put it in a static class that has &lt;a href="http://msdn2.microsoft.com/en-us/library/ms364047.aspx#cs3spec_topic3"&gt;extension methods&lt;/a&gt;. This allows the compiler to select the appropriate method according to the type parameter. (Side note: I&amp;#39;ve specified the EditorBrowsable attribute so that the class with the extensions would not appear in VS intellisense.)&lt;/p&gt; &lt;p&gt;The biggest caveat about this is that extension methods do no have access to private members, so the only option is to make the members &lt;b&gt;internal&lt;/b&gt;, which, in many cases, leads to a bad design. If only extension method classes could be written as inner classes...&lt;/p&gt; &lt;p&gt;Also, extension methods, being static, could not be virtualized. You can, however, make the internal method &amp;quot;&lt;i&gt;protected internal virtual&lt;/i&gt;&amp;quot;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=423" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/Ln7gFKI1AKc" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/pl_2700_s/default.aspx">pl's</category><category domain="http://arbel.net/blog/archive/tags/c_2300_/default.aspx">c#</category><feedburner:origLink>http://arbel.net/blog/archive/2007/11/21/c-partial-specialization-with-extension-methods.aspx</feedburner:origLink></item></channel></rss>
