<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results for 'app:weblogs' matching tag 'WinForms'</title><link>http://msmvps.com/search/SearchResults.aspx?q=app:weblogs&amp;tag=WinForms&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tag 'WinForms'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Extension Methods And Type Inference In Action</title><link>http://msmvps.com/blogs/paulomorgado/archive/2011/04/18/extension-methods-and-type-inference-in-action.aspx</link><pubDate>Mon, 18 Apr 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1791940</guid><dc:creator>paulo</dc:creator><description>&lt;p align="justify"&gt;I make extensive use of &lt;a title="Extension Methods (C# Programming Guide)" href="http://msdn.microsoft.com/library/bb383977.aspx" target="_blank"&gt;extension methods&lt;/a&gt;, either to make classes small and focused or to improve readability.&lt;/p&gt;  &lt;p align="justify"&gt;While porting a &lt;a title="Microsoft .NET Framework" href="http://www.microsoft.com/net/" target="_blank"&gt;&lt;strong&gt;.NET&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; 1.1&lt;/strong&gt; &lt;strong&gt;WinForms&lt;/strong&gt; application to &lt;a title="Microsoft Visual C#" href="http://csharp.net/" target="_blank"&gt;C#&lt;/a&gt; 3.0, I found lots of code like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;delegate int &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Int32DelegateStringBoolean&lt;/span&gt;(&lt;span style="color:blue;"&gt;string &lt;/span&gt;text, &lt;span style="color:blue;"&gt;bool &lt;/span&gt;flag);

&lt;span style="color:blue;"&gt;void &lt;/span&gt;DoStuff()
{
    &lt;span style="color:green;"&gt;// ...

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;&lt;font color="#000000"&gt;x = (&lt;/font&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;.Invoke(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Int32DelegateStringBoolean&lt;/span&gt;(GetStuff), &lt;span style="color:blue;"&gt;new object&lt;/span&gt;[] { &lt;span style="color:#a31515;"&gt;&amp;quot;some text&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;true &lt;/span&gt;});

    &lt;span style="color:green;"&gt;// ...
&lt;/span&gt;}

&lt;span style="color:blue;"&gt;int &lt;/span&gt;GetStuff(&lt;span style="color:blue;"&gt;string &lt;/span&gt;text, &lt;span style="color:blue;"&gt;bool &lt;/span&gt;flag)
{
    &lt;span style="color:green;"&gt;// ...
&lt;/span&gt;}&lt;/pre&gt;

&lt;p align="justify"&gt;&lt;strong&gt;.NET 2.0&lt;/strong&gt; introduced a nicer API and it became possible to write the code calling &lt;strong&gt;Invoke&lt;/strong&gt; like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;x = (&lt;span style="color:blue;"&gt;int&lt;/span&gt;)&lt;span style="color:blue;"&gt;this&lt;/span&gt;.Invoke(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Int32DelegateStringBoolean&lt;/span&gt;(GetStuff), &lt;span style="color:#a31515;"&gt;&amp;quot;some text&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;true&lt;/span&gt;);&lt;/pre&gt;

&lt;p align="justify"&gt;But it’s still not strongly typed enough to my taste and the compiler can’t verify if any mistake was made. This will still be valid code at compile time that will break at run time:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;x = (&lt;span style="color:blue;"&gt;long&lt;/span&gt;)&lt;span style="color:blue;"&gt;this&lt;/span&gt;.Invoke(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Int32DelegateStringBoolean&lt;/span&gt;(GetStuff), &lt;span style="color:#a31515;"&gt;&amp;quot;some text&amp;quot;&lt;/span&gt;, 10M, 5);&lt;/pre&gt;

&lt;p align="justify"&gt;To make the code safer and more readable, I decided to create extension methods to extend the &lt;a title="Control Class" href="http://msdn.microsoft.com/library/system.windows.forms.control.aspx" target="_blank"&gt;Control&lt;/a&gt; class and provide strongly type &lt;strong&gt;Invoke&lt;/strong&gt; methods.&lt;/p&gt;

&lt;p align="justify"&gt;Instead of defining custom delegates for each need, I used the &lt;strong&gt;Action&lt;/strong&gt; and &lt;strong&gt;Func&lt;/strong&gt; delegates exiting in the framework and wrote extension methods like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;TResult InvokeFunc&amp;lt;T1, T2, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, T2, TResult&amp;gt; func, T1 param1, T2 param2)
{
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;(TResult)(control.Invoke(func, param1, param2));
}&lt;/pre&gt;

&lt;p align="justify"&gt;Now I can replace the call to &lt;strong&gt;Invoke&lt;/strong&gt; with this call:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;x = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.InvokeFunc&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;(GetStuff), &lt;span style="color:#a31515;"&gt;&amp;quot;some text&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;true&lt;/span&gt;);&lt;/pre&gt;

&lt;p align="justify"&gt;And the compiler is now able to match the type of the delegate, the parameters and the return value.&lt;/p&gt;

&lt;p align="justify"&gt;Starting with the &lt;strong&gt;C# 2.0&lt;/strong&gt; compiler, there is no need to write the delegate instantiation if the compiler can infer the type of the delegate, which makes the code even simpler:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;x = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.InvokeFunc&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;(GetStuff, &lt;span style="color:#a31515;"&gt;&amp;quot;some text&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;true&lt;/span&gt;);&lt;/pre&gt;

&lt;p align="justify"&gt;The &lt;strong&gt;C#&lt;/strong&gt; compiler is even capable of inferring the type parameters of the &lt;strong&gt;InvokeFunc&lt;/strong&gt; method making the code even smaller and more readable:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;x = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.InvokeFunc(GetStuff, &lt;span style="color:#a31515;"&gt;&amp;quot;some text&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;true&lt;/span&gt;);&lt;/pre&gt;

&lt;p align="justify"&gt;A lot better than what we started with, isn’t it?&lt;/p&gt;

&lt;p align="justify"&gt;So far, I’ve implemented these:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Provides extended functionality to &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;see cref=&amp;quot;System.Windows.Forms.Control&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ControlExtensions
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;A &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;typeparamref name=&amp;quot;TResult&amp;quot;/&amp;gt; &lt;/span&gt;&lt;span style="color:green;"&gt;that contains the return value from the function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) being invoked.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;TResult InvokeFunc&amp;lt;TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TResult&amp;gt; func)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;(TResult)(control.Invoke(func));
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;A &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;typeparamref name=&amp;quot;TResult&amp;quot;/&amp;gt; &lt;/span&gt;&lt;span style="color:green;"&gt;that contains the return value from the function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) being invoked.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;TResult InvokeFunc&amp;lt;T1, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, TResult&amp;gt; func, T1 param1)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;(TResult)(control.Invoke(func, param1));
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;A &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;typeparamref name=&amp;quot;TResult&amp;quot;/&amp;gt; &lt;/span&gt;&lt;span style="color:green;"&gt;that contains the return value from the function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) being invoked.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;TResult InvokeFunc&amp;lt;T1, T2, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, T2, TResult&amp;gt; func, T1 param1, T2 param2)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;(TResult)(control.Invoke(func, param1, param2));
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the third parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The third parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;A &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;typeparamref name=&amp;quot;TResult&amp;quot;/&amp;gt; &lt;/span&gt;&lt;span style="color:green;"&gt;that contains the return value from the function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) being invoked.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;TResult InvokeFunc&amp;lt;T1, T2, T3, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, T2, T3, TResult&amp;gt; func, T1 param1, T2 param2, T3 param3)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;(TResult)(control.Invoke(func, param1, param2, param3));
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the third parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T4&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the forth parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The third parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param4&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The forth parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;A &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;typeparamref name=&amp;quot;TResult&amp;quot;/&amp;gt; &lt;/span&gt;&lt;span style="color:green;"&gt;that contains the return value from the function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) being invoked.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;TResult InvokeFunc&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, T2, T3, T4, TResult&amp;gt; func, T1 param1, T2 param2, T3 param3, T4 param4)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;(TResult)(control.Invoke(func, param1, param2, param3, param4));
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;InvokeAction(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action &lt;/span&gt;action)
    {
        control.Invoke(action);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the parameter.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;InvokeAction&amp;lt;T&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt; action, T param)
    {
        control.Invoke(action, param);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;InvokeAction&amp;lt;T1, T2&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T1, T2&amp;gt; action, T1 param1, T2 param2)
    {
        control.Invoke(action, param1, param2);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the third parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The third parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;InvokeAction&amp;lt;T1, T2, T3&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T1, T2, T3&amp;gt; action, T1 param1, T2 param2, T3 param3)
    {
        control.Invoke(action, param1, param2, param3);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the third parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T4&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the forth parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to invoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to invoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The third parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param4&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The forth parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static void &lt;/span&gt;InvokeAction&amp;lt;T1, T2, T3, T4&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T1, T2, T3, T4&amp;gt; action, T1 param1, T2 param2, T3 param3, T4 param4)
    {
        control.Invoke(action, param1, param2, param3, param4);
    }
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeFunc&amp;lt;TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TResult&amp;gt; func)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(func);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeFunc&amp;lt;T1, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, TResult&amp;gt; func, T1 param1)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(func, param1);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeFunc&amp;lt;T1, T2, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, T2, TResult&amp;gt; func, T1 param1, T2 param2)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(func, param1, param2);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the third parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The third parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeFunc&amp;lt;T1, T2, T3, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, T2, T3, TResult&amp;gt; func, T1 param1, T2 param2, T3 param3)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(func, param1, param2, param3);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified function (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;func&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the third parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T4&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the forth parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;TResult&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the result.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the function on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The function to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The third parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param4&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The forth parameter of the function.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeFunc&amp;lt;T1, T2, T3, T4, TResult&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T1, T2, T3, T4, TResult&amp;gt; func, T1 param1, T2 param2, T3 param3, T4 param4)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(func, param1, param2, param3, param4);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeAction(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action &lt;/span&gt;action)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(action);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the parameter.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeAction&amp;lt;T&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt; action, T param)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(action, param);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeAction&amp;lt;T1, T2&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T1, T2&amp;gt; action, T1 param1, T2 param2)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(action, param1, param2);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the third parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The third parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeAction&amp;lt;T1, T2, T3&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T1, T2, T3&amp;gt; action, T1 param1, T2 param2, T3 param3)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(action, param1, param2, param3);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Executes the specified action (&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;paramref name=&amp;quot;action&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;) on the thread that owns the control&amp;#39;s underlying window handle.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the third parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T4&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The type of the forth parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;control&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The control to BeginInvoke the action on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The action to BeginInvoke.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The first parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The second parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The third parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;param4&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;The forth parameter of the action.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;An System.IAsyncResult that represents the result of the operation.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IAsyncResult &lt;/span&gt;BeginInvokeAction&amp;lt;T1, T2, T3, T4&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Control &lt;/span&gt;control, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T1, T2, T3, T4&amp;gt; action, T1 param1, T2 param2, T3 param3, T4 param4)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;control.BeginInvoke(action, param1, param2, param3, param4);
    }
}&lt;/pre&gt;

&lt;p align="justify"&gt;Use them if you need to.&lt;/p&gt;</description></item><item><title>Setting a Form as a Startup Form with Visual Studio</title><link>http://msmvps.com/blogs/deborahk/archive/2010/12/15/setting-a-form-as-a-startup-form-with-visual-studio.aspx</link><pubDate>Wed, 15 Dec 2010 06:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1784427</guid><dc:creator>DeborahK</dc:creator><description>&lt;p&gt;The startup form is the first form that is launched when your application is executed. By default, a Windows Forms project creates a default form when the project is created. This form is set as the startup form.&lt;/p&gt;  &lt;p&gt;You can change the startup form to any form within your application following the steps below. In this example, the report form is set as the startup form for testing purposes.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;To Set a Form as a Startup Form:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Modify the Program.cs file as follows:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;static void Main()      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Application.EnableVisualStyles();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Application.SetCompatibleTextRenderingDefault(false);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Application.Run(new &lt;strong&gt;ReportWin&lt;/strong&gt;());       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1) Double-click on My Project under the project in Solution Explorer.&lt;/p&gt;  &lt;p&gt;2) Click the Application tab.&lt;/p&gt;  &lt;p&gt;3) Set the Startup form.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/7288.image_5F00_thumb10_5F00_1A855966.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image_thumb10" border="0" alt="image_thumb10" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/4477.image_5F00_thumb10_5F00_thumb_5F00_4485578E.png" width="493" height="303" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Use this technique any time you want to change the start up form for the application.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>HowTo: Crear una pantalla de inicio (splash screen)</title><link>http://msmvps.com/blogs/lfranco/archive/2010/11/26/howto-crear-una-pantalla-de-inicio-splash-screen.aspx</link><pubDate>Fri, 26 Nov 2010 06:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1783020</guid><dc:creator>lfranco</dc:creator><description>&lt;blockquote&gt;   &lt;p&gt;Nota: Otro post en respuesta a una pregunta bastante habitual en los foros MSDN: ¿Cómo crear una pantalla de inicio para mi aplicación?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;He creado un pequeño proyecto de ejemplo, que pueda servir como plantilla base para que cada uno se lo personalice para su aplicación. Este proyecto tiene lo básico: Un formulario sin bordes con una imagen, una barra de progreso, una etiqueta para el título, otra para ir mostrando mensajes, y un botón por si se desea cancelar la carga del programa (al estilo Office 2010).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco.metablogapi/8358.SplashScreen_5F00_6ABA8A32.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="SplashScreen" border="0" alt="SplashScreen" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lfranco.metablogapi/5226.SplashScreen_5F00_thumb_5F00_6FBCC7E1.png" width="451" height="352" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Él proyecto es muy sencillo y lo podéis descargar desde aquí:&lt;/p&gt; &lt;iframe style="padding-bottom:0px;background-color:#fcfcfc;padding-left:0px;width:98px;padding-right:0px;height:115px;padding-top:0px;" title="Preview" src="http://cid-f3a970280830b5fe.office.live.com/embedicon.aspx/MSDN%20Samples/TestSplashScreen.zip" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;p&gt;La pantalla de inicio utiliza un thread para mostrar los diferentes mensajes al cargar, ya que así no se bloquea la aplicación (y la barra de progreso). Esto es así porque en el proyecto de ejemplo, al cargar la pantalla de inicio se lanza un segundo hilo que llama a un método ‘initApplication’, y desde éste método simulamos varios procesos largos (en realidad de un segundo cada uno), y cada vez que se inicia uno de ellos hay que cambiar el mensaje:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; initApplication()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    Thread.Sleep(DEFAULT_TIME);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((MethodInvoker)(() =&amp;gt; setMessage(&lt;span style="color:#006080;"&gt;&amp;quot;Searching for updates...&amp;quot;&lt;/span&gt;)));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    Thread.Sleep(DEFAULT_TIME);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((MethodInvoker)(() =&amp;gt; setMessage(&lt;span style="color:#006080;"&gt;&amp;quot;Connectiong to database...&amp;quot;&lt;/span&gt;)));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    Thread.Sleep(DEFAULT_TIME);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((MethodInvoker)(() =&amp;gt; setMessage(&lt;span style="color:#006080;"&gt;&amp;quot;Connectiong to webservices...&amp;quot;&lt;/span&gt;)));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    Thread.Sleep(DEFAULT_TIME);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((MethodInvoker)(() =&amp;gt; setMessage(&lt;span style="color:#006080;"&gt;&amp;quot;Loading settings...&amp;quot;&lt;/span&gt;)));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    Thread.Sleep(DEFAULT_TIME);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((MethodInvoker)(() =&amp;gt; setMessage(&lt;span style="color:#006080;"&gt;&amp;quot;Loading user preferences...&amp;quot;&lt;/span&gt;)));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    Thread.Sleep(DEFAULT_TIME);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((MethodInvoker)(() =&amp;gt; setMessage(&lt;span style="color:#006080;"&gt;&amp;quot;Starting application...&amp;quot;&lt;/span&gt;)));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    Thread.Sleep(DEFAULT_TIME);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.InvokeRequired) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Action(finishProcess));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Recordar que desde un hilo que no sea el hilo principal, en .NET no se puede actualizar la interfaz de usuario directamente. En su lugar debemos usar el método Invoke. En el ejemplo anterior llamamos a un método ‘setMessage’ que se encarga de mostrar el texto en la etiqueta correspondiente. Para poder llamar a este método mediante Invoke tenemos dos opciones: Podemos usar un MethodInvoker o un Action, en nuestro caso usaremos el primero, ya que un Action se usa cuando no hay paso de parámetros, y este método precisa de un parámetro con el mensaje a mostrar:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; setMessage(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; msg)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    messageLabel.Text = msg;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Una vez finalizado el proceso de carga, se cierra el formulario y se devuelve un DialogResult = Ok. Por otro lado si en cualquier momento de la carga el usuario ha pulsado el botón ‘close’, se hace lo mismo pero devolviendo un DialogResult = Cancel:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; finishProcess()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DialogResult = System.Windows.Forms.DialogResult.OK;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Close();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; closeButton_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DialogResult = System.Windows.Forms.DialogResult.Cancel;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Close();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Como veis el proyecto es muy sencillo, sólo debéis recordar un detalle importante: En una aplicación WinForms el punto de entrada a la misma se define en el método estático Main del Program.cs, y aquí hay una línea que inicializa el formulario inicial de nuestra aplicación:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;Application.Run(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; fMain());&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Lo primero que solemos pensar es que aquí deberíamos lanzar el formulario fSplashScreen, y al cerrarlo mostrar el formulario principal, verdad? Pues no, no podemos hacer eso. El motivo no es otro que este formulario inicial va a definir el ciclo de vida de nuestra aplicación, y si lo cerramos, cerramos la aplicación. Ya se que en VB puede cambiarse este comportamiento, pero entre nosotros... hacerlo siempre me ha parecido una chapuza :-)&lt;/p&gt;

&lt;p&gt;Así pues, aquí lanzaremos el formulario principal, y éste, al cargarse (mientras todavía no es visible) lanzará la pantalla de inicio de forma modal y esperará el valor de retorno. Si al cerrarse la pantalla de bienvenida el valor de retorno es Ok, continúa la carga y muestra el formulario principal, en caso contrario cierra el formulario principal y con por ende la aplicación:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; fMain_Load(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    showSplashScreen();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; showSplashScreen()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (fSplashScreen fsplash = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; fSplashScreen())&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (fsplash.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Close();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Espero que sirva como ejemplo a todos aquellos que desean tener una pantalla de inicio para sus aplicaciones. Un saludo!&lt;/p&gt;

&lt;p&gt;Andorra, Noviembre 2010&lt;/p&gt;</description></item><item><title>Associating Code with a Tag using Delegates II</title><link>http://msmvps.com/blogs/deborahk/archive/2010/11/19/associating-code-with-a-tag-using-delegates-ii.aspx</link><pubDate>Fri, 19 Nov 2010 06:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1782622</guid><dc:creator>DeborahK</dc:creator><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/deborahk/archive/2010/11/19/associating-code-with-a-tag-using-delegates.aspx"&gt;This prior post demonstrated&lt;/a&gt; how to use delegates to associated code with a Tag in a WinForms control. This post shows how to accomplish the same thing using Lambda expressions to define the delegate.&lt;/p&gt;  &lt;p&gt;To try out this example, create a WinForms application and add a TreeView control to the form. Then add the code below.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public delegate void DisplayMessage(string value);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;private void Form1_Load(object sender, EventArgs e)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var rootTreeNode = treeView1.Nodes.Add(&amp;quot;Phones&amp;quot;);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; var appleTreeNode = rootTreeNode.Nodes.Add(&amp;quot;IPhone is the best&amp;quot;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; appleTreeNode.Tag = new DisplayMessage(      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x =&amp;gt; MessageBox.Show(&amp;quot;Apple: &amp;quot; + x));&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; var microsoftTreeNode = rootTreeNode.Nodes.Add(&amp;quot;Win 7 Phone is the best&amp;quot;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; microsoftTreeNode.Tag = new DisplayMessage(      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x =&amp;gt; MessageBox.Show(&amp;quot;Microsoft: &amp;quot; + x));&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; treeView1.ExpandAll();     &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;private void treeView1_DoubleClick(object sender, EventArgs e)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var messageDelegate = (DisplayMessage)treeView1.SelectedNode.Tag;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; messageDelegate.Invoke(treeView1.SelectedNode.Text);      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Delegate Sub DisplayMessage(ByVal value As String)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim rootTreeNode = TreeView1.Nodes.Add(&amp;quot;Phones&amp;quot;)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Dim appleTreeNode = rootTreeNode.Nodes.Add(&amp;quot;IPhone is the best&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; appleTreeNode.Tag = New DisplayMessage(      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Sub(x) MessageBox.Show(&amp;quot;Apple: &amp;quot; &amp;amp; x))&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Dim microsoftTreeNode = rootTreeNode.Nodes.Add(&amp;quot;Win 7 Phone is the best&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; microsoftTreeNode.Tag = New DisplayMessage(      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Sub(x) MessageBox.Show(&amp;quot;Microsoft: &amp;quot; &amp;amp; x))&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; TreeView1.ExpandAll()     &lt;br /&gt;End Sub&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private Sub TreeView1_DoubleClick(ByVal sender As Object,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal e As EventArgs) Handles TreeView1.DoubleClick      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim messageDelegate = TryCast(TreeView1.SelectedNode.Tag,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DisplayMessage)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If messageDelegate IsNot Nothing Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; messageDelegate.Invoke(TreeView1.SelectedNode.Text)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;End Sub      &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The first line of code declares a delegate. If you have not worked with delegates before, &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/10/11/delegates.aspx"&gt;see this prior blog post for more information&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The Load event populates the Treeview with two child nodes. A new instance of the delegate is stored in the Tag property of each node. &lt;/p&gt;  &lt;p&gt;The delegate instance constructor defines the code to call when the user double-clicks on the node. This code is defined using a Lambda expression. If you have not worked with a Lambda expression before, &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/10/11/lambda-expressions-an-introduction.aspx"&gt;see this prior blog post for more information&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The DoubleClick event then pulls the delegate from the Tag property and calls it using the Invoke method, passing the appropriate parameters.&lt;/p&gt;  &lt;p&gt;Use this technique any time you want to define code to execute in the Tag property of a control.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>Associating Code with a Tag using Delegates</title><link>http://msmvps.com/blogs/deborahk/archive/2010/11/19/associating-code-with-a-tag-using-delegates.aspx</link><pubDate>Fri, 19 Nov 2010 06:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1782617</guid><dc:creator>DeborahK</dc:creator><description>&lt;p&gt;Many of the Windows Forms controls have a Tag property that you can use to store data associated with the control. For example, TextBoxes have a Tag property so you could store additional information about each TextBox in the Tag. For TreeView controls, each node has its own Tag property, so you can associate data with each node. But what if you wanted to associated code with each Tag?&lt;/p&gt;  &lt;p&gt;This post details how to use delegates to associated code with a Tag. It uses a TreeView as an example, but any control with a Tag property could use this technique.&lt;/p&gt;  &lt;p&gt;If you want to use a Lambda expression instead of a method to define the delegate, &lt;a href="http://msmvps.com/blogs/deborahk/archive/2010/11/19/associating-code-with-a-tag-using-delegates-ii.aspx"&gt;see this later post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;To try out this example, create a WinForms application and add a TreeView control to the form. Then add the code below.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public delegate void DisplayMessage(string value);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;private void Form1_Load(object sender, EventArgs e)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var rootTreeNode = treeView1.Nodes.Add(&amp;quot;Phones&amp;quot;);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; var appleTreeNode = rootTreeNode.Nodes.Add(&amp;quot;IPhone is the best&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; appleTreeNode.Tag = new DisplayMessage(AppleMessage);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; var microsoftTreeNode = rootTreeNode.Nodes.Add(&amp;quot;Win 7 Phone is the best&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; microsoftTreeNode.Tag = new DisplayMessage(MicrosoftMessage);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; treeView1.ExpandAll();      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public void&amp;#160; AppleMessage(string value)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MessageBox.Show(&amp;quot;Apple: &amp;quot; + value);       &lt;br /&gt;}       &lt;br /&gt;public void MicrosoftMessage(string value)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MessageBox.Show(&amp;quot;Microsoft: &amp;quot; + value);       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;private void treeView1_DoubleClick(object sender, EventArgs e)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var messageDelegate = (DisplayMessage)treeView1.SelectedNode.Tag;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; messageDelegate.Invoke(treeView1.SelectedNode.Text);       &lt;br /&gt;}       &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Delegate Sub DisplayMessage(ByVal value As String)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim rootTreeNode = TreeView1.Nodes.Add(&amp;quot;Phones&amp;quot;)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Dim appleTreeNode = rootTreeNode.Nodes.Add(&amp;quot;IPhone is the best&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; appleTreeNode.Tag = New DisplayMessage(AddressOf AppleMessage)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Dim microsoftTreeNode = rootTreeNode.Nodes.Add(&amp;quot;Win 7 Phone is the best&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; microsoftTreeNode.Tag =       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New DisplayMessage(AddressOf MicrosoftMessage)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; TreeView1.ExpandAll()      &lt;br /&gt;End Sub&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Sub AppleMessage(ByVal value As String)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MessageBox.Show(&amp;quot;Apple: &amp;quot; &amp;amp; value)       &lt;br /&gt;End Sub&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Sub MicrosoftMessage(ByVal value As String)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MessageBox.Show(&amp;quot;Microsoft: &amp;quot; &amp;amp; value)       &lt;br /&gt;End Sub&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private Sub TreeView1_DoubleClick(ByVal sender As Object,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal e As EventArgs) Handles TreeView1.DoubleClick       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim messageDelegate = TryCast(TreeView1.SelectedNode.Tag,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DisplayMessage)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If messageDelegate IsNot Nothing Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; messageDelegate.Invoke(TreeView1.SelectedNode.Text)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Sub       &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The first line of code declares a delegate. If you have not worked with delegates before, &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/10/11/delegates.aspx"&gt;see this blog post for more information&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The Load event populates the Treeview with two child nodes. A new instance of the delegate is stored in the Tag property of each node. The delegate instance defines the method to call when the user double-clicks on the node.&lt;/p&gt;  &lt;p&gt;The AppleMessage method and the MicrosoftMessage method define the two methods to execute. These methods must have a signature that matches the signature of the delegate. In this case, it is a routine that takes one string parameter and does not return a value. But the delegate could define any signature and the methods must then match the delegate&amp;#39;s signature.&lt;/p&gt;  &lt;p&gt;In this example, the methods displayed a messageBox, but the method could do anything. It could perform any type of calculation or perform any processing.&lt;/p&gt;  &lt;p&gt;The DoubleClick event then pulls the delegate from the Tag property and calls it using the Invoke method, passing the appropriate parameters.&lt;/p&gt;  &lt;p&gt;Use this technique any time you want to define code to execute in the Tag property of a control.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>Sorting Lists with Null Values</title><link>http://msmvps.com/blogs/deborahk/archive/2010/10/30/sorting-lists-with-null-values.aspx</link><pubDate>Sat, 30 Oct 2010 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1781100</guid><dc:creator>DeborahK</dc:creator><description>&lt;p&gt;When working with data, you often have values that are null. For example, you may allow entry of a user&amp;#39;s birthday, but not require entry. So some of your rows may contain a null date. Or your application may track a customer&amp;#39;s last order date, which will be null if you track potential customers that have not yet made a purchase.&lt;/p&gt;  &lt;p&gt;When you sort a list that contains null values, the null values will be first in the list as shown below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/8422.image_5F00_5E489340.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/4718.image_5F00_thumb_5F00_5D03FA61.png" width="488" height="103" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;But what if you want the null values at the end and not at the beginning?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/0511.image_5F00_1F2762E5.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/3247.image_5F00_thumb_5F00_79BD6F76.png" width="494" height="108" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This post demonstrates one technique for sorting your null values to the bottom of the list.&lt;/p&gt;  &lt;p&gt;First, some prerequisite code to build the list of business objects that are bound to the grid.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Here is the Customer class:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public class Customer     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public int CustomerId { get; set; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public string LastName { get; set; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public string FirstName { get; set; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public string EmailAddress { get; set; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public DateTime? LastOrderDate { get; set; }      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;And here is the one line of code to build the list of customers:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; List&amp;lt;Customer&amp;gt; custList = new List&amp;lt;Customer&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {new Customer()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { CustomerId = 1,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName=&amp;quot;Bilbo&amp;quot;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastName = &amp;quot;Baggins&amp;quot;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EmailAddress = &amp;quot;bb@hob.me&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastOrderDate = new DateTime(2010,9,1)},      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new Customer()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { CustomerId = 2,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName=&amp;quot;Frodo&amp;quot;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastName = &amp;quot;Baggins&amp;quot;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EmailAddress = &amp;quot;fb@hob.me&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastOrderDate = null},      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new Customer()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { CustomerId = 3,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName = &amp;quot;Samwise&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastName = &amp;quot;Gamgee&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EmailAddress = &amp;quot;sg@hob.me&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastOrderDate = new DateTime(2010, 6, 15),      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new Customer()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { CustomerId = 4,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName = &amp;quot;Rosie&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastName = &amp;quot;Cotton&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EmailAddress = &amp;quot;rc@hob.me&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastOrderDate = new DateTime(2010, 6, 15),      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e"&gt;The code to bind this list to the grid is:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;var sortedList = custList.OrderBy(c =&amp;gt; c.LastOrderDate);     &lt;br /&gt;dataGridView1.DataSource = sortedList.ToList();      &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Here is the Customer class:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Class Customer     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property CustomerId As Integer      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property LastName As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property FirstName As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property EmailAddress As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property LastOrderDate As DateTime?      &lt;br /&gt;End Class&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;And here is the one line of code to build the list of customers:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim custList As New List(Of Customer) From     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {New Customer() With      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {.CustomerId = 1,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .FirstName = &amp;quot;Bilbo&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .LastName = &amp;quot;Baggins&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .EmailAddress = &amp;quot;bb@hob.me&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .LastOrderDate = New DateTime(2010, 9, 1)},      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New Customer() With      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {.CustomerId = 2,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .FirstName = &amp;quot;Frodo&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .LastName = &amp;quot;Baggins&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .EmailAddress = &amp;quot;fb@hob.me&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .LastOrderDate = Nothing},      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New Customer() With      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {.CustomerId = 3,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .FirstName = &amp;quot;Samwise&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .LastName = &amp;quot;Gamgee&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .EmailAddress = &amp;quot;sg@hob.me&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .LastOrderDate = New DateTime(2010, 6, 15)},      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New Customer() With      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {.CustomerId = 4,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .FirstName = &amp;quot;Rosie&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .LastName = &amp;quot;Cotton&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .EmailAddress = &amp;quot;rc@hob.me&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .LastOrderDate = New DateTime(2010, 6, 15)}      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e"&gt;The code to bind this list to the grid is:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim sortedList = custList.OrderBy(Function(c) c.LastOrderDate)     &lt;br /&gt;DataGridView1.DataSource = sortedList.ToList()&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The first set of code defines the customer business object. Note how the LastOrderDate property is defined as a Nullable structure. This allows the date to hold a null value. Both the C# and VB examples use auto-implemented properties, which provide a shortened property syntax.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/deborahk/archive/2010/04/11/auto-implemented-properties.aspx"&gt;See this link&lt;/a&gt; for more information about auto-implemented properties.&lt;/p&gt;  &lt;p&gt;The second (very long) line of code builds the list of customers. Both the C# and VB code build the list using collection initializer syntax.&lt;/p&gt;  &lt;p&gt;The last two lines of code first sort the list using a Lambda expression and then bind that sorted list to a DataGridView.&lt;/p&gt;  &lt;p&gt;If you are not familiar with Lambda expressions, &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/10/11/lambda-expressions-an-introduction.aspx"&gt;see an overview here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;But this example sorts in the default order, with null values first. One way to sort null values to the end is to perform a descending sort. But then all of the rows are sorted in the opposite direction. &lt;/p&gt;  &lt;p&gt;If you want an ascending sort for all of the data, but nulls at the end, you can use multiple sorts as shown below.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;var sortedList = custList     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .OrderBy(c =&amp;gt; !c.LastOrderDate.HasValue)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .ThenBy(c =&amp;gt; c.LastOrderDate);      &lt;br /&gt;dataGridView1.DataSource = sortedList.ToList();      &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim sortedList = custList.     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; OrderBy(Function(c) Not c.LastOrderDate.HasValue).      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ThenBy(Function(c) c.LastOrderDate)      &lt;br /&gt;DataGridView1.DataSource = sortedList.ToList()&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This code first sorts by the LastOrderDate&amp;#39;s HasValue property. The &lt;strong&gt;HasValue&lt;/strong&gt; property of the Nullable structure defines whether or not the property has a value. So if the property has a value, HasValue is true and if the property is null, HasValue is false. This code checks for &amp;quot;not HasValue&amp;quot;, so if the&amp;#160; property is null, the expression is true.&lt;/p&gt;  &lt;p&gt;Since true values are sorted to the end in an ascending sort, the dates with values will be first in the sort order, then the null values.&lt;/p&gt;  &lt;p&gt;The secondary sort (ThenBy), then sorts by the LastOrderDate. This provides the list with the rows in ascending date order, but with the null values last in the list.&lt;/p&gt;  &lt;p&gt;Use this technique any time you need to sort a list and ensure that all null values are at the end of the resulting sorted list.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>Using Enter Key as a Tab</title><link>http://msmvps.com/blogs/deborahk/archive/2010/10/28/using-enter-key-as-a-tab.aspx</link><pubDate>Thu, 28 Oct 2010 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1781005</guid><dc:creator>DeborahK</dc:creator><description>&lt;p&gt;A common question on the forums is how to use the Enter key instead of the Tab key to move through the controls on a Windows form. One common approach is to use SendKeys to send a Tab. But here is another option.&lt;/p&gt;  &lt;p&gt;NOTE: To use this technique, set the &lt;strong&gt;KeyPreview&lt;/strong&gt; property of the form to True.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;private void Form1_KeyDown(object sender, KeyEventArgs e)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Control nextControl ;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (e.KeyCode == Keys.Enter)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nextControl = GetNextControl(ActiveControl, !e.Shift);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (nextControl == null)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nextControl = GetNextControl(null, true);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nextControl.Focus();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e.SuppressKeyPress = true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}       &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private Sub Form1_KeyDown(ByVal sender As Object,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal e As System.Windows.Forms.KeyEventArgs) _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Handles Me.KeyDown       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim nextControl As Control       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If e.KeyCode = Keys.Enter Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nextControl = GetNextControl(ActiveControl, Not e.Shift)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If nextControl Is Nothing Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nextControl = GetNextControl(Nothing, True)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nextControl.Focus()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e.SuppressKeyPress = True       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;End Sub       &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This code first checks the key that was pressed down and if it was the Enter key, processes it.&lt;/p&gt;  &lt;p&gt;It uses the GetNextControl method to find the next control in the tab order. It checks the Shift key and if the Shift key is also pressed, GetNextControl finds the prior key in the tab order. &lt;/p&gt;  &lt;p&gt;If GetNextControl does not find another control (because it runs into the end of the tab order), it calls GetNextControl again passing in a null to start back at the other end of the tab order.&lt;/p&gt;  &lt;p&gt;For example, if you have four TextBoxes: 1,2,3,4, pressing the Enter key will move you from 1 to 2 to 3 to 4 and then back to 1. Pressing Shift + Enter will move you from 4 to 3 to 2 to 1.&lt;/p&gt;  &lt;p&gt;Use this technique any time your users want to use the Enter key instead of the Tab key to move through the controls on a Windows form.&lt;/p&gt;  &lt;p&gt;Hope this helps.&lt;/p&gt;</description></item><item><title>WinForms Checklist</title><link>http://msmvps.com/blogs/deborahk/archive/2010/09/21/winforms-checklist.aspx</link><pubDate>Tue, 21 Sep 2010 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1778532</guid><dc:creator>DeborahK</dc:creator><description>&lt;p&gt;There are endless numbers of details you have to contend with when building great software. So it is easy to forget about some of the small ones, especially when it comes to the UI. So I use a checklist like this one to help ensure I covered all of my bases.&lt;/p&gt;  &lt;h2&gt;Form&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;Related&amp;#160; controls are grouped together&lt;/li&gt;    &lt;li&gt;Controls are in a logical sequence&lt;/li&gt;    &lt;li&gt;Controls are aligned appropriately&lt;/li&gt;    &lt;li&gt;Tab order is set&lt;/li&gt;    &lt;li&gt;Standard font family and size are set&lt;/li&gt;    &lt;li&gt;Title bar text is descriptive&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Modal Dialog&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;Minimize button disabled&lt;/li&gt;    &lt;li&gt;Maximize button disabled&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Resizable Dialog&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;Minimum size defined&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Prevents the form from being resized too small to be usable&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Controls appropriately anchored/docked to size as the dialog resizes&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;No resize code should be required in most cases&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;h2&gt;Controls&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;All text is spelled correctly&lt;/li&gt;    &lt;li&gt;Labels are consistent in tense and terminology&lt;/li&gt;    &lt;li&gt;Tooltips defined on all appropriate controls&lt;/li&gt;    &lt;li&gt;Disabled controls are grayed out and not accessible&lt;/li&gt;    &lt;li&gt;Buttons are all a consistent size and location on the screen&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Validation&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;All required fields are validated&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;All required fields are distinguished in some manner, such as bolding the label, adding an asterisk, or highlighting the control (pick one technique and use it consistently)&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;All numeric fields are validated&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Use this checklist as you finish each one of your WinForm UI components so you don&amp;#39;t have to sweat the details.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>Setting WinForms Colors to a Named, RGB, or Hex Value</title><link>http://msmvps.com/blogs/deborahk/archive/2010/08/17/setting-winforms-colors-to-a-named-rgb-or-hex-value.aspx</link><pubDate>Tue, 17 Aug 2010 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1776169</guid><dc:creator>DeborahK</dc:creator><description>&lt;p&gt;Sometimes you want to add a little color to your WinForms controls. WinForms comes with a large set of named colors that you can use. &lt;/p&gt;  &lt;p&gt;NOTE: Be sure to import a reference to &lt;strong&gt;System.Drawing&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;For example&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;textBox1.BackColor = Color.Linen;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;textBox1.BackColor = Color.Linen&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;But what if you want to display a color that is not one of the named colors? Then you can use the Color.FromArgb method to define your color by specifying the red, green, and blue values.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;textBox1.BackColor = Color.FromArgb(250, 245, 235);&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;textBox1.BackColor = Color.FromArgb(250, 245, 235)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ah, but what if you have the color defined as a hexadecimal value? Well, you could use Bing/Google to find a converter to convert it to RGB. Or you can use the ColorTranslator.FromHtml method.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;textBox1.BackColor = ColorTranslator.FromHtml(&amp;quot;#FAF9F9&amp;quot;);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;textBox3.BackColor = ColorTranslator.FromHtml(&amp;quot;#FAF9F9&amp;quot;)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Use any of these techniques to add some color to your WinForms applications.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>Updating the UI On an Arbitrary Thread</title><link>http://msmvps.com/blogs/p3net/pages/updating-the-ui-on-an-arbitrary-thread.aspx</link><pubDate>Sun, 18 Jul 2010 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1774195</guid><dc:creator>MichaelTaylor</dc:creator><description>&lt;p style="font-size:smaller;"&gt;(Originally published: 5 March 2007)&lt;/p&gt;
&lt;p&gt;It is very common to have to perform work on a secondary thread.&amp;nbsp; This allows us to provide a more interactive UI to our users while still allowing us to do lengthy work.&amp;nbsp; Unfortunately this is not as easy as it first appears.&amp;nbsp; We will discuss the problem, the standard v1.x solution and the v2 solution to the problem.&lt;/p&gt;
&lt;h2&gt;Why Do We Need It&lt;/h2&gt;
&lt;p&gt;Windows has always had the cardinal rule that a UI element can only be interacted with on the thread that created it.&amp;nbsp; This is because internally Windows still uses a message queue to communicate with UI elements.&amp;nbsp; The message queue is per-thread.&amp;nbsp; It is created on the thread that created the element.&amp;nbsp; This ensures that all messages are serialized to the UI and simplifies our work.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;However it is often necessary to do work on secondary threads and still update the UI.&amp;nbsp; In order for this to work we have to actually send the request to the UI&amp;#39;s thread and then have it pushed onto the message queue.&amp;nbsp; There are a couple of different ways to do this.&amp;nbsp; We&amp;#39;ll look at the most common method in v1.x and v2.&amp;nbsp; .NET v3.x introduces the concept of synchronization contexts which can be used to execute code on specific threads.&amp;nbsp; Synchronization contexts are a lengthy topic that will not be covered in this article.&lt;/p&gt;
&lt;h2&gt;v1.x Solution - Invoke and InvokeRequired&lt;/h2&gt;
&lt;p&gt;Every UI element (a control, here on out) has a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx"&gt;InvokeRequired&lt;/a&gt; property.&amp;nbsp; This property can be called on any thread and indicates whether the calling thread is the thread that created the control.&amp;nbsp; If it is then the property is &lt;span class="code"&gt;false&lt;/span&gt; otherwise it is &lt;span class="code"&gt;true&lt;/span&gt;.&amp;nbsp; When working with controls in a multithreaded environment you must check this property.&amp;nbsp; If it is true then you must marshal the request to the UI thread.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;You marshal the request to the UI thread using the &lt;a href="http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx"&gt;Invoke&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/0b1bf3y3.aspx"&gt;BeginInvoke/EndInvoke&lt;/a&gt; methods.&amp;nbsp; These methods can be called on any thread.&amp;nbsp; In each case they accept a delegate, switch to the UI thread and then call the delegate.&lt;/p&gt;
&lt;div class="code"&gt;... &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&amp;nbsp;(myControl.InvokeRequired)&amp;nbsp;&lt;/div&gt;
&lt;div class="code"&gt;&amp;nbsp;&amp;nbsp; myControl.Invoke(...); &lt;br /&gt;&lt;span class="keyword"&gt;else&lt;/span&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;/div&gt;
&lt;p&gt;To make things easier we generally wrap the above code in a method and then create a delegate with the same signature.&amp;nbsp; This allows us to use one function for two different purposes.&amp;nbsp; The first &amp;quot;version&amp;quot; is called in all cases and determines whether an invoke is required.&amp;nbsp; The second &amp;quot;version&amp;quot; actually does the work on the UI thread.&amp;nbsp; This is a nice way to hide the details from your clients.&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="keyword"&gt;delegate&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;UpdateProgressDelegate&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;int&lt;/span&gt;&amp;nbsp;progress&amp;nbsp;); &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;UpdateProgress&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;int&lt;/span&gt;&amp;nbsp;progress&amp;nbsp;) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="lineComment"&gt;//If&amp;nbsp;not&amp;nbsp;on&amp;nbsp;UI&amp;nbsp;thread&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&amp;nbsp;(myProgress.InvokeRequired) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myProgress.Invoke(&lt;span class="keyword"&gt;new&lt;/span&gt;&amp;nbsp;UpdateProgressDelegate(UpdateProgress),&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;object&lt;/span&gt;[]&amp;nbsp;{&amp;nbsp;progress&amp;nbsp;}); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;else&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="lineComment"&gt;//Do&amp;nbsp;work&amp;nbsp;here&amp;nbsp;-&amp;nbsp;called&amp;nbsp;on&amp;nbsp;UI&amp;nbsp;thread&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myProgress.Value&amp;nbsp;=&amp;nbsp;progress; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}; &lt;br /&gt;}&lt;/div&gt;
&lt;p&gt;As far as your users are concerned this is a clean interface.&amp;nbsp; They simply call &lt;span class="code"&gt;UpdateProgress&lt;/span&gt;.&amp;nbsp; Internally if an invocation is required to get the call on the UI thread then it does so.&amp;nbsp; However it calls the same method again.&amp;nbsp; The second time it is called it will be done on the UI thread.&amp;nbsp; The biggest downside to this code is that: a) you have to write it, and b) you have to define a delegate.&amp;nbsp; Here is how we might call it.&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;Run&amp;nbsp;(&amp;nbsp;) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread&amp;nbsp;t&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&amp;nbsp;Thread(&lt;span class="keyword"&gt;new&lt;/span&gt;&amp;nbsp;ThreadStart(DoWork));&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;t.IsBackground&amp;nbsp;=&amp;nbsp;&lt;span class="booleanLiteral"&gt;true&lt;/span&gt;;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;t.Start(); &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;UpdateProgress&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;int&lt;/span&gt;&amp;nbsp;progress&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp;myProgress.Value&amp;nbsp;=&amp;nbsp;progress;&amp;nbsp;}&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;DoWork&amp;nbsp;(&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;for&lt;/span&gt;&amp;nbsp;(&lt;span class="builtinType"&gt;int&lt;/span&gt;&amp;nbsp;nIdx&amp;nbsp;=&amp;nbsp;&lt;span class="integerLiteral"&gt;1&lt;/span&gt;;&amp;nbsp;nIdx&amp;nbsp;&amp;lt;=&amp;nbsp;&lt;span class="integerLiteral"&gt;100&lt;/span&gt;;&amp;nbsp;++nIdx)&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(&lt;span class="integerLiteral"&gt;50&lt;/span&gt;);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UpdateProgress(nIdx); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&amp;nbsp; &lt;br /&gt;}&amp;nbsp;&lt;/div&gt;
&lt;h2&gt;v2 Solution - BackgroundWorker Component&lt;/h2&gt;
&lt;p&gt;Since this is such a common situation in v2 Microsoft has added the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx"&gt;BackgroundWorker&lt;/a&gt; component (BWC).&amp;nbsp; This component&amp;#39;s sole purpose in life is to do work on a secondary thread and then update the UI.&amp;nbsp; The component requires that you identify the function to run.&amp;nbsp; It will then run the function on a thread pool thread.&amp;nbsp; Once it is complete the component will raise the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted.aspx"&gt;RunWorkerCompleted&lt;/a&gt; event.&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;Run&amp;nbsp;(&amp;nbsp;) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackgroundWorker&amp;nbsp;bwc&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&amp;nbsp;BackgroundWorker();&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.DoWork&amp;nbsp;+=&amp;nbsp;DoWork;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.RunWorkerCompleted&amp;nbsp;+=&amp;nbsp;OnCompleted;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.RunWorkerAsync();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="lineComment"&gt;//Run&amp;nbsp;it&lt;/span&gt; &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;OnCompleted&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;object&lt;/span&gt;&amp;nbsp;sender,&amp;nbsp;RunWorkerCompletedEventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp;MessageBox.Show(&lt;span class="stringliteral"&gt;&amp;quot;Done&amp;quot;&lt;/span&gt;);&amp;nbsp;}&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;DoWork&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;object&lt;/span&gt;&amp;nbsp;sender,&amp;nbsp;DoWorkEventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;for&lt;/span&gt;&amp;nbsp;(&lt;span class="builtinType"&gt;int&lt;/span&gt;&amp;nbsp;nIdx&amp;nbsp;=&amp;nbsp;&lt;span class="integerLiteral"&gt;1&lt;/span&gt;;&amp;nbsp;nIdx&amp;nbsp;&amp;lt;=&amp;nbsp;&lt;span class="integerLiteral"&gt;100&lt;/span&gt;;&amp;nbsp;++nIdx)&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;Thread.Sleep(&lt;span class="integerLiteral"&gt;50&lt;/span&gt;);&amp;nbsp;};&amp;nbsp; &lt;br /&gt;}&lt;/div&gt;
&lt;p&gt;Notice a few things about the code.&amp;nbsp; Firstly it is smaller as we don&amp;#39;t have to worry about the thread management.&amp;nbsp; Secondly notice we do not have to worry about the UI thread.&amp;nbsp; All events exposed by &lt;span class="code"&gt;BWC&lt;/span&gt; are raised on the UI thread automatically.&amp;nbsp; Note that you can drop &lt;span class="code"&gt;BWC&lt;/span&gt; onto your form or control because it shows up in the designer.&amp;nbsp; Personally I prefer to create it on the fly.&lt;/p&gt;
&lt;p&gt;There is a problem with the above code.&amp;nbsp; It does not actually update the progress while it is running.&amp;nbsp; In order to raise progress events we need to tell &lt;span class="code"&gt;BWC&lt;/span&gt; we will be raising progress notifications.&amp;nbsp; We also need to hook up another function to handle the event.&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;Run&amp;nbsp;(&amp;nbsp;) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackgroundWorker&amp;nbsp;bwc&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&amp;nbsp;BackgroundWorker();&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.DoWork&amp;nbsp;+=&amp;nbsp;DoWork;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.RunWorkerCompleted&amp;nbsp;+=&amp;nbsp;OnCompleted;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;bwc.WorkerReportsProgress&amp;nbsp;=&amp;nbsp;&lt;/b&gt;&lt;span class="booleanLiteral" style="font-weight:bold;"&gt;true&lt;/span&gt;&lt;b&gt;;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.ProgressChanged&amp;nbsp;+=&amp;nbsp;OnProgressChanged; &lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.RunWorkerAsync();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="lineComment"&gt;//Run&amp;nbsp;it&lt;/span&gt; &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword" style="font-weight:bold;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType" style="font-weight:bold;"&gt;void&lt;/span&gt;&lt;b&gt;&amp;nbsp;OnProgressChanged&amp;nbsp;(&amp;nbsp;&lt;/b&gt;&lt;span class="builtinType" style="font-weight:bold;"&gt;object&lt;/span&gt;&lt;b&gt;&amp;nbsp;sender,&amp;nbsp;ProgressChangedEventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp;myProgress.Value&amp;nbsp;=&amp;nbsp;e.ProgressPercentage;&amp;nbsp;} &lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;OnCompleted&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;object&lt;/span&gt;&amp;nbsp;sender,&amp;nbsp;RunWorkerCompletedEventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp;MessageBox.Show(&lt;span class="stringliteral"&gt;&amp;quot;Done&amp;quot;&lt;/span&gt;);&amp;nbsp;}&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;DoWork&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;object&lt;/span&gt;&amp;nbsp;sender,&amp;nbsp;DoWorkEventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackgroundWorker&amp;nbsp;bwc&amp;nbsp;=&amp;nbsp;sender&amp;nbsp;&lt;span class="keyword"&gt;as&lt;/span&gt;&amp;nbsp;BackgroundWorker;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;for&lt;/span&gt;&amp;nbsp;(&lt;span class="builtinType"&gt;int&lt;/span&gt;&amp;nbsp;nIdx&amp;nbsp;=&amp;nbsp;&lt;span class="integerLiteral"&gt;1&lt;/span&gt;;&amp;nbsp;nIdx&amp;nbsp;&amp;lt;=&amp;nbsp;&lt;span class="integerLiteral"&gt;100&lt;/span&gt;;&amp;nbsp;++nIdx)&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(&lt;span class="integerLiteral"&gt;50&lt;/span&gt;);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;bwc.ReportProgress(nIdx);&lt;/b&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;}&lt;/div&gt;
&lt;p&gt;The changes are in bold.&amp;nbsp; Basically the &lt;span class="code"&gt;UpdateProgress&lt;/span&gt; of earlier changes to &lt;span class="code"&gt;OnProgressChanged&lt;/span&gt;.&amp;nbsp; Again, it is called on the UI thread.&amp;nbsp; We have to report progress using &lt;a href="http://msdn.microsoft.com/en-us/library/ka89zff4.aspx"&gt;BWC.ReportProgress&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One final feature of &lt;span class="code"&gt;BWC&lt;/span&gt; that was not in the original code we wrote is cancellation support.&amp;nbsp; It is often nice to allow users to cancel lengthy tasks.&amp;nbsp; &lt;span class="code"&gt;BWC&lt;/span&gt; supports this automatically.&amp;nbsp; All you have to do is tell it that you will allow cancellation and then periodically check for a cancellation request.&amp;nbsp; For algorithms that loop you generally check at the beginning of each loop.&amp;nbsp; The more frequently you check the cancellation flag (&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancellationpending.aspx"&gt;CancellationPending&lt;/a&gt;) the faster your user will see the process be cancelled.&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;Run&amp;nbsp;(&amp;nbsp;) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackgroundWorker&amp;nbsp;bwc&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&amp;nbsp;BackgroundWorker();&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.DoWork&amp;nbsp;+=&amp;nbsp;DoWork;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.RunWorkerCompleted&amp;nbsp;+=&amp;nbsp;OnCompleted;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.WorkerReportsProgress&amp;nbsp;=&amp;nbsp;&lt;span class="booleanLiteral"&gt;true&lt;/span&gt;;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.ProgressChanged&amp;nbsp;+=&amp;nbsp;OnProgressChanged; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;bwc.WorkerSupportsCancellation&amp;nbsp;=&amp;nbsp;&lt;/b&gt;&lt;span class="booleanLiteral" style="font-weight:bold;"&gt;true&lt;/span&gt;;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.RunWorkerAsync();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="lineComment"&gt;//Run&amp;nbsp;it&lt;/span&gt; &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword" style="font-weight:bold;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType" style="font-weight:bold;"&gt;void&lt;/span&gt;&lt;b&gt;&amp;nbsp;btnCancel_Click&amp;nbsp;(&amp;nbsp;&lt;/b&gt;&lt;span class="builtinType" style="font-weight:bold;"&gt;object&lt;/span&gt;&lt;b&gt;&amp;nbsp;sender,&amp;nbsp;EventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp;bwc.CancelAsync();&amp;nbsp;} &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;OnProgressChanged&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;object&lt;/span&gt;&amp;nbsp;sender,&amp;nbsp;ProgressChangedEventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp;myProgress.Value&amp;nbsp;=&amp;nbsp;e.ProgressPercentage;&amp;nbsp;} &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;OnCompleted&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;object&lt;/span&gt;&amp;nbsp;sender,&amp;nbsp;RunWorkerCompletedEventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword" style="font-weight:bold;"&gt;if&lt;/span&gt;&lt;b&gt;&amp;nbsp;(e.Cancelled)&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(&lt;/b&gt;&lt;span class="stringliteral" style="font-weight:bold;"&gt;&amp;quot;Cancelled&amp;quot;&lt;/span&gt;&lt;b&gt;);&amp;nbsp; &lt;br /&gt;&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;else&lt;/span&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(&lt;span class="stringliteral"&gt;&amp;quot;Done&amp;quot;&lt;/span&gt;); &lt;br /&gt;}&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span class="builtinType"&gt;void&lt;/span&gt;&amp;nbsp;DoWork&amp;nbsp;(&amp;nbsp;&lt;span class="builtinType"&gt;object&lt;/span&gt;&amp;nbsp;sender,&amp;nbsp;DoWorkEventArgs&amp;nbsp;e&amp;nbsp;)&amp;nbsp; &lt;br /&gt;{&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;BackgroundWorker&amp;nbsp;bwc&amp;nbsp;=&amp;nbsp;sender&amp;nbsp;&lt;span class="keyword"&gt;as&lt;/span&gt;&amp;nbsp;BackgroundWorker;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;for&lt;/span&gt;&amp;nbsp;(&lt;span class="builtinType"&gt;int&lt;/span&gt;&amp;nbsp;nIdx&amp;nbsp;=&amp;nbsp;&lt;span class="integerLiteral"&gt;1&lt;/span&gt;;&amp;nbsp;nIdx&amp;nbsp;&amp;lt;=&amp;nbsp;&lt;span class="integerLiteral"&gt;100&lt;/span&gt;;&amp;nbsp;++nIdx)&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword" style="font-weight:bold;"&gt;if&lt;/span&gt;&lt;b&gt;&amp;nbsp;(bwc.CancellationPending) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.Cancel&amp;nbsp;=&amp;nbsp;&lt;/b&gt;&lt;span class="booleanLiteral" style="font-weight:bold;"&gt;true&lt;/span&gt;&lt;b&gt;; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;span class="keyword" style="font-weight:bold;"&gt;return&lt;/span&gt; &lt;b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}; &lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(&lt;span class="integerLiteral"&gt;50&lt;/span&gt;);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bwc.ReportProgress(nIdx);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}; &lt;br /&gt;}&lt;/div&gt;
&lt;p&gt;Here we&amp;#39;ve set the property notifying &lt;span class="code"&gt;BWC&lt;/span&gt; that we support cancellation and we check for cancellation during each iteration of the loop.&amp;nbsp; We also modified the completion handler to detect whether the operation completed or was cancelled.&amp;nbsp; The only hard part here is actually hooking a control (such as a button) up to cancel the work.&amp;nbsp; If you use the designer to drop the &lt;span class="code"&gt;BWC&lt;/span&gt; on your form then you can use the field that is created to access the &lt;span class="code"&gt;BWC&lt;/span&gt;.&amp;nbsp; In the above code it was a local variable so you would have to somehow store the local variable somewhere where the cancel button&amp;#39;s click handler could get to it.&amp;nbsp; I leave that for you to figure out.&lt;/p&gt;
&lt;h2&gt;Why Not Do It Automatically&lt;/h2&gt;
&lt;p&gt;Some people ask why, if it is so common, Windows does not do this automatically or why the framework developers didn&amp;#39;t do it, or why they shouldn&amp;#39;t do it themeselves.&amp;nbsp; The answer is performance.&amp;nbsp; As common as it might be most UI interaction still occurs on the appropriate thread.&amp;nbsp; It is not really worth the performance hit to always handle the situation.&amp;nbsp; This is a common theme throughout the framework.&amp;nbsp; Another problem with threading messages is the order.&amp;nbsp; In general if you send two messages (one right after the other) then you expect the first message to be processed first and then the second message.&amp;nbsp; With asynchronous calls this might not be true.&amp;nbsp; Therefore more effort must be put into ensuring that the ordering of messages is not important.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Most classes in the framework are not thread safe.&amp;nbsp; The reasoning is that it adds complexity and degrades performance.&amp;nbsp; A good multithreaded appliation does not allow just any object to be accessed across threads.&amp;nbsp; This would be a bad design.&amp;nbsp; Instead only a select few objects are shared and it is these objects that need to be thread safe, not the entire application.&lt;/p&gt;
&lt;p&gt;Until Windows sheds its message queue behavior I&amp;#39;m afraid we are stuck with this limitation.&amp;nbsp; Although I believe WPF has somewhat remedied the situation...&lt;/p&gt;</description></item></channel></rss>