<?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:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>JoshEinstein.com</title>
	
	<link>http://www.josheinstein.com/blog</link>
	<description>Home</description>
	<lastBuildDate>Mon, 08 Mar 2010 21:07:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/josheinstein" /><feedburner:info uri="josheinstein" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjosheinstein" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjosheinstein" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/josheinstein" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjosheinstein" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fjosheinstein" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fjosheinstein" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><item>
		<title>WPF : Using Markup Extensions to generate content with icons</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/eHj_27BhDEQ/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/03/wpf-using-markup-extensions-to-generate-content-with-icons/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 21:03:43 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/03/wpf-using-markup-extensions-to-generate-content-with-icons/</guid>
		<description><![CDATA[It&#8217;s way too hard to get an image next to the text content of a Button, TextBlock, ListBoxItem, TreeViewItem, etc. Coming from a Windows Forms background where many controls had an Image property for displaying a small glyph next to text content, I am constantly frustrated by the verbose XAML required to achieve the same [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s way too hard to get an image next to the text content of a Button, TextBlock, ListBoxItem, TreeViewItem, etc. Coming from a Windows Forms background where many controls had an Image property for displaying a small glyph next to text content, I am constantly frustrated by the verbose XAML required to achieve the same in WPF and Silverlight.</p>
<pre class="brush: xml">&lt;StackPanel&gt;
    &lt;Button&gt;
        &lt;DockPanel&gt;
            &lt;Image Source=&quot;Images/Alert.png&quot; /&gt;
            &lt;TextBlock Text=&quot;Alerts&quot; /&gt;
        &lt;/DockPanel&gt;
    &lt;/Button&gt;
    &lt;Button&gt;
        &lt;DockPanel&gt;
            &lt;Image Source=&quot;Images/Color-Blue.png&quot; /&gt;
            &lt;TextBlock Text=&quot;Blue Category&quot; /&gt;
        &lt;/DockPanel&gt;
    &lt;/Button&gt;
    &lt;Button&gt;
        &lt;DockPanel&gt;
            &lt;Image Source=&quot;Images/Color-Green.png&quot; /&gt;
            &lt;TextBlock Text=&quot;Green Category&quot; /&gt;
        &lt;/DockPanel&gt;
    &lt;/Button&gt;
    &lt;Button&gt;
        &lt;DockPanel&gt;
            &lt;Image Source=&quot;Images/Color-Red.png&quot; /&gt;
            &lt;TextBlock Text=&quot;Red Category&quot; /&gt;
        &lt;/DockPanel&gt;
    &lt;/Button&gt;
&lt;/StackPanel&gt;</pre>
<p>Well using a WPF markup extension in XAML we can make the code look a little less clunky. Markup extensions (which derive from System.Windows.MarkupExtension) are instantiated similarly to the way attributes are declared in C#. That is to say, there can be positional and/or named parameters. By overriding the ProvideValue you can use those parameters to construct whatever object structure you want and return it. The XAML parser will use this in place of your markup extension when it finds it.</p>
<pre class="brush: xml">&lt;StackPanel&gt;
    &lt;Button Content=&quot;{e:Content Alerts, Image=Images/Alert.png}&quot; /&gt;
    &lt;Button Content=&quot;{e:Content Blue Category, Image=Images/Color-Blue.png}&quot; /&gt;
    &lt;Button Content=&quot;{e:Content Green Category, Image=Images/Color-Green.png}&quot; /&gt;
    &lt;Button Content=&quot;{e:Content Red Category, Image=Images/Color-Red.png}&quot; /&gt;
&lt;/StackPanel&gt;</pre>
<p>Unfortunately Silverlight does not allow you to create custom markup extensions yet so this same technique cannot be applied to Silverlight where the situation is arguably worse with all the toolkit namespaces and such.</p>
<p>The code for the ContentExtension is very straightforward so I&#8217;m just going to add it to the end of the post instead of going through the hassle of uploading a project. Enjoy.</p>
<pre class="brush: csharp; collapse: true">/// &lt;summary&gt;
/// A XAML Markup Extension that allows you to combine simple text content with an image
/// alongside instead of having to manually nest the image and text in a panel.
/// &lt;/summary&gt;
public class ContentExtension : MarkupExtension
{

    // constructor with positional parameter
    public ContentExtension( string text )
    {
        Text = text;
    }

    // image must be specified as a named parameter
    public ImageSource Image
    {
        get;
        set;
    }

    public string Text
    {
        get;
        set;
    }

    public override object ProvideValue( IServiceProvider serviceProvider )
    {
        return new DockPanel {
            Children = {
                new Image {
                    Source = Image,
                    Stretch = Stretch.None,
                    VerticalAlignment = VerticalAlignment.Center,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    Margin = new Thickness( 5 )
                },
                new TextBlock {
                    VerticalAlignment = VerticalAlignment.Center,
                    Text = Text
                }
            }
        };
    }

}   // class
</pre>
<p><img title="Content Markup Extension" alt="Content Markup Extension" align="center" src="http://www.josheinstein.com/blog/wp-content/uploads/2010/03/ContentExtension.png" /></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F03%2Fwpf-using-markup-extensions-to-generate-content-with-icons%2F&amp;linkname=WPF%20%3A%20Using%20Markup%20Extensions%20to%20generate%20content%20with%20icons"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/eHj_27BhDEQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/03/wpf-using-markup-extensions-to-generate-content-with-icons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/03/wpf-using-markup-extensions-to-generate-content-with-icons/</feedburner:origLink></item>
		<item>
		<title>Windows 7 PowerShell Tip</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/bP_kIbKH2h0/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/03/windows-7-powershell-tip/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 15:43:43 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/03/windows-7-powershell-tip/</guid>
		<description><![CDATA[If you&#8217;re a system administrator (or like many developers), chances are you use PowerShell a lot and have the PowerShell console or PowerShell ISE on your Windows 7 taskbar. On Windows Vista and on Windows Server 2008 prior to R2 I was annoyed by having both ISE and console on the quick launch bar or [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a system administrator (or like many developers), chances are you use PowerShell a lot and have the PowerShell console or PowerShell ISE on your Windows 7 taskbar. On Windows Vista and on Windows Server 2008 prior to R2 I was annoyed by having both ISE and console on the quick launch bar or pinned to the start menu.</p>
<p>In Windows 7 here&#8217;s a neat tip. Pin the PowerShell console to the taskbar and not the PowerShell ISE. When you right click on the icon, you get a handy jump list which includes not only &quot;Run As Administrator&quot; but also &quot;Open PowerShell ISE&quot;. All in the space of a single tile.</p>
<p align="center"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Windows PowerShell Jump List" border="0" alt="Windows PowerShell Jump List" src="http://www.josheinstein.com/blog/wp-content/uploads/2010/03/image.png" width="421" height="315" /></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F03%2Fwindows-7-powershell-tip%2F&amp;linkname=Windows%207%20PowerShell%20Tip"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/bP_kIbKH2h0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/03/windows-7-powershell-tip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/03/windows-7-powershell-tip/</feedburner:origLink></item>
		<item>
		<title>Accept simple mathematical expressions in Silverlight text boxes</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/L1jA0roS5Lk/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/03/mathevalconverter/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 04:26:13 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/?p=160</guid>
		<description><![CDATA[Download MathEvalConverter.zip
Background
With the name Einstein, people typically assume I&#8217;m good at math. I have the utmost respect for the physicists and mathemeticians of our time, prior, and beyond. But to be honest, math is not my strong suit. In fact I have great difficulty simply adding or subtracting numbers without the use of a calculator. [...]]]></description>
			<content:encoded><![CDATA[<p>Download <a href="http://www.josheinstein.com/silverlight/mathevalconverter/mathevalconverter.zip">MathEvalConverter.zip</a></p>
<h2>Background</h2>
<p>With the name Einstein, people typically assume I&#8217;m good at math. I have the utmost respect for the physicists and mathemeticians of our time, prior, and beyond. But to be honest, math is not my strong suit. In fact I have great difficulty simply adding or subtracting numbers without the use of a calculator. This deficiency actually worked to my advantage last month when I was observing the users of an application I had recently dogfed.</p>
<p>The application had several numeric input fields that took in costs, prices, commissions, etc. Like any run of the mill business application, these inputs affected various calculations that updated the UI accordingly. But while observing the users I kept noticing a very peculiar behavior. When they would type into a box for Cost, Price, etc. they would whip out a small desk calculator and add up some numbers before typing them into the box.</p>
<p>As it turns out, the values I took for granted as a pre-calculated input often require various &quot;in-your-head&quot; steps before arriving at what I assumed was a known &quot;input&quot;.</p>
<blockquote><p>&quot;The cost of the product is normally $15 but I knocked it down by $3.&quot;</p>
</blockquote>
<p>Given my mathematical challenges, I was very sympathetic to this situation. I don&#8217;t own a desk calculator but I am very familiar with the Start -&gt; Run -&gt; calc.exe ceremony. If I happen to have a PowerShell window open I&#8217;ll use that instead.</p>
<p>Did I miss a key requirement? Should there have been more input fields? Not really because the calculation steps are not necessarily formal aspects of the system. They&#8217;re mostly things people might normally do in their head had they not happen to have a calculator in front of them. And the type of calculations they perform vary from case to case.</p>
<p>Then I remembered&#8230; I encounter this same situation all the time when working in Excel. But Excel&#8217;s primary feature is the fact that you can type a &quot;formula&quot; or expression anywhere you&#8217;d put a constant value. Wouldn&#8217;t it be great if the text boxes in my application offered the same functionality? Well by the end of this post, they will!</p>
<h2>The Plan</h2>
<p>The idea is that my input boxes would allow the user to enter a number as usual, but if they entered an expression such as &quot;2+2&quot;, committing the value would enter &quot;4&quot; into the field. The expression doesn&#8217;t need to be preserved, so the value of the field can still be backed by a simple number. Also, I only need to implement very basic expressions. I&#8217;ll stick to addition, subtraction, multiplication, division, grouping, and any combination of the above.</p>
<p>I thought about where I might add this functionality. I could subclass TextBox, but then the cells in a DataGrid would need to be addressed separately. I could probably have done it with a behavior but that didn&#8217;t seem appropriate either. In the end I decided to implement an IValueConverter. I was already using one to provide currency formatting in the control.</p>
<p>The end result would look like the working example shown below.</p>
<div align="center"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" style="width: 350px; height: 350px"><param name="source" value="http://www.josheinstein.com/Silverlight/MathEvalConverter/MathEvalConverterDemo.xap" /><param name="background" value="white" /><param name="minRuntimeVersion" value="3.0.40818.0" /><param name="autoUpgrade" value="true" /><a href="http://go.microsoft.com/fwlink/?LinkID=149156&amp;v=3.0.40818.0">             <br />               <img alt="Get Microsoft Silverlight" src="http://go.microsoft.com/fwlink/?LinkId=108181" style="border-style: none" />             <br />           </a><br />       </object></div>
<h2>The Math Parser</h2>
<p>Because this application was an in-browser Silverlight application, I could avoid having to write my own math parser by taking advantage of the HTML bridge and the Eval() method. In short, I would pass the expression to the JavaScript engine to evaluate as if it were a line of code. Of course, I would need to validate the input first to ensure a malicious user could not take advantage of this fact.</p>
<p>To isolate this shortcut into replacable component, I extracted an IMathEvaluator interface that would be defined as follows.</p>
<pre class="brush: csharp">public interface IMathEvaluator {
    bool TryEvaluate(string expression, out decimal value);
}</pre>
<p>This allows me to include my JavaScript hack for the sake of this post while admitting that a less lazy developer could substitute a better implementation. One nice thing about this implementation is that I don&#8217;t need to determine if the user entered a number or expression. Even if they entered a simple number like 1, I still treat it as an expression.</p>
<p>The implementation is pretty simple too. It simply checks the input against a Regex to ensure it&#8217;s not going to pass some malicious payload to the JavaScript engine then calls Eval() via the Silverlight HTML bridge.</p>
<pre class="brush: csharp">public sealed class JScriptMathEvaluator : IMathEvaluator
{
    public bool TryEvaluate(string expression, out decimal value ) {

        // When there's no text, just return zero
        if ( expression == null || expression.Trim().Length == 0 ) {
            value = 0;
            return true;
        }

        // remove currency symbols and commas
        // these are added when we format the number but we want to remove them before
        // parsing the text value because it would invalidate the JavaScript syntax
        var numberFormat = CultureInfo.CurrentCulture.NumberFormat;
        expression = expression.Replace( numberFormat.CurrencySymbol, &quot;&quot; );
        expression = expression.Replace( numberFormat.CurrencyGroupSeparator, &quot;&quot; );
        expression = expression.Replace( numberFormat.NumberGroupSeparator, &quot;&quot; );
        expression = expression.Replace( numberFormat.PercentGroupSeparator, &quot;&quot; );

        // Ensure that a simple expression consisting of only digits,
        // parenthases, and four operators (+, -, *, /) are entered.
        // Never pass non-validated input to JavaScript!
        if (Regex.IsMatch(expression, @&quot;^[0-9\.\+\-\*\/\(\)\s]+$&quot; ) ) {

            try {
                object eval = System.Windows.Browser.HtmlPage.Window.Eval( expression );
                value = Convert.ToDecimal(eval);
                return true;
            }   // try
            catch ( Exception ex ) {
                // trace exception or whatever
                // but let the function return false
            }   // catch

        }   // if

        value = 0;
        return false;

    }
}</pre>
<h2>The Value Converter</h2>
<p>In order to convert the user&#8217;s input into a number I&#8217;ll need to invoke a conversion process when the value of the TextBox changes. I was already doing this with a FormattingConverter that would apply currency formatting to the number and then parse the text value with NumberStyles.</p>
<p>So let&#8217;s just derive a class from FormattingConverter with support for the ConvertBack method. We&#8217;ll call it MathEvalConverter.</p>
<pre class="brush: csharp">public sealed class MathEvalConverter : FormattingConverter
{

    public MathEvalConverter( )
    {
        MathEvaluator = new JScriptMathEvaluator( );
    }

    public IMathEvaluator MathEvaluator
    {
        get;
        set;
    }

    protected override object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
    {

        // View -&gt; ViewModel

        string expression = System.Convert.ToString( value );

        decimal numberValue;
        if ( MathEvaluator != null &amp;&amp; MathEvaluator.TryEvaluate( expression, out numberValue ) ) {
            return numberValue;
        }   // if

        // We couldn't parse the expression.
        // Let silverlight reject it because:
        //   - if we throw an exception, it Silverlight bypasses validation events
        //   - if we return DependencyProperty.UnsetValue, the input will just disappear with no error!
        // By returning the unconverted value back to Silverlight, at least they'll see a conversion error.

        return base.ConvertBack( value, targetType, parameter, culture );

    }

}   // class</pre>
<p>The converter doesn&#8217;t specifically use the JavaScript implementation. It goes through the IMathEvaluator interface which happens to be implemented by JScriptMathEvaluator.</p>
<h2>MathEvalConverter In Action</h2>
<p>We can apply the MathEvalConverter to any two-way binding between a numeric property on the binding source and a string property on a control. Since it derives from FormattingConverter, we can supply a format string to pretty format the numbers.</p>
<pre class="brush: xml">&lt;UserControl&gt;
    &lt;FrameworkElement.Resources&gt;
        &lt;Local:MathEvalConverter x:Key=&quot;Eval&quot; Format=&quot;C2&quot; /&gt;
        &lt;Local:FormattingConverter x:Key=&quot;Date&quot; Format=&quot;d&quot; /&gt;
    &lt;/FrameworkElement.Resources&gt;
    &lt;Form:DataForm Header=&quot;Expense Report&quot;&gt;
        &lt;StackPanel&gt;

            &lt;Form:DataField Label=&quot;Reported By&quot;&gt;
                &lt;TextBox Text=&quot;{Binding Name, Mode=TwoWay}&quot; /&gt;
            &lt;/Form:DataField&gt;

            &lt;Form:DataField Label=&quot;Expense Date&quot;&gt;
                &lt;TextBox Text=&quot;{Binding Date, Converter={StaticResource Date}, Mode=TwoWay}&quot; /&gt;
            &lt;/Form:DataField&gt;

            &lt;Form:DataField Label=&quot;Meals&quot;&gt;
                &lt;TextBox Text=&quot;{Binding Meals, Converter={StaticResource Eval}, Mode=TwoWay}&quot; /&gt;
            &lt;/Form:DataField&gt;

        &lt;/StackPanel&gt;
    &lt;/Form:DataForm&gt;
&lt;/UserControl&gt;</pre>
<h2>Summary</h2>
<p>Enough talk. Download the code, and let me know what you think. I have no idea if anyone finds these posts useful if you don&#8217;t post comments!</p>
<p>Download <a href="http://www.josheinstein.com/silverlight/mathevalconverter/mathevalconverter.zip">MathEvalConverter.zip</a></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F03%2Fmathevalconverter%2F&amp;linkname=Accept%20simple%20mathematical%20expressions%20in%20Silverlight%20text%20boxes"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/L1jA0roS5Lk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/03/mathevalconverter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/03/mathevalconverter/</feedburner:origLink></item>
		<item>
		<title>Excellent WPF performance tips on the Visual Studio Blog</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/pfEax13Dl-w/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/03/excellent-wpf-performance-tips-on-the-visual-studio-blog/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 14:54:39 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/03/excellent-wpf-performance-tips-on-the-visual-studio-blog/</guid>
		<description><![CDATA[These aren&#8217;t your typical, obvious tips. Head over to the Visual Studio Blog to learn some WPF performance tips that the team picked up during the development of Visual Studio 2010. Some of the performance issues required changes to WPF that we all will benefit from in .NET 4. Others are clever ways to work [...]]]></description>
			<content:encoded><![CDATA[<p>These aren&#8217;t your typical, obvious tips. Head over to the <a href="http://blogs.msdn.com/visualstudio/archive/2010/03/02/wpf-in-visual-studio-2010-part-2-performance-tuning.aspx" target="_blank">Visual Studio Blog</a> to learn some WPF performance tips that the team picked up during the development of Visual Studio 2010. Some of the performance issues required changes to WPF that we all will benefit from in .NET 4. Others are clever ways to work around various idiosyncracies of WPF.</p>
<p>Take this for example.</p>
<blockquote><p><strong>Optimize for Remote Desktop scenarios : Use scrolling hint</strong></p>
<p>Also on the topic of Remote Desktop, one area where we needed additional support from WPF was for scrolling in the text editor. As I mentioned above, when in a remote session, all WPF content is transmitted as a bitmap. When the text editor scrolls by a line, that means that the entire contents of the editor region needs to be retransmitted as a bitmap. This, of course can be expensive – the larger the area of the text view, the larger the bitmap and the slower it will be. Fortunately, WPF 4.0 now knows how to issue a “ScrollWindow” command to the remote desktop session which drastically reduces the amount of information transferred across the wire. Only the scroll operation itself (very short) and the newly-exposed line need to be transmitted. To take advantage of this new operation, you need to use the property <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.visual.visualscrollableareaclip(VS.100).aspx">VisualScrollableAreaClip</a>. There are some restrictions on where this can be used, so read the documentation carefully.</p>
</blockquote>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F03%2Fexcellent-wpf-performance-tips-on-the-visual-studio-blog%2F&amp;linkname=Excellent%20WPF%20performance%20tips%20on%20the%20Visual%20Studio%20Blog"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/pfEax13Dl-w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/03/excellent-wpf-performance-tips-on-the-visual-studio-blog/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/03/excellent-wpf-performance-tips-on-the-visual-studio-blog/</feedburner:origLink></item>
		<item>
		<title>LINQ for PowerShell</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/bA8Oye3L9mE/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/linq-for-powershell/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 06:18:13 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/02/linq-for-powershell/</guid>
		<description><![CDATA[Download LINQ.psm1
I&#8217;m gonna start off by saying the module I&#8217;m posting about does not follow the PowerShell naming guidelines. In fact, not only does it use non-standard verb names, but the &#34;verb&#34; part of all the function names aren&#8217;t even verbs. I hate breaking the rules like this but the Verb-Noun naming couldn&#8217;t really group [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://cid-89e05724af67a39e.skydrive.live.com/browse.aspx/PowerShell/Modules/LINQ" target="_blank">Download LINQ.psm1</a></p>
<p><em>I&#8217;m gonna start off by saying the module I&#8217;m posting about does <strong>not</strong> follow the PowerShell naming guidelines. In fact, not only does it use non-standard verb names, but the &quot;verb&quot; part of all the function names aren&#8217;t even verbs. I hate breaking the rules like this but the Verb-Noun naming couldn&#8217;t really group these functions together the way I wanted and naming them correctly would have been very difficult. So feel free to rename as needed.</em></p>
<p>A while back I posted about a <a href="http://www.josheinstein.com/blog/index.php/2008/12/convertto-dictionary/">ConvertTo-Dictionary PowerShell function</a>. This handy little function would take an input object from the pipeline and populate a Hashtable using a key selector and optional value selector. Very similar to how LINQ&#8217;s ToDictionary method works. It uses ScriptBlocks in the same way C# uses lambda expressions. There is one very nice trick in the module. A function called Invoke-ScriptBlock that shows how to inject a $_ (dollar underbar) variable into a ScriptBlock&#8217;s scope when invoking it. This is very handy for simulating lambdas in PowerShell functions.</p>
<p>Anyhow, over time I added several more LINQ-like functions and then I just went all out and tried to implement all the most popular LINQ methods. I managed to get a good deal done although there is still some documentation work needed. Some of the functions may seem redundant because they have nearly the same functionality as existing PowerShell cmdlets. In these cases it&#8217;s usually because I thought it could be more LINQ-like. For example I have Linq-Min because it&#8217;s simpler and more flexible than Measure-Object. But I didn&#8217;t duplicate Where-Object because there was no point.</p>
<p>The following code example shows how you might use these functions. Not all of them are shown. Notice the lamba-like syntax for predicates, selectors, etc. They also make use of the convenient $_ (dollar underbar) variable to represent the &quot;current item&quot; which makes them more consistent with Where-Object, Foreach-Object, etc.</p>
<pre class="brush: text;">Import-Module LINQ

function Assert-AreEqual($Expected, $Actual) {
    if (@(Compare-Object $Expected $Actual -SyncWindow 0).Length) {
        $OFS = ','
        Write-Error &quot;Assert-AreEqual Failed: Expected=($Expected), Actual=($Actual)&quot;
    }
}

# All
Assert-AreEqual -Expected ($true)   -Actual (1..5 | Linq-All { $_ -gt 0 })
Assert-AreEqual -Expected ($false)  -Actual (1..5 | Linq-All { $_ -gt 6 })
Assert-AreEqual -Expected ($true)   -Actual (@()  | Linq-All { $_ -gt 6 })

# Any
Assert-AreEqual -Expected ($true)   -Actual (1..5 | Linq-Any)
Assert-AreEqual -Expected ($false)  -Actual (@()  | Linq-Any)
Assert-AreEqual -Expected ($true)   -Actual (1..5 | Linq-Any { $_ -eq 3 })
Assert-AreEqual -Expected ($false)  -Actual (1..5 | Linq-Any { $_ -eq 6 })

# First
Assert-AreEqual -Expected @(1)      -Actual @(1..5 | Linq-First)
Assert-AreEqual -Expected @(2)      -Actual @(1..5 | Linq-First { $_ -gt 1 })
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-First { $_ -gt 5 })

# Last
Assert-AreEqual -Expected @(5)      -Actual @(1..5 | Linq-Last)
Assert-AreEqual -Expected @(4)      -Actual @(1..5 | Linq-Last { $_ -lt 5 })
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-Last { $_ -lt 1 })

# Single
Assert-AreEqual -Expected @(2)      -Actual @(1..5 | Linq-Single { $_ -eq 2 })
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-Single { $_ -gt 5 })

# Skip
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-Skip 0)
Assert-AreEqual -Expected @(3..5)   -Actual @(1..5 | Linq-Skip 2)
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-Skip 5)
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-Skip 6)

# SkipWhile
Assert-AreEqual -Expected @(2..5)   -Actual @(1..5 | Linq-SkipWhile { $_ -eq 1})
Assert-AreEqual -Expected @(3..5)   -Actual @(1..5 | Linq-SkipWhile { $_ -lt 3})
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-SkipWhile { $false })
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-SkipWhile { $true })

# Take
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-Take 5)
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-Take 6)
Assert-AreEqual -Expected @(1..5)   -Actual @(1..6 | Linq-Take 5)
Assert-AreEqual -Expected @(1..3)   -Actual @(1..5 | Linq-Take 3)
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-Take 0)

# TakeWhile
Assert-AreEqual -Expected @(1..2)   -Actual @(1..5 | Linq-TakeWhile { $_ -lt 3})
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-TakeWhile { $_ -eq 2})
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-TakeWhile { $false })
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-TakeWhile { $true })

# Distinct
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-Distinct)
Assert-AreEqual -Expected @(1..5)   -Actual @(1,2,3,4,5,1,2,3,4,5 | Linq-Distinct)
Assert-AreEqual -Expected @()       -Actual @(Linq-Distinct)

# Repeat
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-Repeat 1)
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-Repeat 0)
Assert-AreEqual -Expected @(1,1,2,2,3,3,4,4,5,5) -Actual @(1..5 | Linq-Repeat 2)

# Except
Assert-AreEqual -Expected @(1,3,5)  -Actual @(1..5 | Linq-Except (2,4))
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-Except 6)
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-Except (1..5))

# Intersect
Assert-AreEqual -Expected @(2,4)    -Actual @(1..5 | Linq-Intersect (2,4))
Assert-AreEqual -Expected @()       -Actual @(1..5 | Linq-Intersect 6)
Assert-AreEqual -Expected @(1..5)   -Actual @(1..5 | Linq-Intersect (1..5))

# IndexOf
Assert-AreEqual -Expected (0)       -Actual (1..5 | Linq-IndexOf { $_ -eq 1 })
Assert-AreEqual -Expected (3)       -Actual (1..5 | Linq-IndexOf { $_ -eq 4 })
Assert-AreEqual -Expected (-1)      -Actual (1..5 | Linq-IndexOf { $_ -eq 6 })
Assert-AreEqual -Expected (2)       -Actual (1,2,3,3,3 | Linq-IndexOf { $_ -eq 3 })

# Count
Assert-AreEqual -Expected (5)       -Actual (1..5 | Linq-Count)
Assert-AreEqual -Expected (1)       -Actual (1..5 | Linq-Count { $_ -eq 3 })
Assert-AreEqual -Expected (0)       -Actual (1..5 | Linq-Count { $_ -eq 6 })

# Average, Min, Max
Assert-AreEqual -Expected (3)       -Actual (1..5 | Linq-Average)
Assert-AreEqual -Expected (15)      -Actual (1..5 | Linq-Sum)
Assert-AreEqual -Expected (5)       -Actual (1..5 | Linq-Max)
Assert-AreEqual -Expected (1)       -Actual (1..5 | Linq-Min)</pre>
<p>The complete function listing is shown below. I&#8217;ve been selfishly keeping this module to myself for about a year now and I felt it was time to post it. Let me know what you think!</p>
<table border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td width="146"><strong>Name</strong></td>
<td width="450"><strong>Synopsis</strong></td>
</tr>
<tr>
<td width="146">Linq-All</td>
<td width="450">Determines whether all elements of a sequence satisfy a condition.</td>
</tr>
<tr>
<td width="146">Linq-Any</td>
<td width="450">Determines whether any element of a sequence satisfies a condition.</td>
</tr>
<tr>
<td width="146">Linq-Average</td>
<td width="450">Returns the average of values in a sequence.</td>
</tr>
<tr>
<td width="146">Linq-Count</td>
<td width="450">Returns a number that represents how many elements in the specified sequence satisfy a condition.</td>
</tr>
<tr>
<td width="146">Linq-Distinct</td>
<td width="450">Returns unique items from the pipeline input.</td>
</tr>
<tr>
<td width="146">Linq-Except</td>
<td width="450">Excludes from the pipeline input the items which also appear in a second set.</td>
</tr>
<tr>
<td width="146">Linq-Expand</td>
<td width="450">Drills into an input object based on one or more property names to simplify access to data inside nested structures.</td>
</tr>
<tr>
<td width="146">Linq-First</td>
<td width="450">Returns the first element in a sequence that satisfies a specified condition.</td>
</tr>
<tr>
<td width="146">Linq-IndexOf</td>
<td width="450">Returns the zero-based position of the first element in a sequence that meets the specified criteria.</td>
</tr>
<tr>
<td width="146">Linq-Intersect</td>
<td width="450">Includes from the pipeline input only the items that exist in a second set.</td>
</tr>
<tr>
<td width="146">Linq-Last</td>
<td width="450">Returns the last element of a sequence that satisfies a specified condition.</td>
</tr>
<tr>
<td width="146">Linq-Max</td>
<td width="450">Returns the maximum value in a sequence.</td>
</tr>
<tr>
<td width="146">Linq-Min</td>
<td width="450">Returns the minimum value in a sequence.</td>
</tr>
<tr>
<td width="146">Linq-Repeat</td>
<td width="450">Repeats the items from the pipeline a specified number of times.</td>
</tr>
<tr>
<td width="146">Linq-Select</td>
<td width="450">Selects a property, property set, or ScriptBlock projection of the input.</td>
</tr>
<tr>
<td width="146">Linq-SelectMany</td>
<td width="450">Similar to Linq-Select but always ensures the output is wrapped in an array.</td>
</tr>
<tr>
<td width="146">Linq-Single</td>
<td width="450">Returns a single item that satisfies a specified condition, and throws an exception if more than one or zero such element exists.</td>
</tr>
<tr>
<td width="146">Linq-Skip</td>
<td width="450">Skips the specified number of items from the input and then returns the remaining items.</td>
</tr>
<tr>
<td width="146">Linq-SkipWhile</td>
<td width="450">Skips items from the input as long as a specified condition is true and then returns the remaining items.</td>
</tr>
<tr>
<td width="146">Linq-Sum</td>
<td width="450">Returns the sum of values in a sequence.</td>
</tr>
<tr>
<td width="146">Linq-Take</td>
<td width="450">Returns a specified number of contiguous items from the start of the input pipeline.</td>
</tr>
<tr>
<td width="146">Linq-TakeWhile</td>
<td width="450">Returns items from the input as long as a specified condition is true.</td>
</tr>
<tr>
<td width="146">Linq-ToDictionary</td>
<td width="450">Creates a Hashtable from a sequence according to specified key selector and value selector functions.</td>
</tr>
<tr>
<td width="146">Linq-ToSet</td>
<td width="450">Creates a HashSet containing only unique items from a sequence.</td>
</tr>
<tr>
<td width="146">Where-Like</td>
<td width="450">Returns items from a sequence whose selected values match one or more wildcard patterns.</td>
</tr>
<tr>
<td width="146">Where-Match</td>
<td width="450">Returns items from a sequence whose selected values match one or more regular expression patterns.</td>
</tr>
</tbody>
</table>
<p><a href="http://cid-89e05724af67a39e.skydrive.live.com/browse.aspx/PowerShell/Modules/LINQ" target="_blank">Download LINQ.psm1</a></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Flinq-for-powershell%2F&amp;linkname=LINQ%20for%20PowerShell"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/bA8Oye3L9mE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/linq-for-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/linq-for-powershell/</feedburner:origLink></item>
		<item>
		<title>Path.Combine in .NET 4</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/FK0wUIxCp3Y/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/path-combine-in-net-4/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 21:15:29 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/02/path-combine-in-net-4/</guid>
		<description><![CDATA[I recently blogged about a new method I noticed in .NET 4 on the Enum class. One of the great things about .NET 4 is that it is a new version of base class library too. In .NET 3.0 and 3.5 as we all know, the CLR and BCL was left at version 2.0 which [...]]]></description>
			<content:encoded><![CDATA[<p>I <a href="http://www.josheinstein.com/blog/index.php/2010/02/enum-hasflag-in-net-4">recently blogged</a> about a new method I noticed in .NET 4 on the Enum class. One of the great things about .NET 4 is that it is a new version of base class library too. In .NET 3.0 and 3.5 as we all know, the CLR and BCL was left at version 2.0 which meant there were practically no improvements to core system classes and such.</p>
<p>Well I just stumbled upon another welcome upgrade to a rusty old class. <a href="http://msdn.microsoft.com/en-us/library/dd991142(VS.100).aspx" target="_blank">Path.Combine</a> in .NET 4 takes a parameter array of parts.</p>
<pre class="brush: csharp;">// so code that used to look like this...
string documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string filename =
    Path.Combine(documents,
        Path.Combine(&quot;Visual Studio 2008&quot;,
            Path.Combine(&quot;Projects&quot;, &quot;My Project&quot;);

// now looks like this...
string documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string filename = Path.Combine(documents, &quot;Visual Studio 2008&quot;, &quot;Projects&quot;, &quot;MyProjects&quot;);</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Fpath-combine-in-net-4%2F&amp;linkname=Path.Combine%20in%20.NET%204"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/FK0wUIxCp3Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/path-combine-in-net-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/path-combine-in-net-4/</feedburner:origLink></item>
		<item>
		<title>Hate VS2010 help? Get H3Viewer!</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/NGb_IHVIg_4/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/h3viewer/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 19:04:34 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[VS2010]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/02/hate-vs2010-help-get-h3viewer/</guid>
		<description><![CDATA[ 
Update: There was a bug in H3Viewer at the time I posted this that showed an empty TOC and Index on x64 versions of Windows. Rob Chandler just informed me the current build (1.0.0.20) fixes this and I have confirmed it now works fine on x64! Apparently in between Beta 2 and RC Microsoft [...]]]></description>
			<content:encoded><![CDATA[<p><a title="H3Viewer" href="http://mshcmigrate.helpmvp.com/viewer" target="_blank"><img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="H3Viewer" border="0" alt="H3Viewer" align="right" src="http://www.josheinstein.com/blog/wp-content/uploads/2010/02/h3vsc1.png" width="244" height="187" /></a> </p>
<p><em>Update: There was a bug in H3Viewer at the time I posted this that showed an empty TOC and Index on x64 versions of Windows. Rob Chandler just informed me the current build (1.0.0.20) fixes this and I have confirmed it now works fine on x64! Apparently in between Beta 2 and RC Microsoft may have changed the help agent from 32 bit to 64 bit which relocated some registry keys. H3Viewer is still a 32 bit application but works fine on 64 bit Windows.</em></p>
<p>I hate Visual Studio 2010’s new help system. Well hate isn’t really the right word. It’s more like loathing with every fiber of my being. There was a <a href="http://blogs.msdn.com/bharry/archive/2010/01/27/playing-back-the-help-feedback.aspx" target="_blank">pretty good discussion</a> going on in the comments of Brian Harry’s blog on MSDN. The bottom line is though, it’s here to stay.</p>
<p>Fortunately a Microsoft Help MVP named Robert Chandler has created <a title="H3Viewer" href="http://mshcmigrate.helpmvp.com/viewer" target="_blank">H3Viewer</a> which is an interface on top of the new help system that aims to bring back the familiar feel of dexplore, including a TOC, index, and bookmarks. It doesn’t change the fact that help is now served by a local web server but it’s a great improvement over the out of box experience. Sorry but IE/Chrome are not good help viewers.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Fh3viewer%2F&amp;linkname=Hate%20VS2010%20help%3F%20Get%20H3Viewer%21"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/NGb_IHVIg_4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/h3viewer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/h3viewer/</feedburner:origLink></item>
		<item>
		<title>FullScreenBehavior makes full-screen apps in WPF easy</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/LWDu6SsJZo4/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/fullscreenbehavior-wpf/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 04:00:19 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/02/fullscreenbehavior-makes-full-screen-apps-in-wpf-easy/</guid>
		<description><![CDATA[Download FullScreenDemo Project
So now I’m working on an application that will be used at a trade show in a booth. Customers will come up to the application and type in the area code and exchange of their phone number and the application will tell them whether or not they can move their phone number over [...]]]></description>
			<content:encoded><![CDATA[<p><a title="FullScreenBehavior" href="http://www.josheinstein.com/wpf/fullscreenbehavior/fullscreendemo.zip">Download FullScreenDemo Project</a></p>
<p>So now I’m working on an application that will be used at a trade show in a booth. Customers will come up to the application and type in the area code and exchange of their phone number and the application will tell them whether or not they can move their phone number over to us. Piece of cake. But obviously a battleship gray Windows Forms application will simply not do. I chose WPF for the project because it needs to access an offline database, interact with an external COM server (MapPoint), and run full screen with keyboard input.</p>
<p>That last point is what led me to the code I posted tonight. Running a WPF application in full screen mode is pretty trivial.</p>
<ul>
<li>Set WindowStyle = None </li>
<li>Set TopMost = True </li>
<li>Set WindowState = Maximized </li>
</ul>
<p>But coming off a recent Silverlight project, I was a little perturbed about the fact that Silverlight can easily “go full screen” and back whereas in WPF it felt really manual. Plus there were a few other improvements I wanted to make that I could easily wrap up into a reusable behavior. For one, using a full-screen window during debugging is a pain in the ass, even with two monitors. Therefore, I want to be able to toggle full screen mode at runtime.</p>
<p>Here are a few common ways that applications enter and exit full screen mode. This behavior supports them all.</p>
<ul>
<li>Many full-screen apps allow the user to toggle full screen mode by double clicking inside the window. </li>
<li>Many full-screen apps allow the user to exit full screen mode by pressing escape. </li>
<li>Many full-screen apps implicitly enter full screen mode when the window is maximized. </li>
</ul>
<p>The only one that was tricky was the last one. Since WPF does not have a “StateChanging” event, what was happening was the Window (with its border and title bar) is maximized before the event is raised. By that time, setting the WindowStyle property to remove the caption and border didn’t affect the maximized size so the maximized window was still showing the taskbar. It took a little trial and error but I settled on using WM_SYSCOMMAND.</p>
<p>Usage of the behavior is simple.</p>
<pre class="brush: xml;">&lt;Window ... &gt;

    &lt;i:Interaction.Behaviors&gt;

        &lt;Einstein:FullScreenBehavior
                FullScreenOnDoubleClick=&quot;True&quot;
                FullScreenOnMaximize=&quot;True&quot;
                RestoreOnEscape=&quot;True&quot; /&gt;

    &lt;/i:Interaction.Behaviors&gt;

&lt;/Window&gt;</pre>
<p>The <a title="FullScreenBehavior" href="http://www.josheinstein.com/wpf/fullscreenbehavior/fullscreendemo.zip">attached demo</a> includes the FullScreenBehavior.cs which has no external dependencies. Enjoy.</p>
<p align="center"><a title="FullScreenBehavior" href="http://www.josheinstein.com/wpf/fullscreenbehavior/fullscreendemo.zip"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Full Screen Demo" border="0" alt="Full Screen Demo" src="http://www.josheinstein.com/blog/wp-content/uploads/2010/02/FullScreenDemo.png" width="500" height="477" /></a></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Ffullscreenbehavior-wpf%2F&amp;linkname=FullScreenBehavior%20makes%20full-screen%20apps%20in%20WPF%20easy"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/LWDu6SsJZo4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/fullscreenbehavior-wpf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/fullscreenbehavior-wpf/</feedburner:origLink></item>
		<item>
		<title>Enum.HasFlag in .NET 4</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/jog8Hwd7DVY/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/enum-hasflag-in-net-4/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 18:44:46 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/02/enum-hasflag-in-net-4/</guid>
		<description><![CDATA[Shh&#8230; hear that? It’s the sound of a million developers ripping out their home-grown HasFlag, IsFlagSet, CheckFlag, etc helper methods. Just noticed that in .NET 4 System.Enum now has a built-in HasFlag method. As Forrest Gump would say “Lt. Dan says we don’t have to worry about enum flags no more. That’s good. One less [...]]]></description>
			<content:encoded><![CDATA[<p>Shh&#8230; hear that? It’s the sound of a million developers ripping out their home-grown HasFlag, IsFlagSet, CheckFlag, etc helper methods. Just noticed that in .NET 4 System.Enum now has a built-in <a title="Enum.HasFlag" href="http://msdn.microsoft.com/en-us/library/system.enum.hasflag(VS.100).aspx" target="_blank">HasFlag</a> method. As Forrest Gump would say “Lt. Dan says we don’t have to worry about enum flags no more. That’s good. One less thing.”</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Fenum-hasflag-in-net-4%2F&amp;linkname=Enum.HasFlag%20in%20.NET%204"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/jog8Hwd7DVY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/enum-hasflag-in-net-4/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/enum-hasflag-in-net-4/</feedburner:origLink></item>
		<item>
		<title>Unit tests are no substitute for manual tests by end users</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/GoBKCDUdPD4/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/unit-tests-are-no-substitute-for-manual-tests-by-end-users/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 15:35:05 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Noise]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/02/unit-tests-are-no-substitute-for-manual-tests-by-end-users/</guid>
		<description><![CDATA[I like unit testing. I’m not a hard liner so I don’t take it too seriously. I don’t necessarily fully subscribe to the test-first approach in all cases and I think aiming for 100% code coverage is rarely practical. But I do like unit tests. They give my a certain peace of mind and set [...]]]></description>
			<content:encoded><![CDATA[<p>I like unit testing. I’m not a hard liner so I don’t take it too seriously. I don’t necessarily fully subscribe to the test-first approach in all cases and I think aiming for 100% code coverage is rarely practical. But I do like unit tests. They give my a certain peace of mind and set a minimum standard for functionality.</p>
<p>But I just ran into a bug in my code that I didn’t catch in my unit tests but the end user caught pretty early on. Typing a decimal value into a field that was bound to an Int64 property on the viewmodel didn’t produce any error but simply reverted the field to zero. As the developer, it never occurred to me that someone would want to put a non-integer value in the field. I even guarded against negative integers.</p>
<p>Anyhow, the fix for now is “don’t type fractional minutes in the minutes field.” The bug is not particularly disruptive, just confusing. The nature of the field is such that a fractional minute is meaningless, but the end user is entering numbers directly off a bill which happens to have way more precision than is needed. It’s super low priority so I’ll queue it up for when other bugs need to be fixed. But I thought it was a great example of how developers can know the code inside and out, yet the end user will always find a bug you never even considered.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Funit-tests-are-no-substitute-for-manual-tests-by-end-users%2F&amp;linkname=Unit%20tests%20are%20no%20substitute%20for%20manual%20tests%20by%20end%20users"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/GoBKCDUdPD4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/unit-tests-are-no-substitute-for-manual-tests-by-end-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/unit-tests-are-no-substitute-for-manual-tests-by-end-users/</feedburner:origLink></item>
		<item>
		<title>Useful PowerShell Function: Use-Location</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/uOzPfa5dAyE/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/useful-powershell-function-use-location/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 22:22:55 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/02/useful-powershell-function-use-location/</guid>
		<description><![CDATA[It’s a simple one, but useful. And it can clean up some of your ugly scripts that have a lot of redundant paths embedded in strings.
# Reduced for the sake of the example
# The full advanced function is included at the end.
function Use-Location($Path, $Body) {

    Push-Location $Path

    try { [...]]]></description>
			<content:encoded><![CDATA[<p>It’s a simple one, but useful. And it can clean up some of your ugly scripts that have a lot of redundant paths embedded in strings.</p>
<pre class="brush: powershell;"># Reduced for the sake of the example
# The full advanced function is included at the end.
function Use-Location($Path, $Body) {

    Push-Location $Path

    try { &amp;$Body }
    finally { Pop-Location }

}</pre>
<p>Usage of the function couldn’t be simpler and uses a C#-style scope syntax.</p>
<pre class="brush: powershell;">Use-Location &quot;C:\Temp&quot; {

    mkdir textfiles
    dir *.txt | move textfiles

    mkdir images
    dir *.jpg,*.png | move images

}</pre>
<p>Obviously you could just as well use Push-Location and Pop-Location in a try/catch yourself but why? This way enforces clean scoping and ensures you don’t forget the call to pop.</p>
<pre class="brush: powershell; collapse: true;">##############################################################################
#.SYNOPSIS
# Executes a ScriptBlock within the context of the specified working directory.
#
#.DESCRIPTION
# This function sets the current location to the specified Path and executes a
# ScriptBlock. All relative paths in the ScriptBlock will be based on the new
# current directory. When the ScriptBlock exits, the old current directory
# will be restored.
#
#.PARAMETER Path
# The working directory to use for the duration of the ScriptBlock.
#
#.PARAMETER ScriptBlock
# The code to execute within the context of the new current directory.
#
#.PARAMETER Create
# Creates the directory if it does not exist.
#
#.EXAMPLE
# Use-Location &quot;C:\Temp&quot; {
#
#    mkdir textfiles
#    dir *.txt | move textfiles
#
#    mkdir images
#    dir *.jpg,*.png | move images
#
# }
#
#.LINK
# Push-Location
# Pop-Location
##############################################################################
function Use-Location {

    [CmdletBinding()]
    param(

        [Alias('PSPath')]
        [Alias('LiteralPath')]
        [Parameter(Position=1, Mandatory=$true)]
        [String]$Path,

        [Parameter(Position=2, Mandatory=$true)]
        [ScriptBlock]$ScriptBlock,

        [Parameter()]
        [Switch]$Create

    )

    $ErrorActionPreference = 'Stop'

    # Create if necessary
    if ($Create) {
        $Exists = Test-Path -LiteralPath $Path -PathType Container
        if (-not $Exists) {
            New-Item $Path -ItemType Directory | Out-Null
        }
    }

    Push-Location $Path -StackName 'Use-Location'

    try { &amp;$ScriptBlock }
    finally { Pop-Location -StackName 'Use-Location' }

}</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Fuseful-powershell-function-use-location%2F&amp;linkname=Useful%20PowerShell%20Function%3A%20Use-Location"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/uOzPfa5dAyE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/useful-powershell-function-use-location/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/useful-powershell-function-use-location/</feedburner:origLink></item>
		<item>
		<title>Silverlight: Animated "Turbo Tax" style number display</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/InmDRpJwvI0/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/silverlight-animated-turbotax-number-display/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 03:51:48 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/?p=114</guid>
		<description><![CDATA[<p>If you’ve used Turbo Tax, you may have noticed the prominent “Federal Refund” box that’s ever-present at the top of the page while you’re figuring out your taxes. I like this UI concept because when most people are filing their taxes, there’s only one number they actually care about and they care about it every step of the way.</p>

<p>One nice little touch about the display is that whenever you make changes to your return that affect the federal refund, instead of the field just changing immediately, it has a nice incrementing (or decrementing if you’re like me) animation. It is a subtle effect that draws your attention to the field whenever it changes. Try the working example below.</p>

<p>Recently I worked on a line of business application that would benefit from a similar UI. The application is for pricing out sales proposals and takes into account cost of goods, retail price, agent commission, etc. At every step of the way, slight changes to the various inputs affect the <em>bottom line</em> which is the profitability of the deal. So the profitability is always displayed on the screen. When the value changes, I wanted to have this smooth animation between numbers just like Turbo Tax. Turns out it isn’t that hard.</p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.josheinstein.com/Silverlight/AnimatedNumber/AnimatedNumberDemo.zip">Download Animated Number Project</a></p>
<p>If you’ve used Turbo Tax, you may have noticed the prominent “Federal Refund” box that’s ever-present at the top of the page while you’re figuring out your taxes. I like this UI concept because when most people are filing their taxes, there’s only one number they actually care about and they care about it every step of the way.</p>
<p>One nice little touch about the display is that whenever you make changes to your return that affect the federal refund, instead of the field just changing immediately, it has a nice incrementing (or decrementing if you’re like me) animation. It is a subtle effect that draws your attention to the field whenever it changes. Try the working example below.</p>
<div align="center"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" style="width: 450px; height: 150px"><param name="source" value="http://www.josheinstein.com/Silverlight/AnimatedNumber/AnimatedNumberDemo.xap" /><param name="background" value="white" /><param name="minRuntimeVersion" value="3.0.40818.0" /><param name="autoUpgrade" value="true" /><a href="http://go.microsoft.com/fwlink/?LinkID=149156&#038;v=3.0.40818.0"><br />
            <img alt="Get Microsoft Silverlight" src="http://go.microsoft.com/fwlink/?LinkId=108181" style="border-style: none" /><br />
        </a><br />
    </object></div>
<p>Recently I worked on a line of business application that would benefit from a similar UI. The application is for pricing out sales proposals and takes into account cost of goods, retail price, agent commission, etc. At every step of the way, slight changes to the various inputs affect the <em>bottom line</em> which is the profitability of the deal. So the profitability is always displayed on the screen. When the value changes, I wanted to have this smooth animation between numbers just like Turbo Tax. Turns out it isn’t that hard.</p>
<h3>Before we begin</h3>
<p>I just want to note that if I just wanted to create a one-off solution, it could probably be done in about 10 lines of code with event handlers. The purpose of this article is to create a control that is effortless to use and re-use. If you want, you can just <a href="http://www.josheinstein.com/Silverlight/AnimatedNumber/AnimatedNumberDemo.zip">skip to the sample project</a> and look at the code. It’s really not that complex.</p>
<h3>Creating the Control</h3>
<p>The idea is very simple. A control that lets you bind a numeric value to it and when that value changes, the displayed number should quickly increment or decrement to the new value instead of changing immediately. The example above shows the finished control in action.</p>
<p>At first I didn’t want to do this as a control. I thought maybe there was some way I could do it at the binding level or with an attached property but that didn’t seem to be possible via any of the extensibility points offered by Silverlight. So I decided to make it a control.</p>
<p>What kind of control should it be? Should it derive from ContentControl? TextBlock? Neither of those seemed appropriate because in order to make it work, I would need a strongly typed Value property. Having a simple Content property based on System.Object would imply that it could accept any type. I didn’t want to go crazy supporting different types. For example, there’s no point in making it able to animate between two DateTime values or TimeSpan. I decided to stick with System.Double as the type of the Value property. Any numeric type would be convertible to/from Double and there’s a built in DoubleAnimation that I could take advantage of.</p>
<p>I settled on creating a new class called AnimatedNumber that derives from Control (not ContentControl.) I added two dependency properties:</p>
<pre class="brush: csharp;">public class AnimatedNumber : Control {
    // the actual code defines theese as dependency properties
    public double Value { get; set; }
    private double AnimatedValue { get; set; }
}</pre>
<p>The idea here is that the Value property is the bindable public property that would be set to a discrete value such as 0, 100, 200, etc. When this happens we will <em>animate</em> the private AnimatedValue property so that over a short period of time, the AnimatedValue property will quickly change from 0, 1, 2, &#8230; 100, &#8230; 198, 199, 200.</p>
<p>To do this, I included a PropertyChangedCallback with the ValueProperty registration. This callback is invoked whenever the Value property is changed (either via x.Value = 100 or as a result of a binding expression.) In the callback, we’ll run a Storyboard against the AnimatedValue property that uses a DoubleAnimation to interpolate between the old and new values.</p>
<pre class="brush: csharp;">private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    var senderControl = (AnimatedNumber)sender;
    senderControl.AnimateValue((double)e.NewValue);
}

private void AnimateValue(double newValue)
{
    var animation = new DoubleAnimation();
    animation.Duration = TimeSpan.FromSeconds(1);
    animation.To = newValue;

    var storyboard = new Storyboard();
    storyboard.Duration = TimeSpan.FromSeconds(1);
    storyboard.Children.Add(animation);

    Storyboard.SetTarget(animation, this);
    Storyboard.SetTargetProperty(animation, new PropertyPath("AnimatedValue"));

    storyboard.Begin();
}</pre>
<p>So now we have a control that exposes a Value that when changed, triggers an incremental change to the new value in a corresponding AnimatedValue property. But so far, the control has absolutely no visual representation! We’ve only defined the behavior of the control.</p>
<h3>Creating a Default Control Template</h3>
<p>To add a default control template, add a folder named “Themes” to the root of the project and create a resource dictionary named Generic.xaml. Add a style with no key and a setter that defines a very basic control template. In fact, the only thing this control has is a ContentPresenter that will present the AnimatedValue property. The entire Generic.xaml is only a few lines long. The control doesn’t need anything more than that because we eventually want to use it wherever we’d place “content” such as in a button or label. Let some other control provide the eye candy.</p>
<pre class="brush: xml;">
&lt;ResourceDictionary
  xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
  xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
  xmlns:Local=&quot;clr-namespace:AnimatedNumberDemo&quot;&gt;
  &lt;Style TargetType=&quot;Local:AnimatedNumber&quot;&gt;
    &lt;Setter Property=&quot;Template&quot;&gt;
      &lt;Setter.Value&gt;
        &lt;ControlTemplate TargetType=&quot;Local:AnimatedNumber&quot;&gt;
          &lt;ContentPresenter x:Name=&quot;PART_Content&quot; /&gt;
        &lt;/ControlTemplate&gt;
      &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
  &lt;/Style&gt;
&lt;/ResourceDictionary&gt;
</pre>
<p>The important thing is that we have a ContentPresenter named (exactly) PART_Content. You’ll see why in a second.</p>
<p>To make Silverlight associate the above template with our control, we need to add a line to the constructor, and while we’re at it, override OnApplyTemplate. This is the best place to grab the template part we expect to find (PART_Content) and bind it to the AnimatedValue property.</p>
<pre class="brush: csharp;">// Template part
private ContentPresenter PART_Content;

// Default public constructor
public AnimatedNumber() {
    DefaultStyleKey = typeof(AnimatedNumber);
}

protected override void OnApplyTemplate() {

    base.OnApplyTemplate();

    PART_Content = GetTemplateChild("PART_Content") as ContentPresenter;
    if (PART_Content != null) {
        var binding = new Binding("AnimatedValue");
        binding.Source = this;
        PART_Content.SetBinding(ContentPresenter.ContentProperty, binding);
    }

}</pre>
</p>
<p>Okay, now in theory it should work but I would advise reading the next section first and looking at the *actual* code I attached as opposed to the select snippets I put inline.</p>
<h3>Okay, now it should work…</h3>
<p>Really this is all that is needed to make the control functional. But it’s a little crude. The attached sample project is a bit more cleaned up than the inline code so far. There’s also additional functionality.</p>
<p>For one, the code above would use the default Double.ToString() conversion which means as the animation was in progress, you’d probably see a huge ugly number with lots of decimal places, no separators, and no currency symbols. The attached control adds a Format property and uses an included FormattingValueConverter. This way you can specify a format string as an attribute in the XAML to get the nice formatting as seen in the demo at the beginning of the article.</p>
<p>Also, the attached control does not create a new Storyboard everytime the value is animated. A single Storyboard is created in the constructor and is reused for the life of the control. The nice thing about this is that multiple changes to the value will “interrupt” the previous animation. So for example if it’s halfway through animation from 0 to 100 and you change it back to 0, it won’t continue to climb to 100 then drop to 0. It will stop climbing at 50 or whatever, and start dropping.</p>
<p>Finally, the attached control provides a TransitionDuration property that lets you control how long the control will spend transitioning. Right now the time is constant which is a little weird.</p>
<p>Using the code is pretty straightforward. The following is an example of a simple button that is bound to a TotalProfit value of the ViewModel and animates the value when it changes.</p>
<pre class="brush: xml;">
&lt;Button Style=&quot;{StaticResource GlassButton}&quot;&gt;
    &lt;StackPanel&gt;
        &lt;TextBlock Text=&quot;Total Profit&quot; /&gt;
        &lt;Local:AnimatedNumber Value=&quot;{Binding TotalProfit}&quot; Format=&quot;C2&quot; /&gt;
    &lt;/StackPanel&gt;
&lt;/Button&gt;
</pre>
<h3>Ideas for Additional Improvements</h3>
<p>Some things that I didn’t have time to get to but would be nice:</p>
<ul>
<li>Using an easing function to make the animation more fluid </li>
<li>Varying the duration of the animation based on how large or small the change is. For example if you changed 1000 to 1009, it’s kind of silly that the control spends 2 seconds making that transition. </li>
<li>Adding support for the Visual State Manager. In particular, it would be nice to have 3 states – Positive, Zero, Negative. This way you could color the value red when negative and green when positive without putting too much burden on the consumer of the control. </li>
</ul>
<p>Please let me know what you think of this example. It’s my first time posting a lenthy example of a Silverlight control but as time permits I’d like to share more of my recent experiences.</p>
<p><a href="http://www.josheinstein.com/Silverlight/AnimatedNumber/AnimatedNumberDemo.zip">Download Animated Number Project</a></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Fsilverlight-animated-turbotax-number-display%2F&amp;linkname=Silverlight%3A%20Animated%20%26quot%3BTurbo%20Tax%26quot%3B%20style%20number%20display"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/InmDRpJwvI0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/silverlight-animated-turbotax-number-display/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/silverlight-animated-turbotax-number-display/</feedburner:origLink></item>
		<item>
		<title>Google begins phasing out support for legacy versions of Internet Explorer</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/593rH_ITiJ0/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/02/google-begins-phasing-out-support-for-legacy-versions-of-internet-explorer/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 04:02:43 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[IE]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/02/google-begins-phasing-out-support-for-legacy-versions-of-internet-explorer/</guid>
		<description><![CDATA[And hopefully many more will follow suit. SharePoint 2010 also does not support IE6. Hopefully this will hasten it’s demise.
Dear Google Apps admin,​     
In order to continue to improve our products and deliver more sophisticated features and performance, we are harnessing some of the latest improvements in web browser technology.&#160; This [...]]]></description>
			<content:encoded><![CDATA[<p>And hopefully many more will follow suit. SharePoint 2010 also <a href="http://blogs.msdn.com/sharepoint/archive/2009/05/07/announcing-sharepoint-server-2010-preliminary-system-requirements.aspx" target="_blank">does not support IE6</a>. Hopefully this will hasten it’s demise.</p>
<blockquote><p>Dear Google Apps admin,​     </p>
<p>In order to continue to improve our products and deliver more sophisticated features and performance, we are harnessing some of the latest improvements in web browser technology.&#160; This includes faster JavaScript processing and new standards like HTML5.&#160; As a result, over the course of 2010, we will be phasing out support for Microsoft Internet Explorer 6.0 as well as other older browsers that are not supported by their own manufacturers.      </p>
<p>We plan to begin phasing out support of these older browsers on the Google Docs suite and the Google Sites editor on March 1, 2010.&#160; After that point, certain functionality within these applications may have higher latency and may not work correctly in these older browsers. Later in 2010, we will start to phase out support for these browsers for Google Mail and Google Calendar.      </p>
<p>Google Apps will continue to support Internet Explorer 7.0 and above, Firefox 3.0 and above, Google Chrome 4.0 and above, and Safari 3.0 and above.      </p>
<p>Starting this week, users on these older browsers will see a message in Google Docs and the Google Sites editor explaining this change and asking them to upgrade their browser.&#160; We will also alert you again closer to March 1 to remind you of this change.      </p>
<p>In 2009, the Google Apps team delivered more than 100 improvements to enhance your product experience. We are aiming to beat that in 2010 and continue to deliver the best and most innovative collaboration products for businesses.      </p>
<p>Thank you for your continued support!      </p>
<p>Sincerely,      </p>
<p>The Google Apps team      </p>
<p>Email preferences: You have received this mandatory email service announcement to update you about important changes to your Google Apps product or account.      </p>
<p>Google Inc.      <br />1600 Amphitheatre Parkway      <br />Mountain View, CA 94043</p>
</blockquote>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F02%2Fgoogle-begins-phasing-out-support-for-legacy-versions-of-internet-explorer%2F&amp;linkname=Google%20begins%20phasing%20out%20support%20for%20legacy%20versions%20of%20Internet%20Explorer"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/593rH_ITiJ0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/02/google-begins-phasing-out-support-for-legacy-versions-of-internet-explorer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/02/google-begins-phasing-out-support-for-legacy-versions-of-internet-explorer/</feedburner:origLink></item>
		<item>
		<title>Awesome Extension Methods: In and Between</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/mLj1v1VeHCA/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/01/in-between/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 22:54:43 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Extension Methods]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/01/awesome-extension-methods-in-and-between/</guid>
		<description><![CDATA[These ones are pretty simple in implementation but go a long way to cleaning up your code. In some cases, the slight performance overhead may not be acceptable but I haven’t run into any real-world problems with them. Check out the usage below.
int x = 3;

// is x either 1, 3, or 5?
if (x.In(1, 3, [...]]]></description>
			<content:encoded><![CDATA[<p>These ones are pretty simple in implementation but go a long way to cleaning up your code. In some cases, the slight performance overhead may not be acceptable but I haven’t run into any real-world problems with them. Check out the usage below.</p>
<pre class="brush: csharp;">int x = 3;

// is x either 1, 3, or 5?
if (x.In(1, 3, 5)) {
    // yes!
}

// is x between 1 and 5?
if (x.Between(1, 5)) {
    // yes!
}</pre>
<p>The In method works with any kind of object and uses the default EqualityComparer&lt;T&gt; implementation for the type. But there are overloads that specify common types such as int, byte, long, etc. These overloads will perform much better than the generic overload. There is also an overload for String that takes a comparer so that you can specify case-insensitive matching as needed.</p>
<p>The Between method works on any type implementing IComparable. It also has overloads for commonly used types to get better performance than using the default IComparable implementation.</p>
<p>The code for both extension methods is shown below.</p>
<pre class="brush: csharp; collapse: true;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Einstein
{

    /// &lt;summary&gt;
    /// Extension methods for &lt;see cref=&quot;T:IComparable&quot;/&gt; types.
    /// &lt;/summary&gt;
    public static class ComparableExtensions
    {

        #region Methods

        #region In

        /// &lt;summary&gt;
        /// Determines whether this value exists in the &lt;paramref name=&quot;set&quot;/&gt; passed.
        /// &lt;/summary&gt;
        /// &lt;typeparam name=&quot;T&quot;&gt;The type of the value to compare and the values in the set.&lt;/typeparam&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value.&lt;/param&gt;
        /// &lt;param name=&quot;comparer&quot;&gt;The comparer to use.&lt;/param&gt;
        /// &lt;param name=&quot;set&quot;&gt;The set of values to determine if &lt;paramref name=&quot;value&quot;/&gt; is in.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; exists in the &lt;paramref name=&quot;set&quot;/&gt; otherwise, false.&lt;/returns&gt;
        public static bool In&lt;T&gt;( this T value, IEqualityComparer&lt;T&gt; comparer, params T[] set )
        {

            // Use default comparer
            if ( comparer == null ) {
                comparer = EqualityComparer&lt;T&gt;.Default;
            }   // if

            // Constant false
            if ( set.Length == 0 ) {
                return false;
            }   // if

            for ( int i = 0; i &lt; set.Length; i++ ) {
                if ( comparer.Equals( value, set[i] ) ) {
                    return true;
                }   // if
            }   // for

            return false;

        }

        /// &lt;summary&gt;
        /// Determines whether this value exists in the &lt;paramref name=&quot;set&quot;/&gt; passed.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value.&lt;/param&gt;
        /// &lt;param name=&quot;set&quot;&gt;The set of values to determine if &lt;paramref name=&quot;value&quot;/&gt; is in.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; exists in the &lt;paramref name=&quot;set&quot;/&gt; otherwise, false.&lt;/returns&gt;
        public static bool In( this byte value, params byte[] set )
        {
            for ( int i = 0; i &lt; set.Length; i++ ) {
                if ( value == set[i] ) {
                    return true;
                }   // if
            }   // for
            return false;
        }

        /// &lt;summary&gt;
        /// Determines whether this value exists in the &lt;paramref name=&quot;set&quot;/&gt; passed.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value.&lt;/param&gt;
        /// &lt;param name=&quot;set&quot;&gt;The set of values to determine if &lt;paramref name=&quot;value&quot;/&gt; is in.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; exists in the &lt;paramref name=&quot;set&quot;/&gt; otherwise, false.&lt;/returns&gt;
        public static bool In( this short value, params short[] set )
        {
            for ( int i = 0; i &lt; set.Length; i++ ) {
                if ( value == set[i] ) {
                    return true;
                }   // if
            }   // for
            return false;
        }

        /// &lt;summary&gt;
        /// Determines whether this value exists in the &lt;paramref name=&quot;set&quot;/&gt; passed.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value.&lt;/param&gt;
        /// &lt;param name=&quot;set&quot;&gt;The set of values to determine if &lt;paramref name=&quot;value&quot;/&gt; is in.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; exists in the &lt;paramref name=&quot;set&quot;/&gt; otherwise, false.&lt;/returns&gt;
        public static bool In( this int value, params int[] set )
        {
            for ( int i = 0; i &lt; set.Length; i++ ) {
                if ( value == set[i] ) {
                    return true;
                }   // if
            }   // for
            return false;
        }

        /// &lt;summary&gt;
        /// Determines whether this value exists in the &lt;paramref name=&quot;set&quot;/&gt; passed.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value.&lt;/param&gt;
        /// &lt;param name=&quot;set&quot;&gt;The set of values to determine if &lt;paramref name=&quot;value&quot;/&gt; is in.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; exists in the &lt;paramref name=&quot;set&quot;/&gt; otherwise, false.&lt;/returns&gt;
        public static bool In( this long value, params long[] set )
        {
            for ( int i = 0; i &lt; set.Length; i++ ) {
                if ( value == set[i] ) {
                    return true;
                }   // if
            }   // for
            return false;
        }

        /// &lt;summary&gt;
        /// Determines whether this value exists in the &lt;paramref name=&quot;set&quot;/&gt; passed.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value.&lt;/param&gt;
        /// &lt;param name=&quot;set&quot;&gt;The set of values to determine if &lt;paramref name=&quot;value&quot;/&gt; is in.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; exists in the &lt;paramref name=&quot;set&quot;/&gt; otherwise, false.&lt;/returns&gt;
        public static bool In( this string value, params string[] set )
        {
            return In&lt;string&gt;( value, StringComparer.OrdinalIgnoreCase, set );
        }

        /// &lt;summary&gt;
        /// Determines whether this value exists in the &lt;paramref name=&quot;set&quot;/&gt; passed.
        /// &lt;/summary&gt;
        /// &lt;typeparam name=&quot;T&quot;&gt;The type of the value to compare and the values in the set.&lt;/typeparam&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value.&lt;/param&gt;
        /// &lt;param name=&quot;set&quot;&gt;The set of values to determine if &lt;paramref name=&quot;value&quot;/&gt; is in.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; exists in the &lt;paramref name=&quot;set&quot;/&gt; otherwise, false.&lt;/returns&gt;
        public static bool In&lt;T&gt;( this T value, params T[] set )
        {
            return In&lt;T&gt;( value, EqualityComparer&lt;T&gt;.Default, set );
        }

        #endregion

        #region Between

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;typeparam name=&quot;T&quot;&gt;The type of values to compare.&lt;/typeparam&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between&lt;T&gt;( this T value, T minValueInclusive, T maxValueInclusive ) where T : IComparable
        {

            ParameterValidation.ThrowIfNull( value, &quot;value&quot; );

            int o1 = value.CompareTo( minValueInclusive );
            int o2 = value.CompareTo( maxValueInclusive );

            return ( o1 &gt;= 0 &amp;&amp; o2 &lt;= 0 ) || ( o1 &lt;= 0 &amp;&amp; o2 &gt;= 0 );

        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this byte value, byte minValueInclusive, byte maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this short value, short minValueInclusive, short maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this int value, int minValueInclusive, int maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this long value, long minValueInclusive, long maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this decimal value, decimal minValueInclusive, decimal maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this float value, float minValueInclusive, float maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this double value, double minValueInclusive, double maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this DateTime value, DateTime minValueInclusive, DateTime maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        /// &lt;summary&gt;
        /// Determines if the &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;value&quot;&gt;The value to check.&lt;/param&gt;
        /// &lt;param name=&quot;minValueInclusive&quot;&gt;The min value inclusive.&lt;/param&gt;
        /// &lt;param name=&quot;maxValueInclusive&quot;&gt;The max value inclusive.&lt;/param&gt;
        /// &lt;returns&gt;True if &lt;paramref name=&quot;value&quot;/&gt; is between &lt;paramref name=&quot;minValueInclusive&quot;/&gt; and
        /// &lt;paramref name=&quot;maxValueInclusive&quot;/&gt;, otherwise false.&lt;/returns&gt;
        public static bool Between( this TimeSpan value, TimeSpan minValueInclusive, TimeSpan maxValueInclusive )
        {
            if ( minValueInclusive &lt;= maxValueInclusive ) {
                return ( value &gt;= minValueInclusive ) &amp;&amp; ( value &lt;= maxValueInclusive );
            }   // if
            else {
                return ( value &gt;= maxValueInclusive ) &amp;&amp; ( value &lt;= minValueInclusive );
            }   // else
        }

        #endregion

        #endregion

    }   // class

}   // namespace</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F01%2Fin-between%2F&amp;linkname=Awesome%20Extension%20Methods%3A%20In%20and%20Between"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/mLj1v1VeHCA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/01/in-between/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/01/in-between/</feedburner:origLink></item>
		<item>
		<title>How would you like to lose your job to a 9 year old?</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/SFOayfqV2og/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/01/9-year-old-mcse/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 23:49:29 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Noise]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/01/how-would-you-like-to-lose-your-job-to-a-9-year-old/</guid>
		<description><![CDATA[ This is pretty impressive. When I was 9 I was still trying to figure out how I could get Guns N’ Roses to come to my birthday party. Of course the cynics will probably claim it is a reflection of the MCSE certification, but how can you not be impressed?
9-Year-Old is World&#8217;s Youngest Microsoft [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.techeblog.com/index.php/tech-gadget/9-year-old-is-world-s-youngest-microsoft-certified-systems-engineer" target="_blank"><img style="border-bottom: 0px; border-left: 0px; margin: 5px; display: inline; border-top: 0px; border-right: 0px" title="9-Year-Old is World&#39;s Youngest Microsoft Certified Systems Engineer" border="0" alt="9-Year-Old is World&#39;s Youngest Microsoft Certified Systems Engineer" align="right" src="http://www.josheinstein.com/blog/wp-content/uploads/2010/01/microsoft_certified_systems_engineer_1.jpg" width="178" height="212" /></a> This is pretty impressive. When I was 9 I was still trying to figure out how I could get Guns N’ Roses to come to my birthday party. Of course the cynics will probably claim it is a reflection of the MCSE certification, but how can you not be impressed?</p>
<p><a href="http://www.techeblog.com/index.php/tech-gadget/9-year-old-is-world-s-youngest-microsoft-certified-systems-engineer" target="_blank">9-Year-Old is World&#8217;s Youngest Microsoft Certified Systems Engineer</a></p>
<p>via <a href="http://dougfinke.com/blog/index.php/2010/01/23/are-you-smarter-than-a-9yr-old-microsoft-certified-systems-engineer" target="_blank">Doug Finke</a></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F01%2F9-year-old-mcse%2F&amp;linkname=How%20would%20you%20like%20to%20lose%20your%20job%20to%20a%209%20year%20old%3F"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/SFOayfqV2og" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/01/9-year-old-mcse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/01/9-year-old-mcse/</feedburner:origLink></item>
		<item>
		<title>Yes we can! Scott Brown wins MA special election!</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/n6Nd2Z4op54/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/01/yes-we-can-scott-brown-wins-ma-special-election/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 04:20:04 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Politics]]></category>
		<category><![CDATA[Elections]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/01/yes-we-can-scott-brown-wins-ma-special-election/</guid>
		<description><![CDATA[
Sure, it’s a victory for the GOP. But more importantly, it’s a victory for “just right of center” moderates and independents like me. Scott Brown’s astonishing defeat of Martha Coakley, the one “chosen” to replace the late Ted Kennedy, sends a dual message to both the right and left – don’t f*ck with the independents!
While [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.foxnews.com/politics/2010/01/19/polls-close-competitive-massachusetts-senate-race" target="_blank"><img style="border-right-width: 0px; margin: 5px 5px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Epic Upset" border="0" alt="Epic Upset" align="right" src="http://www.josheinstein.com/blog/wp-content/uploads/2010/01/image.png" width="244" height="184" /></a></p>
<p>Sure, it’s a victory for the GOP. But more importantly, it’s a victory for “just right of center” moderates and independents like me. Scott Brown’s <a href="http://www.foxnews.com/politics/2010/01/19/polls-close-competitive-massachusetts-senate-race" target="_blank">astonishing defeat</a> of Martha Coakley, the one “chosen” to replace the late Ted Kennedy, sends a dual message to both the right and left – don’t f*ck with the independents!</p>
<p>While it’s partly true that Democrats left the plane on autopilot, assuming a liberal state like Massachusetts was in the bag, Scott Brown also is a very effective campaigner. On the national stage, he found the right message to attract the right donors and supporters. But at the local level, he struck the right balance between “change” and “mutiny.” Then there’s that little issue of our fearless leader marching in to save the day with his <a href="http://biggovernment.com/2010/01/18/barack-obama-slams-scott-brown-and-his-truck-its-a-gm-truck/" target="_blank">elitist jabs at average everyday people who drive trucks</a>.</p>
<p>But conservatives from outside the state could have just as easily screwed the whole thing up. After the way the tea party purists botched the NY-23 election in November, I was quite worried that the GOP would fracture and turn to cannibalism in an effort to weed out those they deemed were not falling in line. It doesn’t take a genius to realize that you can’t win elections by purging voters. But in November, it seemed as though logic was out the window when they literally handed a seat to the Democrats because a bunch of outsiders didn’t like the nominee.</p>
<p>Glenn Beck and Rush Limbaugh would never get behind a candidate like Chris Christie if given the choice between him and a much more conservative candidate. But had Steve Lonegan (the “conservative” choice) won the NJ primary, MSNBC would be talking to Gov. Jon Corzine tonight. Instead, Gov. Chris Christie was elected and <a href="http://www.nj.com/news/index.ssf/2010/01/nj_gov_chris_christie_inaugura.html" target="_blank">today he was inaugurated</a>.</p>
<p>When your car is out of control and veering to the left, your natural instinct is to jerk the wheel to the right. But in doing so, you make the problem worse and you may never regain control. So while there’s still a lot of work to do to restore balance to our government, today is a good day and 2010 is off to a great start.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F01%2Fyes-we-can-scott-brown-wins-ma-special-election%2F&amp;linkname=Yes%20we%20can%21%20Scott%20Brown%20wins%20MA%20special%20election%21"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/n6Nd2Z4op54" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/01/yes-we-can-scott-brown-wins-ma-special-election/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/01/yes-we-can-scott-brown-wins-ma-special-election/</feedburner:origLink></item>
		<item>
		<title>AT&amp;T fixes bug that logged users into random Facebook accounts</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/MgZ7tfpuKiQ/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/01/att-fixes-bug-that-logged-users-into-random-facebook-accounts/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 05:58:45 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Noise]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/01/att-fixes-bug-that-logged-users-into-random-facebook-accounts/</guid>
		<description><![CDATA[Note sure how Facebook gets off the hook on this one. This is entirely a *Facebook* problem, not AT&#38;T. If Facebook wasn&#8217;t developed by morons with no regard for privacy and security, this bug wouldn&#8217;t be possible.
AT&#38;T fixes bug that logged users into random Facebook accounts




Okay, so we were under the impression that Facebook login [...]]]></description>
			<content:encoded><![CDATA[<p>Note sure how Facebook gets off the hook on this one. This is entirely a *Facebook* problem, not AT&amp;T. If Facebook wasn&#8217;t developed by morons with no regard for privacy and security, this bug wouldn&#8217;t be possible.</p>
<p><a href="http://www.engadget.com/2010/01/18/atandt-fixes-bug-that-logged-users-into-random-facebook-accounts" target="_blank">AT&amp;T fixes bug that logged users into random Facebook accounts</a></p>
<table border="0" cellspacing="0" cellpadding="2" width="437">
<tbody>
<tr>
<td valign="top" width="109"><a href="http://www.engadget.com/2010/01/18/atandt-fixes-bug-that-logged-users-into-random-facebook-accounts" target="_blank"><img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" src="http://www.blogcdn.com/www.engadget.com/media/2010/01/fbooksm.jpg" width="100" height="150" /></a></td>
<td valign="top" width="326"><em><font color="#808080" size="2">Okay, so we were under the impression that Facebook login credentials were a locally-managed affair, but it looks like almost anything can break when AT&amp;T&#8217;s involved &#8212; according to CNET, the carrier just fixed &quot;several problems&quot; that had users logging into the wrong Facebook account from their phones.</font></em></td>
</tr>
</tbody>
</table>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F01%2Fatt-fixes-bug-that-logged-users-into-random-facebook-accounts%2F&amp;linkname=AT%26%23038%3BT%20fixes%20bug%20that%20logged%20users%20into%20random%20Facebook%20accounts"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/MgZ7tfpuKiQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/01/att-fixes-bug-that-logged-users-into-random-facebook-accounts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/01/att-fixes-bug-that-logged-users-into-random-facebook-accounts/</feedburner:origLink></item>
		<item>
		<title>Ed Bott: It’s time to stop using IE6</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/uI63vEhlYbQ/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/01/dump-ie6/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 01:11:46 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[IE]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/01/ed-bott-its-time-to-stop-using-ie6/</guid>
		<description><![CDATA[Ed Bott has thrown down the gauntlet when it comes to companies that still use Internet Explorer 6. Users stuck on IE6 are one of the main reasons IE still has such a bad reputation when it comes to security even though Firefox and Safari were found to be far more vulnerable than Internet Explorer [...]]]></description>
			<content:encoded><![CDATA[<p>Ed Bott has thrown down the gauntlet when it comes to companies that still use Internet Explorer 6. Users stuck on IE6 are one of the main reasons IE still has such a bad reputation when it comes to security even though Firefox and Safari were <a href="http://www.internetnews.com/software/article.php/3847461" target="_blank">found to be far more vulnerable</a> than Internet Explorer in 2009. And according to Ed, allowing people to use IE6 is akin to IT-malpractice.</p>
<blockquote><p><em>Any IT professional who is still allowing IE6 to be used in a corporate setting is guilty of malpractice. Think that judgment is too harsh? Ask the security experts at Google, Adobe, and dozens of other large corporations that are cleaning up the mess from a wave of targeted attacks that allowed source code and confidential data to fall into the hands of well-organized intruders. The entry point? According to Microsoft, it’s IE6.</em></p>
</blockquote>
<p>First, upgrade to <a href="http://www.microsoft.com/windows/internet-explorer/default.aspx">Internet Explorer 8</a> if you haven&#8217;t already.</p>
<p>Then, read more: <a href="http://blogs.zdnet.com/Bott/?p=1645" target="_blank">It&#8217;s time to stop using IE6</a></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F01%2Fdump-ie6%2F&amp;linkname=Ed%20Bott%3A%20It%26%238217%3Bs%20time%20to%20stop%20using%20IE6"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/uI63vEhlYbQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/01/dump-ie6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/01/dump-ie6/</feedburner:origLink></item>
		<item>
		<title>Easy way to prevent WebBrowser control from using window.alert</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/--PqKj6nnwI/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2010/01/webbrowser-control-prevent-window-alert/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 16:04:51 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2010/01/easy-way-to-prevent-webbrowser-control-from-using-window-alert/</guid>
		<description><![CDATA[There are all sorts of official ways of doing this implementing various IE hosting interfaces in order to handle the presentation of the UI. But if you’re trying to automate a web page and a pesky window.alert is blocking your progress, the following code will supress it for the current page.
/// &#60;summary&#62;
/// Handles the Navigated [...]]]></description>
			<content:encoded><![CDATA[<p>There are all sorts of official ways of doing this implementing various IE hosting interfaces in order to handle the presentation of the UI. But if you’re trying to automate a web page and a pesky window.alert is blocking your progress, the following code will supress it for the current page.</p>
<pre class="brush: csharp; collapse: true;">/// &lt;summary&gt;
/// Handles the Navigated event of the browser control.
/// &lt;/summary&gt;
/// &lt;param name=&quot;sender&quot;&gt;The source of the event.&lt;/param&gt;
/// &lt;param name=&quot;e&quot;&gt;The &lt;see cref=&quot;T:WebBrowserNavigatedEventArgs&quot;/&gt; instance containing the
/// event data.&lt;/param&gt;
private void browser_Navigated( object sender, WebBrowserNavigatedEventArgs e )
{

    if ( browser.Document != null ) {

        // kills messagebox functionality by disabling the &quot;window.alert()&quot; function
        object window = browser.Document.Window.DomWindow;
        if ( window != null ) {
            Type windowType = window.GetType();
            BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Instance;
            string[] args = { &quot;window.alert=function() {};&quot;, &quot;JScript&quot; };
            windowType.InvokeMember( &quot;[DispID=1165]&quot;, flags, null, window, args );
        }   // if

    }   // if

}</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2010%2F01%2Fwebbrowser-control-prevent-window-alert%2F&amp;linkname=Easy%20way%20to%20prevent%20WebBrowser%20control%20from%20using%20window.alert"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/--PqKj6nnwI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2010/01/webbrowser-control-prevent-window-alert/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2010/01/webbrowser-control-prevent-window-alert/</feedburner:origLink></item>
		<item>
		<title>Awesome Extension Methods: IEnumerable.Batch</title>
		<link>http://feedproxy.google.com/~r/josheinstein/~3/2vsDNOziNtU/</link>
		<comments>http://www.josheinstein.com/blog/index.php/2009/12/ienumerable-batch/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 07:03:00 +0000</pubDate>
		<dc:creator>Josh Einstein</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Extension Methods]]></category>

		<guid isPermaLink="false">http://www.josheinstein.com/blog/index.php/2009/12/awesome-extension-methods-ienumerable-batch/</guid>
		<description><![CDATA[.NET 3.5 brought a bunch of great extension methods to the framework, most of which extended the IEnumerable&#60;T&#62; (or IQueryable&#60;T&#62;) interfaces implemented by just about every collection type. These include simple ones such as Where, OrderBy, FirstOrDefault, etc as well as more complex ones like Aggregate, GroupBy, etc. The Enumerable class really covers a lot [...]]]></description>
			<content:encoded><![CDATA[<p>.NET 3.5 brought a bunch of great <a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" target="_blank">extension methods</a> to the framework, most of which extended the <a href="http://msdn.microsoft.com/en-us/library/9eekhta0.aspx" target="_blank">IEnumerable&lt;T&gt;</a> (or <a href="http://msdn.microsoft.com/en-us/library/bb351562.aspx" target="_blank">IQueryable&lt;T&gt;</a>) interfaces implemented by just about every collection type. These include simple ones such as <a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.where.aspx" target="_blank">Where</a>, <a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderby.aspx" target="_blank">OrderBy</a>, <a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.firstordefault.aspx" target="_blank">FirstOrDefault</a>, etc as well as more complex ones like <a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.aggregate.aspx" target="_blank">Aggregate</a>, <a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.groupby.aspx" target="_blank">GroupBy</a>, etc. The <a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods.aspx" target="_blank">Enumerable</a> class really covers a lot of ground, but I’ve created a couple more that I use from time to time in my “Common” assembly.</p>
<p>The extension method I’m writing about today is called Batch. It allows you to take any input sequence (array, collection, iterator, etc.) and process it in batches of a specified size.</p>
<p>Many times you will have an input sequence that contains a lot of items but for various reasons, you can’t process the entire sequence at once (memory constraints, you want to update a console with progress, etc.) and processing one at a time is too slow.</p>
<p>Before, I used to write code that would look like this.</p>
<pre class="brush: csharp;">var batch = new List();

foreach (var item in sequence) {

    batch.Add(item);

    if (batch.Count == 100) {
        BulkInsert(batch);
        batch.Clear();
    }

}</pre>
<p>This isn’t too bad but it’s a lot of ceremony and extension methods are all about turning globs like that into more readable, concise code. The method signature for the Batch method looks like the following.</p>
<pre class="brush: csharp;">/// &lt;summary&gt;
/// Enumerates a sequence in chunks, yielding batches of a certain size to the enumerator.
/// &lt;/summary&gt;
/// &lt;typeparam name=&quot;T&quot;&gt;The type of item in the batch.&lt;/typeparam&gt;
/// &lt;param name=&quot;sequence&quot;&gt;The sequence of items to be enumerated.&lt;/param&gt;
/// &lt;param name=&quot;batchSize&quot;&gt;The maximum number of items to include in a batch.&lt;/param&gt;
/// &lt;returns&gt;A sequence of arrays, with each array containing at most
/// &lt;paramref name=&quot;batchSize&quot;/&gt; elements.&lt;/returns&gt;
public static IEnumerable&lt;T[]&gt; Batch&lt;T&gt;( this IEnumerable&lt;T&gt; sequence, int batchSize )</pre>
<p>As the summary suggests, it converts an input sequence into a sequence of arrays of a specified size. The last array in the sequence will have fewer items than the batch size if the input count is not evenly divisible by batchSize. Calling it is very simple. The first example can be rewritten as the following.</p>
<pre class="brush: csharp;">foreach (Record[] batch in sequence.Batch(100)) {
    BulkInsert(batch);
}</pre>
<p>The complete code example is shown below.</p>
<pre class="brush: csharp; collapse: true;">/// &lt;summary&gt;
/// Enumerates a sequence in chunks, yielding batches of a certain size to the enumerator.
/// &lt;/summary&gt;
/// &lt;typeparam name=&quot;T&quot;&gt;The type of item in the batch.&lt;/typeparam&gt;
/// &lt;param name=&quot;sequence&quot;&gt;The sequence of items to be enumerated.&lt;/param&gt;
/// &lt;param name=&quot;batchSize&quot;&gt;The maximum number of items to include in a batch.&lt;/param&gt;
/// &lt;returns&gt;A sequence of arrays, with each array containing at most
/// &lt;paramref name=&quot;batchSize&quot;/&gt; elements.&lt;/returns&gt;
public static IEnumerable&lt;T[]&gt; Batch&lt;T&gt;( this IEnumerable&lt;T&gt; sequence, int batchSize )
{

    var batch = new List&lt;T&gt;( batchSize );

    foreach ( var item in sequence ) {

        batch.Add( item );

        // when we've accumulated enough in the
        // batch, send it out
        if ( batch.Count &gt;= batchSize ) {
            yield return batch.ToArray( );
            batch.Clear( );
        }   // if

    }   // foreach

    // send out any leftovers
    if ( batch.Count &gt; 0 ) {
        yield return batch.ToArray( );
        batch.Clear( );
    }   // if

}</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.josheinstein.com%2Fblog%2Findex.php%2F2009%2F12%2Fienumerable-batch%2F&amp;linkname=Awesome%20Extension%20Methods%3A%20IEnumerable.Batch"><img src="http://www.josheinstein.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><img src="http://feeds.feedburner.com/~r/josheinstein/~4/2vsDNOziNtU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.josheinstein.com/blog/index.php/2009/12/ienumerable-batch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.josheinstein.com/blog/index.php/2009/12/ienumerable-batch/</feedburner:origLink></item>
	</channel>
</rss>
