<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.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>Dan Gartner's codetastic blog about programming and other things (such as hotdogs, for instance).</title><link>http://blogs.msdn.com/b/dgartner/</link><description>Apparently, this is a blog.</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Using Assert::ExpectException with Native Unit Testing in VS11</title><link>http://blogs.msdn.com/b/dgartner/archive/2012/04/22/using-assert-expectexception-with-native-unit-testing-in-vs11.aspx</link><pubDate>Mon, 23 Apr 2012 00:36:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10296278</guid><dc:creator>dgartner_live.com</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dgartner/rsscomments.aspx?WeblogPostID=10296278</wfw:commentRss><comments>http://blogs.msdn.com/b/dgartner/archive/2012/04/22/using-assert-expectexception-with-native-unit-testing-in-vs11.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;The native unit testing capabilities in VS11 beta are very cool indeed.&amp;nbsp; Being mainly a managed code developer, I was left wondering how to pass a test if an expected exception is thrown (a al the [ExpectedException] attribute I’ve used with MS-TEST in managed code unit tests.&amp;nbsp; With the native unit testing capabilities in VS11, there is no ExpectedException attribute, but there is a static Assert::ExpectException method that we use to verify that our code under test throws an exception.&amp;nbsp; It accepts a lambda or a functor as a parameter.&amp;nbsp; Being a beta, I hadn’t seen too many examples, so I’ve included a couple below.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;        TEST_METHOD(ExpectCallThrowException)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;            auto func = [&lt;span class="kwrd"&gt;this&lt;/span&gt;] { throwException();};&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;            Assert::ExpectException&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;(func);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; throwException()&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            &lt;span class="kwrd"&gt;throw&lt;/span&gt; 1;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Here is a more realistic example, where my BankAccount class throws an invalid_argument exception if a zero amount is passed in as the parameter.&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;double&lt;/span&gt; BankAccount::Debit(&lt;span class="kwrd"&gt;double&lt;/span&gt; amount)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(amount == 0)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="kwrd"&gt;throw&lt;/span&gt; std::invalid_argument(&lt;span class="str"&gt;"amount"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    balance -= amount;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; balance;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&lt;span class="kwrd"&gt;double&lt;/span&gt; BankAccount::Credit(&lt;span class="kwrd"&gt;double&lt;/span&gt; amount)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(amount == 0)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        &lt;span class="kwrd"&gt;throw&lt;/span&gt; std::invalid_argument(&lt;span class="str"&gt;"amount"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    balance += amount;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; balance;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And for my test code, we have examples below of using Assert::ExpectException with a lambda, or by catching the exception ourselves and verifying in the test.&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;    &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;#include &amp;lt;stdexcept&amp;gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;#include &amp;lt;functional&amp;gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        TEST_METHOD(InvalidArgumentIsThrownWhenDebittingZero)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            BankAccount* sut = &lt;span class="kwrd"&gt;new&lt;/span&gt; BankAccount();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;            &lt;span class="kwrd"&gt;double&lt;/span&gt; amount = 0.00;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            function&amp;lt;&lt;span class="kwrd"&gt;double&lt;/span&gt; (&lt;span class="kwrd"&gt;void&lt;/span&gt;)&amp;gt; f1 = [sut] { &lt;span class="kwrd"&gt;return&lt;/span&gt; sut-&amp;gt;Debit(0.00); };&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            Assert::ExpectException&amp;lt;invalid_argument&amp;gt;(f1);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        TEST_METHOD(ExceptionThrownWhenCreditAmountIsZero)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            BankAccount* sut = &lt;span class="kwrd"&gt;new&lt;/span&gt; BankAccount();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            &lt;span class="kwrd"&gt;double&lt;/span&gt; amount = 0.00;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            &lt;span class="kwrd"&gt;bool&lt;/span&gt; exceptionThrown = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;                sut-&amp;gt;Credit(amount);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            }&lt;span class="kwrd"&gt;catch&lt;/span&gt;(invalid_argument&amp;amp; ex)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;                auto desc = ex.what();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;                exceptionThrown = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            Assert::IsTrue(exceptionThrown);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;        }&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I haven’t seen too many examples of using Assert::ExpectException, so hopefully this is helpful.&amp;nbsp; If this all changes for the VS11 RTM, I’ll be sure to update this post.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;br&gt;-Dan&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10296278" width="1" height="1"&gt;</description></item><item><title>Useful Windows and SQL Azure Whitepapers</title><link>http://blogs.msdn.com/b/dgartner/archive/2010/06/23/useful-windows-and-sql-azure-whitepapers.aspx</link><pubDate>Wed, 23 Jun 2010 18:28:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10029140</guid><dc:creator>dgartner_live.com</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dgartner/rsscomments.aspx?WeblogPostID=10029140</wfw:commentRss><comments>http://blogs.msdn.com/b/dgartner/archive/2010/06/23/useful-windows-and-sql-azure-whitepapers.aspx#comments</comments><description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Below is a collection of useful whitepapers on Windows and SQL Azure that have been recently released.&amp;nbsp; I plan on updating this page as others are released.&amp;nbsp; &lt;/p&gt; &lt;h3&gt;&lt;a name="_Toc264954434"&gt;Developing and Deploying with SQL Azure&lt;/a&gt;&lt;/h3&gt; &lt;h6&gt;Brief Description&lt;/h6&gt; &lt;p&gt;This document provides guidelines on how to deploy an existing on-premise SQL Server database into SQL Azure. It also discusses best practices related to data migration. &lt;h6&gt;Overview&lt;/h6&gt; &lt;p&gt;SQL Azure Database is a cloud based relational database service from Microsoft. SQL Azure provides relational database functionality as a utility service. Cloud-based database solutions such as SQL Azure can provide many benefits, including rapid provisioning, cost-effective scalability, high availability, and reduced management overhead.&lt;br /&gt;This document provides guidelines on how to deploy an existing on-premise SQL Server database into SQL Azure. It also discusses best practices related to data migration. &lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=45066b7f-a444-4aa8-ae13-88adf5473acd"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=45066b7f-a444-4aa8-ae13-88adf5473acd&lt;/a&gt; &lt;p&gt;&amp;nbsp; &lt;h3&gt;&lt;a name="_Toc264954444"&gt;Security Guidelines for SQL Azure&lt;/a&gt;&lt;/h3&gt; &lt;h6&gt;Brief Description&lt;/h6&gt; &lt;p&gt;This document provides an overview of security guidelines for customers who connect to SQL Azure Database, and who build secure applications on SQL Azure. &lt;h6&gt;Overview&lt;/h6&gt; &lt;p&gt;SQL Azure Database is a cloud database service from Microsoft. SQL Azure provides Web-facing database functionality as a utility service. Cloud-based database solutions such as SQL Azure can provide many benefits, including rapid provisioning, cost-effective scalability, high availability, and reduced management overhead. This document provides an overview of security guidelines for customers who connect to SQL Azure Database, and who build secure applications on SQL Azure. &lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=4322517e-9d80-4ad3-8a75-bf0a10aa64d9"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=4322517e-9d80-4ad3-8a75-bf0a10aa64d9&lt;/a&gt; &lt;h3&gt;&amp;nbsp;&lt;/h3&gt; &lt;h3&gt;&lt;a name="_Toc264357242"&gt;Scaling out with SQL Azure&lt;/a&gt;&lt;/h3&gt; &lt;h6&gt;Brief Description&lt;/h6&gt; &lt;p&gt;This paper provides an overview on some scale-out strategies, challenges with scaling out on-premise, and the benefits of scaling out with SQL Azure. &lt;h6&gt;Overview&lt;/h6&gt; &lt;p&gt;SQL Azure Database is a cloud database service from Microsoft. SQL Azure provides Web-facing database functionality as a utility service. Cloud-based database solutions such as SQL Azure can provide many benefits, including rapid provisioning, cost-effective scalability, high availability, and reduced management overhead. This paper provides an overview on some scale-out strategies, challenges with scaling out on-premise, and the benefits of scaling out with SQL Azure. &lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=4931d76f-0e21-44a7-8699-852eec6ee029"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=4931d76f-0e21-44a7-8699-852eec6ee029&lt;/a&gt; &lt;h3&gt;&amp;nbsp;&lt;/h3&gt; &lt;h3&gt;&lt;a name="_Toc264357378"&gt;Windows Azure Architecture Guide – Part 1 – Code Samples&lt;/a&gt;&lt;/h3&gt; &lt;h6&gt;Brief Description&lt;/h6&gt; &lt;p&gt;Moving Applications to the Cloud&lt;br /&gt;This guide has four accompanying samples, covering all of the scenarios described in the book: a typical on-premises application, the first migration to Windows Azure and subsequent optimizations.  &lt;h6&gt;Overview&lt;/h6&gt; &lt;p&gt;These samples illustrate the steps towards migration of a typical application built with .NET to the Windows Azure platform. To check for software prerequisites needed to run the samples, run CheckDependencies.cmd in the sample scenarios folder once all content is extracted to your local file system. This batch file launches a dependency checking tool that reports any components that are missing in your system, and it provides links if needed for obtaining, installing and configuring the missing components. Not all of samples require the same components to run.  &lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=76883a9f-f4aa-4218-add3-1c9b8cc36fc7"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=76883a9f-f4aa-4218-add3-1c9b8cc36fc7&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp; &lt;h3&gt;Security Best Practices for Developing Windows Azure Applications&lt;/h3&gt; &lt;h6&gt;Brief Description&lt;/h6&gt; &lt;p&gt;A document describing how to build more secure Windows Azure applications &lt;h6&gt;Overview&lt;/h6&gt; &lt;p&gt;In this document Microsoft describes some of the security technologies software developers should use, and the security design and development practices they should use to build more secure Windows Azure applications. &lt;p&gt;&lt;a title="http://www.microsoft.com/downloads/details.aspx?familyid=0FF0C25F-DC54-4F56-AAE7-481E67504DF6&amp;amp;displaylang=en" href="http://www.microsoft.com/downloads/details.aspx?familyid=0FF0C25F-DC54-4F56-AAE7-481E67504DF6&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=0FF0C25F-DC54-4F56-AAE7-481E67504DF6&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10029140" width="1" height="1"&gt;</description></item><item><title>Trying and Retrying in C#</title><link>http://blogs.msdn.com/b/dgartner/archive/2010/03/09/trying-and-retrying-in-c.aspx</link><pubDate>Tue, 09 Mar 2010 21:56:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9975795</guid><dc:creator>dgartner_live.com</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dgartner/rsscomments.aspx?WeblogPostID=9975795</wfw:commentRss><comments>http://blogs.msdn.com/b/dgartner/archive/2010/03/09/trying-and-retrying-in-c.aspx#comments</comments><description>&lt;p&gt;I sometimes encounter a requirement where we want to execute some code and, if that method throws an exception, we want to retry executing it several times until some limit is reached.&amp;#160; In this scenario, the thrown exception was expected at times by the application, and could be ignored. The operation was something that failed frequently enough that it was necessary sometimes to retry until it succeeded (web services calls for example may fail due to intermittent connectivity issues).&lt;/p&gt;  &lt;p&gt;Another scenario was that if the code failed, we wanted to wait a period of time before retrying. Below is what I came up with. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;           var service = &lt;span class="kwrd"&gt;new&lt;/span&gt; WebService();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;            &lt;span class="rem"&gt;//the type parameter is for the return type of &lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;            &lt;span class="rem"&gt;//the method we are retrying (GetDataFromRemoteServer()&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;            &lt;span class="rem"&gt;//returns a string in this example)&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;            var retrier = &lt;span class="kwrd"&gt;new&lt;/span&gt; Retrier&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;            &lt;span class="rem"&gt;//call the service up to 3 times in the event of failure&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; result = retrier.Try(&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;                () =&amp;gt; service.GetDataFromRemoteServer(), 3);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            &lt;span class="rem"&gt;//call the service up to 3 times, &lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            &lt;span class="rem"&gt;//wait 500ms if there is a failure&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; result2 = retrier.TryWithDelay(&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;                ()=&amp;gt; service.GetDataFromRemoteServer(), 3, 500);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;And here is the Retrier class.&amp;#160; It takes a lambda expression, tries to execute it, and if an exception is thrown, it swallows it and retries executing the code until maxRetries is reached.&amp;#160; This is only useful in scenarios where the exception that gets thrown is expected from time to time, and you just want to ignore it and re-execute your code.&amp;#160; One way to improve would be to take as a parameter an ExpectedException type, and if the caught exception does not match that, throw.&amp;#160; You should never swallow exceptional exceptions.&amp;#160; Also, if you try to execute the method the maximum number or retry times, and it is never successful, you probably want to go ahead and rethrow the exception in that case.&amp;#160; One scenario I think this might be useful is calling web services where the network connection is prone to failure, thus you want to retry in the event of a failure.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Retrier&amp;lt;TResult&amp;gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; TResult Try(Func&amp;lt;TResult&amp;gt; func, &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; maxRetries)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        TResult returnValue = &lt;span class="kwrd"&gt;default&lt;/span&gt;(TResult);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; numTries = 0;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;bool&lt;/span&gt; succeeded = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        &lt;span class="kwrd"&gt;while&lt;/span&gt; (numTries &amp;lt; maxRetries)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;                returnValue = func();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;                succeeded = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;                &lt;span class="rem"&gt;//todo: figure out what to do here&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            &lt;span class="kwrd"&gt;finally&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;                numTries++;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (succeeded)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; returnValue;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt;(TResult);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; TResult TryWithDelay(Func&amp;lt;TResult&amp;gt; func, &lt;span class="kwrd"&gt;int&lt;/span&gt; maxRetries, &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; delayInMilliseconds)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        TResult returnValue = &lt;span class="kwrd"&gt;default&lt;/span&gt;(TResult);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt; numTries = 0;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        &lt;span class="kwrd"&gt;bool&lt;/span&gt; succeeded = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        &lt;span class="kwrd"&gt;while&lt;/span&gt; (numTries &amp;lt; maxRetries)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;            &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;                returnValue = func();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;                succeeded = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;                &lt;span class="rem"&gt;//todo: figure out what to do here&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;            &lt;span class="kwrd"&gt;finally&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;                numTries++;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (succeeded)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; returnValue;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;            System.Threading.Thread.Sleep(delayInMilliseconds);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt;(TResult);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9975795" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/retry/">retry</category><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/try/">try</category></item><item><title>WPF Attached Behavior Example – Watermark Text</title><link>http://blogs.msdn.com/b/dgartner/archive/2009/11/11/wpf-attached-behavior-example-watermark-text.aspx</link><pubDate>Wed, 11 Nov 2009 16:51:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9920898</guid><dc:creator>dgartner_live.com</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dgartner/rsscomments.aspx?WeblogPostID=9920898</wfw:commentRss><comments>http://blogs.msdn.com/b/dgartner/archive/2009/11/11/wpf-attached-behavior-example-watermark-text.aspx#comments</comments><description>&lt;p&gt;I’ve been working on a relatively simple WPF application lately, in an effort to effectively follow the MVVM pattern, I’ve been working with custom attached properties.&amp;nbsp; In my app, I have some textboxes that I want to contain some default text that is removed when the user tabs into the control:&lt;/p&gt; &lt;p&gt;Unfocused: &lt;a href="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/WPFAttachedBehaviorExampleWatermarkText_98AC/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/WPFAttachedBehaviorExampleWatermarkText_98AC/image_thumb.png" width="244" height="51"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Focused:&lt;a href="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/WPFAttachedBehaviorExampleWatermarkText_98AC/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/WPFAttachedBehaviorExampleWatermarkText_98AC/image_thumb_1.png" width="244" height="38"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;I could implement an event handler for the GotFocus and LostFocus events, but that would require some code in the code-behind, and isn’t particularly re-usable (show below):&lt;/p&gt; &lt;div style="overflow: auto"&gt; &lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnInputTextBoxGotFocus(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;            var tb = e.OriginalSource &lt;span class="kwrd"&gt;as&lt;/span&gt; TextBox;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;                ClearTextBox(tb);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ResetTextBox(TextBox tb)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb.Name == &lt;span class="str"&gt;"tbWhat"&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(tb.Text))&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;                    tb.Text = &lt;span class="str"&gt;"What."&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb.Name == &lt;span class="str"&gt;"tbWhere"&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(tb.Text))&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;                    tb.Text = &lt;span class="str"&gt;"Where."&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ClearTextBox(TextBox tb)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb.Name == &lt;span class="str"&gt;"tbWhat"&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb.Text == &lt;span class="str"&gt;"What."&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;                    tb.Text = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb.Name == &lt;span class="str"&gt;"tbWhere"&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb.Text == &lt;span class="str"&gt;"Where."&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;                    tb.Text = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnInputTextBoxLostFocus(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;            var tb = e.OriginalSource &lt;span class="kwrd"&gt;as&lt;/span&gt; TextBox;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;                ResetTextBox(tb);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The above code is pretty terrible, and specific to the two textboxes I have on my window (tbWhat and tbWhere).&amp;nbsp; Ugly stuff, that fortunately can be replaced by a more elegant solution.&amp;nbsp; There have been some good blog posts on WPF Attached Behaviors: &lt;a title="http://www.mindscape.co.nz/blog/index.php/2009/02/01/attached-behaviours-in-wpf/" href="http://www.mindscape.co.nz/blog/index.php/2009/02/01/attached-behaviours-in-wpf/"&gt;http://www.mindscape.co.nz/blog/index.php/2009/02/01/attached-behaviours-in-wpf/&lt;/a&gt; and &lt;a title="http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx" href="http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx"&gt;http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx&lt;/a&gt; are what I read to get up to speed.&lt;/p&gt;
&lt;p&gt;In my implementation, I want some default text to be displayed in the textbox, and I want to text to disappear when the user focuses into the textbox.&amp;nbsp; To do this, I’m going to have my behavior attach two dependency properties to the textbox, IsWatermarkEnabled and WatermarkText.&amp;nbsp; When IsWatermarkEnabled is set to true or false, I will attach or detach event handlers to the GotFocus and LostFocus events.&amp;nbsp; Below is the complete code listing:&lt;/p&gt;
&lt;div style="overflow: auto"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TextBoxFocusBehavior&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetWatermarkText(DependencyObject obj)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;)obj.GetValue(WatermarkText);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetWatermarkText(DependencyObject obj, &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            obj.SetValue(WatermarkText, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; GetIsWatermarkEnabled(DependencyObject obj)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; (&lt;span class="kwrd"&gt;bool&lt;/span&gt;)obj.GetValue(IsWatermarkEnabled);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetIsWatermarkEnabled(DependencyObject obj, &lt;span class="kwrd"&gt;bool&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            obj.SetValue(IsWatermarkEnabled, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; DependencyProperty IsWatermarkEnabled =&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            DependencyProperty.RegisterAttached(&lt;span class="str"&gt;"IsWatermarkEnabled"&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;bool&lt;/span&gt;), &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(TextBoxFocusBehavior),&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; UIPropertyMetadata(&lt;span class="kwrd"&gt;false&lt;/span&gt;, OnIsWatermarkEnabled));&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; DependencyProperty WatermarkText =&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            DependencyProperty.RegisterAttached(&lt;span class="str"&gt;"WatermarkText"&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;            &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;), &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(TextBoxFocusBehavior),&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; UIPropertyMetadata(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty, OnWatermarkTextChanged));&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnWatermarkTextChanged(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DependencyPropertyChangedEventArgs e)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            TextBox tb = sender &lt;span class="kwrd"&gt;as&lt;/span&gt; TextBox;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;                tb.Text = (&lt;span class="kwrd"&gt;string&lt;/span&gt;) e.NewValue;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnIsWatermarkEnabled(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DependencyPropertyChangedEventArgs e)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;            TextBox tb = sender &lt;span class="kwrd"&gt;as&lt;/span&gt; TextBox;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;                &lt;span class="kwrd"&gt;bool&lt;/span&gt; isEnabled = (&lt;span class="kwrd"&gt;bool&lt;/span&gt;)e.NewValue;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (isEnabled)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;                {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;                    tb.GotFocus += OnInputTextBoxGotFocus;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;                    tb.LostFocus += OnInputTextBoxLostFocus;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;                }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;                {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;                    tb.GotFocus -= OnInputTextBoxGotFocus;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;                    tb.LostFocus -= OnInputTextBoxLostFocus;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:  &lt;/span&gt;                }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  58:  &lt;/span&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  60:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  61:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnInputTextBoxLostFocus(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  62:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  63:  &lt;/span&gt;            var tb = e.OriginalSource &lt;span class="kwrd"&gt;as&lt;/span&gt; TextBox;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  64:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  65:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  66:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(tb.Text))&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  67:  &lt;/span&gt;                    tb.Text = GetWatermarkText(tb);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  68:  &lt;/span&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  69:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  70:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  71:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnInputTextBoxGotFocus(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  72:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  73:  &lt;/span&gt;            var tb = e.OriginalSource &lt;span class="kwrd"&gt;as&lt;/span&gt; TextBox;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  74:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  75:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  76:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (tb.Text == GetWatermarkText(tb))&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  77:  &lt;/span&gt;                    tb.Text = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  78:  &lt;/span&gt;            }   &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  79:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  80:  &lt;/span&gt;    }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;To attach this behavior to my textbox in XAML, I first add an xmlns reference to my behaviors namespace: xmlns:local="clr-namespace:StopForgetting.Behaviors" and add the behavior to the TextBox XAML:&lt;/p&gt;
&lt;div style="overflow: auto"&gt;&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBox&lt;/span&gt; &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;="tbWhere"&lt;/span&gt; &lt;span class="attr"&gt;local:TextBoxFocusBehavior&lt;/span&gt;.&lt;span class="attr"&gt;IsWatermarkEnabled&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="attr"&gt;local:TextBoxFocusBehavior&lt;/span&gt;.&lt;span class="attr"&gt;WatermarkText&lt;/span&gt;&lt;span class="kwrd"&gt;="Where."&lt;/span&gt; &lt;span class="attr"&gt;Style&lt;/span&gt;&lt;span class="kwrd"&gt;="{StaticResource InputBox}"&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;="150"&lt;/span&gt; &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;="5"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TextBox&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
               &lt;/pre&gt;&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;And that’s it.&amp;nbsp; Much more re-usable than placing event handlers in the code-behind.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/WPFAttachedBehaviorExampleWatermarkText_98AC/image_10.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/WPFAttachedBehaviorExampleWatermarkText_98AC/image_thumb_4.png" width="244" height="21"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/WPFAttachedBehaviorExampleWatermarkText_98AC/image_12.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/WPFAttachedBehaviorExampleWatermarkText_98AC/image_thumb_5.png" width="244" height="20"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9920898" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/wpf/">wpf</category><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/attached/">attached</category><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/mvvm/">mvvm</category><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/behavior/">behavior</category></item><item><title>ASP.Net AJAX – Seadragon AJAX Control – making it work with DeepZoomPix</title><link>http://blogs.msdn.com/b/dgartner/archive/2009/10/22/asp-net-ajax-seadragon-ajax-control-making-it-work-with-deepzoompix.aspx</link><pubDate>Thu, 22 Oct 2009 18:01:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9911569</guid><dc:creator>dgartner_live.com</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dgartner/rsscomments.aspx?WeblogPostID=9911569</wfw:commentRss><comments>http://blogs.msdn.com/b/dgartner/archive/2009/10/22/asp-net-ajax-seadragon-ajax-control-making-it-work-with-deepzoompix.aspx#comments</comments><description>&lt;p&gt;The &lt;a href="http://ajaxcontroltoolkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=33804"&gt;latest version of the AJAX Control Toolkit&lt;/a&gt; includes a new &lt;a href="http://www.asp.net/ajax/ajaxcontroltoolkit/samples/Seadragon/Seadragon.aspx"&gt;SeaDragon control&lt;/a&gt; that allows you to DeepZoom images with pure JavaScript.&amp;nbsp; This is very cool, however, the instructions for &lt;a href="http://livelabs.com/seadragon-ajax/embed-viewer/#form"&gt;embedding the viewer&lt;/a&gt; seem to already be out of date. &lt;/p&gt; &lt;p&gt;The instructions tell you to “copy the URL that appears at the bottom” after you have uploaded your image.&amp;nbsp; Since PhotoZoom has changed to &lt;a href="http://deepzoompix.com/Default.aspx"&gt;DeepZoomPix&lt;/a&gt;, these instructions no longer apply (there is no URL at the bottom of the image in DeepZoomPix).&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/ASP.NetAJAXSeadragonAJAXControlmakingitw_B70F/embed_seadragon_viewer_1.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Unfortunately, there is no URL at the bottom in DeepZoomPix." border="0" alt="Unfortunately, there is no URL at the bottom in DeepZoomPix." src="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/ASP.NetAJAXSeadragonAJAXControlmakingitw_B70F/embed_seadragon_viewer_thumb_1.png" width="372" height="269"&gt;&lt;/a&gt; &lt;/p&gt; &lt;h3&gt;Fiddler Workaround&lt;/h3&gt; &lt;p&gt;Until they update the documentation, you can use &lt;a href="http://www.fiddlertool.com/fiddler/version.asp"&gt;fiddler&lt;/a&gt; to discover the appropriate url for your DeepZoom image.&lt;/p&gt; &lt;p&gt;After adding your image to a DeepZoomPix album, launch Fiddler and browse to your album.&amp;nbsp; Fiddler should capture a series of requests that looks something like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/ASP.NetAJAXSeadragonAJAXControlmakingitw_B70F/fiddler_trace_seadragon.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="You are looking for a url with the word &amp;quot;Image&amp;quot; in it." border="0" alt="You are looking for a url with the word &amp;quot;Image&amp;quot; in it." src="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/ASP.NetAJAXSeadragonAJAXControlmakingitw_B70F/fiddler_trace_seadragon_thumb.png" width="570" height="174"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;The url you are interested will point to an xml file and will start with something similar to /DZ/100/0/&lt;strong&gt;Image&lt;/strong&gt;/ (look for that Image directory).&amp;nbsp; Right click and copy the URL.&lt;/p&gt; &lt;p&gt;Then, navigate back to the &lt;a href="http://livelabs.com/seadragon-ajax/embed-viewer/#form"&gt;Live Labs Seadragon Wizard&lt;/a&gt;, and paste the url into the appropriate textbox (shown below) and you should be good to go.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/ASP.NetAJAXSeadragonAJAXControlmakingitw_B70F/wizard_textbox.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="wizard_textbox" border="0" alt="wizard_textbox" src="http://blogs.msdn.com/blogfiles/dgartner/WindowsLiveWriter/ASP.NetAJAXSeadragonAJAXControlmakingitw_B70F/wizard_textbox_thumb.png" width="354" height="70"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Here is the final product:&lt;/p&gt;&lt;script type="text/javascript" src="http://seadragon.com/ajax/embed.js"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;Seadragon.embed("400px", "300px", "http://deepzoompix.com/DZ/100/0/Image/468bd985-5292-40e9-8ea6-de44b0cbb67d.xml", 800, 800, 448, 0, "jpg");&lt;/script&gt; &lt;p&gt;Hope this helps,&lt;/p&gt; &lt;p&gt;-Dan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9911569" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/deepzoompix/">deepzoompix</category><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/seadragon/">seadragon</category><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/deepzoom/">deepzoom</category><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/asp-net+ajax/">asp.net ajax</category><category domain="http://blogs.msdn.com/b/dgartner/archive/tags/deepzoompiz/">deepzoompiz</category></item></channel></rss>