<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><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>(Working Title)</description><dc:language>en</dc:language><generator>CommunityServer 2007 (Build: 20423.869)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/arbelnet" type="application/rss+xml" /><item><title>In the Zune</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/395233739/in-the-zune.aspx</link><pubDate>Wed, 17 Sep 2008 14:06:50 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:7739</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=7739</wfw:commentRss><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;img src="http://arbel.net/blog/aggbug.aspx?PostID=7739" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/395233739" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/personal/default.aspx">personal</category><category domain="http://arbel.net/blog/archive/tags/zune/default.aspx">zune</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://feeds.feedburner.com/~r/arbelnet/~3/368065515/good-old-gdi-or-unblur-thy-text.aspx</link><pubDate>Mon, 18 Aug 2008 12:35:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:7725</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=7725</wfw:commentRss><comments>http://arbel.net/blog/archive/2008/08/18/good-old-gdi-or-unblur-thy-text.aspx#comments</comments><description>&lt;p&gt;It&amp;#39;s been a while since I&amp;#39;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&amp;#39;s one area where it seems the good old GDI+ can still surpass it&amp;#39;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&amp;#39;s impossible. However, I recently encountered a whitepaper on windowsclient.net called &amp;quot;&lt;a href="http://windowsclient.net/wpf/white-papers/wpftextclarity.aspx"&gt;Text Clarity in WPF&lt;/a&gt;&amp;quot;, which suggests a way to do just that. It&amp;#39;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&amp;#39;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&amp;#39;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&amp;#39;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&amp;#39;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&amp;#39;t support all the options available in WPF (e.g. FontStyles.Oblique, non-solid Foreground, TextAlignment.Justify.) While I&amp;#39;ve included a property called TextQuality, which allows you to set the TextRenderingHint, you&amp;#39;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&amp;#39;t done any real performance tests, so I can&amp;#39;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;br /&gt;&lt;/p&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=7725" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/368065515" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/attachment/7725.ashx" 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/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://feeds.feedburner.com/~r/arbelnet/~3/368008715/writing-methods-and-classes-in-linqpad.aspx</link><pubDate>Mon, 18 Aug 2008 10:54:12 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:7724</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=7724</wfw:commentRss><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;img src="http://arbel.net/blog/aggbug.aspx?PostID=7724" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/368008715" 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://feeds.feedburner.com/~r/arbelnet/~3/188718383/c-partial-specialization-with-extension-methods.aspx</link><pubDate>Thu, 22 Nov 2007 08:46:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:3876</guid><dc:creator>aelij</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=3876</wfw:commentRss><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;img src="http://arbel.net/blog/aggbug.aspx?PostID=3876" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/188718383" 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><item><title>Vista Fish</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/157181399/vista-fish.aspx</link><pubDate>Sun, 16 Sep 2007 12:40:46 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:3168</guid><dc:creator>aelij</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=3168</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/09/16/vista-fish.aspx#comments</comments><description>&lt;p&gt;About a month ago I went on a trip to London. I just got to uploading the &lt;a href="http://picasaweb.google.com/aelija/London/"&gt;photo album&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;One of the places we visited there was the &lt;a href="http://www.londonaquarium.co.uk/"&gt;London Aquarium&lt;/a&gt;. I took a photo of some &lt;a href="http://en.wikipedia.org/wiki/Glass_catfish"&gt;glass catfish&lt;/a&gt;, which reminded me of Windows Vista:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://picasaweb.google.com/aelija/London/photo#5109980044645930562"&gt;&lt;img src="http://lh5.google.com/aelija/RupLxtp0lkI/AAAAAAAAA5E/HSEaVCLxsA0/s400/DSC01600.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=3168" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/157181399" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/windows+vista/default.aspx">windows vista</category><category domain="http://arbel.net/blog/archive/tags/personal/default.aspx">personal</category><feedburner:origLink>http://arbel.net/blog/archive/2007/09/16/vista-fish.aspx</feedburner:origLink></item><item><title>The WPF Contrib Project</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/151824556/the-wpf-contrib-project.aspx</link><pubDate>Tue, 04 Sep 2007 00:26:29 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:2965</guid><dc:creator>aelij</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=2965</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/09/03/the-wpf-contrib-project.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve been quiet for a while. Working a lot, and also burning the midnight oil, trying to bring life into this project I call... the &lt;a href="http://www.codeplex.com/wpfcontrib/"&gt;&lt;strong&gt;WPF Contrib&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Set up at CodePlex, WPF Contrib is mainly a library of reusable components.&amp;nbsp;My&amp;nbsp;goal is for it to become a true community project. Meanwhile, I invite everyone to review the code, play with the demos and send me feedback! If you want to join, the doors are open. You only need&amp;nbsp;to be a WPF expert :P and have motivation to innovate and share.&lt;/p&gt; &lt;p&gt;I&amp;#39;d also love to hear about what you would like to see in&amp;nbsp;this library. You can use the CodePlex Issue Tracker to request features (or just email me).&lt;/p&gt; &lt;p&gt;The latest&amp;nbsp;addition to the library (and one of my favorites) is the &lt;strong&gt;TaskDialog&lt;/strong&gt; control. I&amp;#39;ve been wanting to write it for some time now. Using it, you can create Task Dialogs in every WPF-supported platform. They help make a&amp;nbsp;very good UX.&lt;/p&gt; &lt;p&gt;Ælij.&lt;/p&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=2965" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/151824556" 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/c_2300_/default.aspx">c#</category><category domain="http://arbel.net/blog/archive/tags/community/default.aspx">community</category><feedburner:origLink>http://arbel.net/blog/archive/2007/09/03/the-wpf-contrib-project.aspx</feedburner:origLink></item><item><title>Yet Another Upgrade</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/128981821/yet-another-upgrade.aspx</link><pubDate>Fri, 29 Jun 2007 14:18:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:2010</guid><dc:creator>aelij</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=2010</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/06/29/yet-another-upgrade.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve upgraded to Community Server 2007. Unfortunately, the entire theme model is changed, though for the better, I don&amp;#39;t have the time to update my Aero theme, so I chose Kid Congo right now. The main reason for upgrading is the built-in &lt;a class="" href="http://www.feedburner.com/"&gt;FeedBurner&lt;/a&gt; support. It&amp;#39;s an excellent service that gives you a bit more information about your readers.&lt;/p&gt;
&lt;p&gt;I love getting responses, so don&amp;#39;t be afraid to&amp;nbsp;&lt;a class="" href="http://arbel.net/blog/contact.aspx"&gt;drop me a line&lt;/a&gt; if you got the time. :-) BTW, it seems there was some problem with the&amp;nbsp;mail settings on the server, so if you did try the contact form and never got a reply, I&amp;#39;m sorry. You can also reach me at &lt;strong&gt;aelija&lt;/strong&gt; via gmail.&lt;/p&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=2010" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/128981821" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/blog/default.aspx">blog</category><feedburner:origLink>http://arbel.net/blog/archive/2007/06/29/yet-another-upgrade.aspx</feedburner:origLink></item><item><title>New York, New York!</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/127717833/new-york-new-york.aspx</link><pubDate>Wed, 06 Jun 2007 20:53:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:1991</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=1991</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/06/06/new-york-new-york.aspx#comments</comments><description>&lt;P&gt;&lt;IMG title="At the Empire State Building" style="WIDTH:200px;HEIGHT:150px;" height=150 alt="At the Empire State Building" src="http://lh4.google.com/image/aelija/RlSKcNJPiTI/AAAAAAAAANY/dDGEYrMmr6k/DSC01314.JPG?imgmax=200" width=200 align=left&gt;I've recently visited New York City for the first time. I had an awesome trip; strolling around in the streets, visiting museums and checking out the gay scene. I did not get to see Lady Liberty, because as it turned out, you have to &lt;A title="Status of Liberty Reservations" href="http://www.statuereservations.com/"&gt;pre-register&lt;/A&gt; to get inside her.&lt;/P&gt;
&lt;P&gt;I took a few photos. The worst thing about traveling alone is that you're dependent on strangers' graces to get yourself photographed. :) But it wasn't that bad, and people have been very nice. I uploaded the entire album:&lt;/P&gt;
&lt;P&gt;&lt;A title="My photo album of New York City" href="http://picasaweb.google.com/aelija/NewYorkCity/"&gt;http://picasaweb.google.com/aelija/NewYorkCity/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The trip was my "between-jobs-vacation". I don't think I ever mentioned it on the blog, but I used to work for &lt;A href="http://www.amdocs.com/"&gt;Amdocs&lt;/A&gt;. After almost three good years, I've decided a change pace was in order, and so&amp;nbsp;I moved to a startup company named &lt;A href="http://www.varonis.com/"&gt;Varonis&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lastly, I know I don't normally write about personal stuff on the blog. That's mostly because I don't have anything interesting to report, and also because this blog has a more technological nature. I'll consider opening a second blog, should the situation merit it. The inspiration for this&amp;nbsp;came from Kevin Moore, when I recently saw his&amp;nbsp;"&lt;A href="http://www.j832.com/Review2006/"&gt;2006 Year in Review&lt;/A&gt;". He sure got a lot done that year. :-) Kevin is a program manager on the WPF team (and if you're a WPF developer you should subscribe to his &lt;A href="http://work.j832.com/"&gt;work blog&lt;/A&gt;.) For the time being I'll just add the tag "&lt;EM&gt;personal&lt;/EM&gt;" to posts of this nature.&lt;/P&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=1991" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/127717833" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/personal/default.aspx">personal</category><feedburner:origLink>http://arbel.net/blog/archive/2007/06/06/new-york-new-york.aspx</feedburner:origLink></item><item><title>Trace (route) that call!</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/127717834/trace-route-that-call.aspx</link><pubDate>Sun, 06 May 2007 21:50:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:1985</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=1985</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/05/06/trace-route-that-call.aspx#comments</comments><description>&lt;P&gt;Have you ever used &lt;STRONG&gt;EventManager.RegisterClassHandler()&lt;/STRONG&gt;? If so, make sure you know what you're doing. This method allows you to listen to events &lt;EM&gt;passing&amp;nbsp;through&lt;/EM&gt; (as I like to put it) an element (i.e.&amp;nbsp;bubbling or tunneling), regardless of the class that invoked the call. Most of the times you would call it in a static constructor, and pass it a &lt;STRONG&gt;typeof&lt;/STRONG&gt; of that class, but that is only a &lt;EM&gt;recommendation&lt;/EM&gt;. The &lt;A href="http://msdn2.microsoft.com/en-us/library/ms747183.aspx"&gt;documentation&lt;/A&gt; is a bit weak on this point.&lt;/P&gt;
&lt;P&gt;This can be a very powerful tool if you use it right. Let me demonstrate. Say you want to listen to all button clicks in your app. Normally you would put this in your main Window (by calling the above method or UIElement.AddHandler() instance method) so all the ButtonBase.Click event would bubble up to the Window and get caught.&lt;/P&gt;
&lt;P&gt;But what you can actually do is call the RegisterClassHandler from &lt;EM&gt;anywhere you like&lt;/EM&gt; (it doesn't have to be a static constructor or even&amp;nbsp;a DependencyObject. But remember that every call would add a handler, so beware of multiple registrations!):&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;&lt;FONT color=#008080&gt;EventManager&lt;/FONT&gt;.RegisterClassHandler(&lt;FONT color=#0000ff&gt;typeof&lt;/FONT&gt;(&lt;FONT color=#008080&gt;ButtonBase&lt;/FONT&gt;), &lt;FONT color=#008080&gt;ButtonBase&lt;/FONT&gt;.ClickEvent, &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;RoutedEventHandler&lt;/FONT&gt;(SomeMethod), &lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;);&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This method has no idea from where it's called, nor does it care. All that matters is that the bubbling or tunneling &lt;EM&gt;passes&amp;nbsp;through&lt;/EM&gt; an element of the type you specified.&lt;/P&gt;
&lt;P&gt;Since the Click event would always pass through a ButtonBase (well,&amp;nbsp;actually originate from one.&amp;nbsp;That is, unless you invoke it from some custom class, which doesn't make too much sense &lt;EM&gt;most&lt;/EM&gt; of the time. But I'm going off on a tangent here.) the method would be invoke for every button click. The last parameter makes sure it's invoked even if you marked the event as&amp;nbsp;handled somewhere along the way (albeit redundant in this case, since we handle it right at the root of the bubble.)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;[This post was brought to you by &lt;A href="http://www.bbc.co.uk/comedy/littlebritain/characters/marjorie.shtml"&gt;Marjorie Dawes&lt;/A&gt;. Dust, anybody, no? :-]&lt;/P&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=1985" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/127717834" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><feedburner:origLink>http://arbel.net/blog/archive/2007/05/06/trace-route-that-call.aspx</feedburner:origLink></item><item><title>i'm (making a difference)</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/127717835/IM.aspx</link><pubDate>Thu, 22 Mar 2007 22:38:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:1970</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=1970</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/03/22/IM.aspx#comments</comments><description>&lt;P&gt;Microsoft has started a new program to donate some of Messenger's ad revenue to various organizations dedicated to social causes. Join by clicking the banner on the left. You don't have to do a lot to make a difference. :-)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;(I chose &lt;A class="" href="http://www.unicef.org/"&gt;UNICEF&lt;/A&gt;.)&lt;/P&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=1970" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/127717835" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/activism/default.aspx">activism</category><feedburner:origLink>http://arbel.net/blog/archive/2007/03/22/IM.aspx</feedburner:origLink></item><item><title>Dispatch It</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/127717836/dispatch-it.aspx</link><pubDate>Fri, 16 Feb 2007 13:57:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:1960</guid><dc:creator>aelij</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=1960</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/02/16/dispatch-it.aspx#comments</comments><description>&lt;P&gt;In WPF, like most UI frameworks,&amp;nbsp;UI elements&amp;nbsp;can only be updated from the thread they were created on.&amp;nbsp;If you do background work, and want to affect the UI from a different thread, you'll have to &lt;EM&gt;dispatch&lt;/EM&gt; it. The Dispatcher class has a CheckAccess() method (which is marked as&amp;nbsp;EditorBrowsableState.Never, making it invisible to intellisense for some reason.)&lt;/P&gt;
&lt;P&gt;Here's how you would normally use it:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0080ff&gt;delegate&lt;/FONT&gt; &lt;FONT color=#0080ff&gt;void&lt;/FONT&gt; &lt;FONT color=#008080&gt;CallMeDelegate&lt;/FONT&gt;(&lt;FONT color=#008080&gt;Button&lt;/FONT&gt; b);&lt;BR&gt;&lt;FONT color=#0080ff&gt;&lt;BR&gt;&lt;FONT face=Consolas&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Consolas&gt; CallMe(&lt;FONT color=#008080&gt;Button&lt;/FONT&gt; b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0080ff&gt;if&lt;/FONT&gt; (!Dispatcher.CheckAccess())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dispatcher.Invoke(&lt;FONT color=#008080&gt;DispatcherPriority&lt;/FONT&gt;.Normal, &lt;FONT color=#0080ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;CallMeDelegate&lt;/FONT&gt;(CallMe), b);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0080ff&gt;return&lt;/FONT&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; b.Foreground = &lt;FONT color=#008080&gt;Brushes&lt;/FONT&gt;.Red;&lt;BR&gt;} &lt;/FONT&gt;
&lt;P&gt;You have to create a delegate, check for access and dispach if necessary. However, there's a smarter way, if you allow for a bit of Reflection: 
&lt;P&gt;&lt;FONT face=Consolas&gt;&lt;FONT color=#0080ff&gt;void&lt;/FONT&gt; CallMe(&lt;FONT color=#008080&gt;Button&lt;/FONT&gt; b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (&lt;FONT color=#008080&gt;UIHelper&lt;/FONT&gt;.EnsureAccess(&lt;FONT color=#008080&gt;MethodBase&lt;/FONT&gt;.GetCurrentMethod(), &lt;FONT color=#0080ff&gt;this&lt;/FONT&gt;, b))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; b.Foreground = &lt;FONT color=#008080&gt;Brushes&lt;/FONT&gt;.Red;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt; 
&lt;P&gt;What &lt;STRONG&gt;MethodBase.GetCurrentMethod()&lt;/STRONG&gt; does is actually give you a method descriptor of the calling method (quite useful for a few scenarios! Too bad they don't have a GetCallerMethod() as well...) The EnsureAccess() method then checks with the dispatcher if we're on the right thread, and if not, dynamically dispatches it.&lt;/P&gt;
&lt;P&gt;Last note: Dispatchers run a prioritized queue, so it can be handy to set the &lt;STRONG&gt;DispatcherPriority&lt;/STRONG&gt; to something other than Normal. For example, if you set a Dependency Property's value, and want to do something after the UI was updated, try dispatching it with ContextIdle priority.&lt;/P&gt;
&lt;P&gt;For more information about Dispatchers, you should&amp;nbsp;read Nick Kramer's &lt;A class="" href="http://blogs.msdn.com/nickkramer/archive/2006/03/17/553378.aspx"&gt;whitepaper&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Update:&lt;/STRONG&gt; I also discovered the existence of the&amp;nbsp;&lt;A class="" href="http://msdn2.microsoft.com/en-us/system.windows.threading.dispatchersynchronizationcontext.aspx"&gt;DispatcherSynchronizationContext&lt;/A&gt;, which inherits from the good old SynchronizationContext of .NET 2.0. The original one uses ThreadPool to queue items, while the WPF one uses the Dispatcher mechanism, which is more suitable for WPF. Note that this way you cannot specify a priority. I still believe the way I described above is slightly better.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Another Update:&lt;/STRONG&gt; I've changed a few things in the implementation. Now it checks whether the object it receives is a DispatcherObject, and if so, uses its Dispatcher instead of the Application's. This is good for (the rare) cases where your UI itself runs in more than one thread.&lt;/P&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=1960" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/127717836" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/attachment/1960.ashx" length="565" type="application/octet-stream" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/clr/default.aspx">clr</category><feedburner:origLink>http://arbel.net/blog/archive/2007/02/16/dispatch-it.aspx</feedburner:origLink></item><item><title>BitmapEffect Begone</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/127717838/bitmapeffect-begone.aspx</link><pubDate>Fri, 09 Feb 2007 14:30:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:1956</guid><dc:creator>aelij</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=1956</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/02/09/bitmapeffect-begone.aspx#comments</comments><description>&lt;P&gt;You can do really neat things with Bitmap Effects in WPF. Shadow, Bevel, Outer Glow can all have a great impact on how your application looks. But you should be aware that they don't come cheap. They are rendered in &lt;STRONG&gt;software&lt;/STRONG&gt;, which yields very poor performance. Also, &lt;A href="http://arbel.net/blog/archive/2007/02/02/give-me-back-my-cleartype.aspx"&gt;ClearType is turned off&lt;/A&gt; on elements that have them applied, so your text&amp;nbsp;becomes blurry.&lt;/P&gt;
&lt;P&gt;So, what to do?&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Abstinence&lt;/STRONG&gt;. Now, I'm not really a prude, but in this case, minimizing the use of bitmap effects can significantly improve performance. 
&lt;LI&gt;&lt;STRONG&gt;&lt;FONT color=#8000ff&gt;Apply only on simple Visuals&lt;/FONT&gt;&lt;/STRONG&gt;.&amp;nbsp;Probably the most important advice here.&amp;nbsp;If you want to apply an effect on a complex Visual, use layers! Apply the BitmapEffect on a simple &lt;STRONG&gt;Shape&lt;/STRONG&gt; (e.g. Rectangle, Path), and use a Grid, for example, to position it below your complex Visual. Do not apply the effect on a Decorator (such as a Border) that contains your Visual, since that will cause the &lt;STRONG&gt;entire visual tree&lt;/STRONG&gt; to suffer from the effect. 
&lt;LI&gt;&lt;STRONG&gt;Avoid Animations&lt;/STRONG&gt;. Especially on large Visuals, avoid animating the BitmapEffect's properties, and animating elements that have effects applied on them. TextBoxes, for example, animate the cursor frequently when they are focused, so if an element that has an effect contains a TextBox, it is forced to render itself entirely every blink. 
&lt;LI&gt;&lt;STRONG&gt;Use Bitmaps&lt;/STRONG&gt;. Yes, it's true&amp;nbsp;bitmaps don't scale like vectors, but in some places they are a very viable alternative. 
&lt;LI&gt;
&lt;DIV class=wlWriterSmartContent id=6960CE03-38FC-44df-87D4-FA4540212B06:b45ee0d3-3425-4b1d-9b0c-1369c3f35216 style="PADDING-RIGHT:10px;DISPLAY:inline;PADDING-LEFT:10px;FLOAT:right;PADDING-BOTTOM:10px;MARGIN:0px;PADDING-TOP:10px;TEXT-ALIGN:center;"&gt;&lt;IMG style="WIDTH:132px;HEIGHT:132px;" alt="" src="http://arbel.net/blog/photos/aelij/images/1955/original.aspx"&gt;&lt;BR&gt;How nine-grid images work&lt;/DIV&gt;&lt;STRONG&gt;Use Nine-Grid Images&lt;/STRONG&gt;. Have you ever wondered how the themes on XP and Vista work? You can stretch a button as much as you like and it still looks good. They use nine grid images. The idea is very simple: divide the image to nine areas and stretch it as shown in the illustration. The effect is that the proportions of the corners&amp;nbsp;and borders&amp;nbsp;are always maintained. I've attached a project with a NineGridBorder class that can be used to draw these images. After I wrote it, I discovered &lt;A href="http://wpf.netfx3.com/files/folders/code_snippets/entry7532.aspx"&gt;another implementation&lt;/A&gt;, so I took the best of both of them.&amp;nbsp; 
&lt;LI&gt;&lt;STRONG&gt;Vectorize&lt;/STRONG&gt;. When exporting from &lt;A href="http://www.microsoft.com/products/expression/en/Expression-Design/"&gt;Expression Design&lt;/A&gt; to XAML, you have the option to either rasterize (i.e. create a bitmap) or vectorize some of the effects. For example, when applying soft edges to a vector drawing, ED exporter will create a Canvas that contains a few layers with different opacities, which will simulate the effect. 
&lt;LI&gt;&lt;STRONG&gt;Use WpfPerf&lt;/STRONG&gt;. This is a great tool that comes with the Windows SDK. You can use Perforator to detect whether your careless colleagues used BitmapEffects or other ill-advised features that may&amp;nbsp;hinder your application's performance. Check "&lt;EM&gt;Draw software rendering with purple tint&lt;/EM&gt;" to immediately view what causes problems. Try to resize the window or run animations while this is checked.&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=1956" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/127717838" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/attachment/1956.ashx" length="36588" type="application/octet-stream" /><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><feedburner:origLink>http://arbel.net/blog/archive/2007/02/09/bitmapeffect-begone.aspx</feedburner:origLink></item><item><title>Give me back my ClearType</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/127717840/give-me-back-my-cleartype.aspx</link><pubDate>Sat, 03 Feb 2007 08:55:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:1778</guid><dc:creator>aelij</dc:creator><slash:comments>9</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=1778</wfw:commentRss><comments>http://arbel.net/blog/archive/2007/02/02/give-me-back-my-cleartype.aspx#comments</comments><description>&lt;P&gt;WPF has a separate &lt;A href="http://www.microsoft.com/typography/cleartypeinfo.mspx"&gt;ClearType&lt;/A&gt; rendering system, which is better than GDI's (mostly because it also does y-direction antialiasing; read more &lt;A href="http://msdn2.microsoft.com/en-us/library/ms749295.aspx"&gt;here&lt;/A&gt;&amp;nbsp;and in the &lt;A href="http://blogs.msdn.com/text/"&gt;WPF Text Blog&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;However, there are some situations in which WPF cannot use ClearType, and has to resort to grayscale antialiasing (it cannot render &lt;EM&gt;aliased&lt;/EM&gt; text because of its pixel independent architecture) which comes out pretty blurry for small text sizes, in my opinion.&lt;/P&gt;
&lt;P&gt;Here's when WPF can't use ClearType:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Window/Popup &lt;STRONG&gt;AllowsTransparency&lt;/STRONG&gt; = true. This creates an HwndSource with UsesPerPixelOpacity = true (i.e. a layered window.) All context menus and tooltips in WPF have this turned on with no trivial way of turning it off. More on this later on. 
&lt;LI&gt;Visual (or some ancestor) has a &lt;STRONG&gt;Bitmap Effect&lt;/STRONG&gt;. (Sidebar: You should really&amp;nbsp;avoid&amp;nbsp;using those on any complex Visual. They yield&amp;nbsp;the worse performance. If you want a shadow under something, take an empty Rectangle or some other Shape, apply the effect on it and put it under the more complex Visual.) 
&lt;LI&gt;Text&amp;nbsp;from another Visual&amp;nbsp;appearing in&amp;nbsp;a &lt;STRONG&gt;VisualBrush&lt;/STRONG&gt;. 
&lt;LI&gt;Rendering a Visual using &lt;STRONG&gt;RenderTargetBitmap&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Setting the &lt;STRONG&gt;HwndTarget.BackgroundColor&lt;/STRONG&gt; to Transparent (needed for extending DWM glass to client area.)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Also, there are &lt;STRONG&gt;registry&lt;/STRONG&gt; settings that can enable, disable or configure ClearType, both system-wide&amp;nbsp;and &lt;A href="http://msdn2.microsoft.com/en-us/library/ms749295.aspx"&gt;WPF-specific&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;In Vista, ClearType is turned on by default, so WPF also uses it. In XP, however, it is not. And so by default WPF is rendering grayscaled text. From my experience, ClearType is better even on CRT monitors, so when I write WPF applications, if ClearType is off, I display a message recommending to turn it on, and make the WPF-specific registry changes.&lt;/P&gt;
&lt;P&gt;Now, for my woes. Take a look at these screenshots:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class=wlWriterSmartContent id=6960CE03-38FC-44df-87D4-FA4540212B06:07aa1e71-d574-4408-be8f-9278d6a2b7c0 style="PADDING-RIGHT:0px;DISPLAY:inline;PADDING-LEFT:0px;FLOAT:none;PADDING-BOTTOM:0px;MARGIN:0px;PADDING-TOP:0px;"&gt;&lt;IMG style="WIDTH:570px;HEIGHT:240px;" alt="" src="http://arbel.net/blog/photos/aelij/images/1024/original.aspx"&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The left one is with ClearType, the right&amp;nbsp;one without.&amp;nbsp;I hope the difference is clear. As I mentioned earlier, context menus, tooltips&amp;nbsp;and combo box use the Popup class, which has the AllowsTransparancy set to true. This is &lt;EM&gt;hardcoded&lt;/EM&gt;. The reason for this is obvious: the designers of WPF wanted you to be able to customize these windows as you saw fit. And it can truly be used to do wonderful things (see this &lt;A href="http://blois.us/blog/2006/09/styled-tooltips-it-took-me-while-to.html"&gt;styled tooltips example&lt;/A&gt;. Quite effortless, if you consider what you had to do to get this done in Win32.) But I think &lt;STRONG&gt;readability&lt;/STRONG&gt; is more important&amp;nbsp;in these cases. At any rate, this should be configurable.&lt;/P&gt;
&lt;P&gt;Aside from the text issues, layered windows' performance is much worse than normal windows. Even under Vista, where they are hardware-accelerated, the menu highlight is lagging after the mouse sometimes.&lt;/P&gt;
&lt;P&gt;Frustrated a bit, I came up with a somewhat&lt;EM&gt;&amp;nbsp;dubious&lt;/EM&gt; solution to these issues.&lt;/P&gt;
&lt;P&gt;For ComboBoxes and MenuItems, I created an attached Dependency Property, which, when attached to a control, attempts to find the "PART_Popup" in its template and set its AllowsTransparency property to false. Caveats:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;You lose the animation when opening a combo box (slide) or a menu (fade). 
&lt;LI&gt;You lose the shadow. 
&lt;LI&gt;If you apply a transform, the popup will not match it (Then again, who would want a skewed combo box? But a rotated menu might be useful.)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;For ContextMenus and ToolTips, I create subclasses, overrode IsOpenProperty metadata and added an additional changed handler. The &lt;A href="http://msdn2.microsoft.com/en-us/library/ms751554.aspx"&gt;Framework Property Metadata&lt;/A&gt;&amp;nbsp;documentation states that:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;The actual property system behavior for PropertyChangedCallback is that implementations for all metadata owners in the hierarchy are retained and added to a table, with order of execution by the property system being that the &lt;/EM&gt;&lt;STRONG&gt;most derived class's callbacks are invoked first&lt;/STRONG&gt;&lt;EM&gt;. Inherited callbacks run only once, counting as being owned by the class that placed them in metadata.&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Either I don't understand it well or the documentation is wrong, since the method I specified ran &lt;EM&gt;after&lt;/EM&gt; the original method. To solve that,&amp;nbsp;I wrote a class that inherits FrameworkPropertyMetadata and reverses the execution order, so I could create the Popup myself without setting the AllowsTransparency to true. Caveats:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;I use reflection to get to private fields. Yes, I know it's bad... :P 
&lt;LI&gt;Again, you lose shadows and animations. 
&lt;LI&gt;Tooltips have rounded corners by default (at least on Vista) so you'll see gray 1-pixel dots on the corners. But you can change the tooltip's default style to get rid of this.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I tried to regain the shadows using cheaper means (CS_DROPSHADOW window class style) but it's difficult to reach.&lt;/P&gt;
&lt;P&gt;You may think I'm crazy to go through all of that just for a few blurry texts, but I think this really impacts the overall readability of my applications.&lt;/P&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=1778" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/127717840" height="1" width="1"/&gt;</description><enclosure url="http://arbel.net/blog/attachment/1778.ashx" length="25817" type="application/octet-stream" /><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><feedburner:origLink>http://arbel.net/blog/archive/2007/02/02/give-me-back-my-cleartype.aspx</feedburner:origLink></item><item><title>Anonymous Comments Enabled</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/127717842/Anonymous-Comments-Enabled.aspx</link><pubDate>Sun, 19 Nov 2006 00:30:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:54</guid><dc:creator>aelij</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=54</wfw:commentRss><comments>http://arbel.net/blog/archive/2006/11/18/Anonymous-Comments-Enabled.aspx#comments</comments><description>&lt;P&gt;I didn't notice that when I set up the blog, anonymous comments were disabled!&lt;/P&gt;
&lt;P&gt;I just enabled them, and I hope this won't lead to a spam attack. Maybe I should add a &lt;A href="http://dbvt.com/files/folders/addons/entry5198.aspx"&gt;captcha&lt;/A&gt;, though I don't care much for that method.&lt;/P&gt;
&lt;P&gt;Anyway, now you can feel free to comment on my posts. :P&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Update:&lt;/STRONG&gt; Comment spam was unbearable... Added &lt;A class="" href="http://trefry.net/blogs/michael/archive/2005/05/11/182.aspx"&gt;this captcha&lt;/A&gt;. Still have hundreds of junk comments to delete :-|&lt;/P&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=54" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/127717842" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/blog/default.aspx">blog</category><feedburner:origLink>http://arbel.net/blog/archive/2006/11/18/Anonymous-Comments-Enabled.aspx</feedburner:origLink></item><item><title>I Got Rhythm Now Available in XBAP!</title><link>http://feeds.feedburner.com/~r/arbelnet/~3/127717843/I-Got-Rhythm-Now-Available-in-XBAP_2100_.aspx</link><pubDate>Wed, 15 Nov 2006 23:25:00 GMT</pubDate><guid isPermaLink="false">39a06390-e82b-4c3a-ad8f-755b89b96660:53</guid><dc:creator>aelij</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://arbel.net/blog/rsscomments.aspx?PostID=53</wfw:commentRss><comments>http://arbel.net/blog/archive/2006/11/15/I-Got-Rhythm-Now-Available-in-XBAP_2100_.aspx#comments</comments><description>&lt;p&gt;This is not quite ready, but I just had to give you a sneak peek:&lt;/p&gt;&lt;p&gt;&lt;a href="http://arbel.net/blogx/blog.xbap"&gt;http://arbel.net/blogx/blog.xbap&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I believe this is the first blog presented in XBAP. The possibilities are endless... The tag cloud uses &lt;a href="http://blogs.msdn.com/okoboji/"&gt;Kevin Moore&lt;/a&gt;&amp;#39;s &lt;a href="http://blogs.msdn.com/okoboji/archive/2006/11/10/bag-o-tricks-rtm-edition.aspx"&gt;Bag-O-Tricks&lt;/a&gt;. The HTML is being rendered by a modified version of the Windows SDK Team&amp;#39;s &lt;a href="http://blogs.msdn.com/wpfsdk/archive/2006/05/25/606317.aspx"&gt;HTML to Flow Document&lt;/a&gt; converter.&lt;/p&gt;&lt;p&gt;I&amp;#39;ve written a Community Server web service that allows me to pull all the data and bind to it.&lt;/p&gt;&lt;p&gt;Note that this was compiled in RC1 (waiting for Vista RTM in MSDN) but it seems to work on .NET 3.0 RTM.&lt;/p&gt;&lt;img src="http://arbel.net/blog/aggbug.aspx?PostID=53" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/arbelnet/~4/127717843" height="1" width="1"/&gt;</description><category domain="http://arbel.net/blog/archive/tags/blog/default.aspx">blog</category><category domain="http://arbel.net/blog/archive/tags/wpf/default.aspx">wpf</category><category domain="http://arbel.net/blog/archive/tags/xbap/default.aspx">xbap</category><feedburner:origLink>http://arbel.net/blog/archive/2006/11/15/I-Got-Rhythm-Now-Available-in-XBAP_2100_.aspx</feedburner:origLink></item></channel></rss>
