<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5359546512544809971</id><updated>2012-02-16T10:20:25.242-08:00</updated><category term='Threading'/><category term='Book Review'/><category term='Data Access'/><category term='Languages'/><category term='Lambda Expression'/><category term='MVC'/><category term='General'/><category term='WCF'/><category term='Code Camp'/><category term='User Control'/><category term='Silverlight 3'/><category term='Data Template'/><category term='Value Converter'/><category term='Design Patterns'/><category term='Event'/><category term='BackgroundWorker'/><category term='WPF'/><category term='.NET'/><category term='XAML'/><category term='Silverlight'/><category term='ASP.NET'/><category term='Extension Method'/><title type='text'>Jeremy Bytes</title><subtitle type='html'>byte-sized chunks of .NET</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>59</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7324481896029869187</id><published>2012-01-01T14:00:00.000-08:00</published><updated>2012-01-02T12:26:22.353-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Happy New Year!</title><content type='html'>Another year has gone by, and we have another year to look forward to.  Thank you to everyone who attended one of my sessions at a code camp or user group.  You are why I keep presenting.&lt;br /&gt;&lt;br /&gt;Over the last 2 years, you've come out to see me at &lt;b&gt;45 sessions&lt;/b&gt; across&amp;nbsp;&lt;b&gt;20 events&lt;/b&gt;, with a total of &lt;b&gt;over 1,500 people&lt;/b&gt; in attendance (1,510, but who's counting?).&lt;br /&gt;&lt;br /&gt;We've got another great year coming up.  I've already got several sessions scheduled, and I hope to see you at one in the future.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Jan 28 &amp;amp; 29 - So Cal Code Camp (Fullerton, CA)&lt;/li&gt;&lt;li&gt;Mar 6 - San Diego .NET Developers Group (San Diego, CA)&lt;/li&gt;&lt;li&gt;Mar 20 - Disney .NET Developers Group (Burbank, CA)&lt;/li&gt;&lt;li&gt;Mar 21 - San Gabriel Valley .NET Developers Group (Monrovia, CA)&lt;/li&gt;&lt;li&gt;Apr 26 - Southern Nevada's .NET User Group (Las Vegas, NV)&lt;/li&gt;&lt;li&gt;May 8 - Inland Empire .NET User's Group (Riverside, CA)&lt;/li&gt;&lt;/ul&gt;All of these dates are subject to change (so be sure to check beforehand), and there will be more events in 2012 as well. &amp;nbsp;Hope to see you at one of them.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7324481896029869187?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7324481896029869187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2012/01/happy-new-year.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7324481896029869187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7324481896029869187'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2012/01/happy-new-year.html' title='Happy New Year!'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7176566535266701271</id><published>2011-11-13T11:29:00.001-08:00</published><updated>2011-11-13T12:08:21.384-08:00</updated><title type='text'>Exceptions in Multi-Cast Delegates</title><content type='html'>At the last 2 code camps (So Cal Code Camp and Desert Code Camp), the same question came up. How do exceptions affect the process flow when invoking a multi-cast delegate? Let's do a quick review and then take a closer look. For more information, please take a look at &lt;a href="http://www.jeremybytes.com/demos.aspx#GF"&gt;Get Func&amp;lt;&amp;gt;-y: Delegates in .NET&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Multi-Cast Delegates&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;All delegates in .NET are multi-cast delegates. This means that we can assign multiple methods to the same delegate variable. When we invoke the delegate variable (to run the methods), then all methods that have been assigned are run.&lt;br /&gt;&lt;br /&gt;For example, take a look at this Action variable:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Action&amp;lt;List&amp;lt;Person&amp;gt;&amp;gt; act;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then we can assign multiple methods as follows (in this case using lambda expressions):&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;act += p =&amp;gt; Console.WriteLine(p.Average(r =&amp;gt; r.Rating)).ToString();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;act += p =&amp;gt; Console.WriteLine(p.Min(s =&amp;gt; s.StartDate));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then we can invoke the delegate (assuming that "people" is a list of Person objects):&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;act(people);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The resulting output to the console window is as follows:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;6.4285714285714288&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;10/17/1975&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Single-Threaded Execution&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;.NET does not do anything magical when it runs the methods assigned to the delegate. &amp;nbsp;They simply run in order, synchronously, on the same thread where the delegate is invoked. &amp;nbsp;In the examples from the "Get Func&amp;lt;&amp;gt;-y" session, we invoke the delegate from the UI thread of a WPF application, and we see that if one of the methods is blocking (such as a MessageBox.Show() method that waits for user input), then the other methods do not execute until that method has completed. &amp;nbsp;(As you can imagine, if we wanted the methods to run on separate threads, we could do that; but that is not the default behavior.)&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Exceptions&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Now, what happens if we add an exception into the mix:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;act += p =&amp;gt; Console.WriteLine(p.Average(r =&amp;gt; r.Rating)).ToString();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;act += p =&amp;gt; { throw new Exception("Error Here"); };&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;act += p =&amp;gt; Console.WriteLine(p.Min(s =&amp;gt; s.StartDate));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What do we expect to happen? &amp;nbsp;Will all 3 methods execute? &amp;nbsp;None of the methods? &amp;nbsp;Only the first one?&lt;br /&gt;&lt;br /&gt;The answer turns out to be pretty simple. &amp;nbsp;Since the methods are run in order, the first method will execute successfully, the second method will throw an exception, and the third will not execute. &amp;nbsp;Since we do not have any exception handling defined, our application will stop working. &amp;nbsp;The console window will have the following:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;6.4285714285714288&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, we can see that the first method did in fact run, but the third method did not.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Exception Handling&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;We can keep our application operational by adding a try/catch block around the invocation of the delegate. &amp;nbsp;This will keep our application from completely erroring out:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; act(people);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;catch (Exception ex)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; Console.WriteLine("Caught Exception: {0}", ex.Message);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And our output now looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;6.4285714285714288&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Caught Exception: Error Here&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But something to notice, even though our application continues (and completes normally), the third method still does not run. &amp;nbsp;And this should not be surprising. &amp;nbsp;When an exception is thrown, the system will walk up the call stack until it finds an exception handler. &amp;nbsp;If it does not find one, then the application will error out. &amp;nbsp;In this case, when the exception in the second method is thrown, it walks back up the call stack to the method that invoked the delegate. &amp;nbsp;There it finds the try/catch and handles the exception. &amp;nbsp;But since we exited out of the actual delegate invocation, the third method is not called.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Some Things to Think About&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Now let's consider a bit how we use delegates. &amp;nbsp;Generally, we (as developers) are on one end of the delegate or the other -- meaning we are creating a delegate so that other developers can hook into our code, or we are using a delegate to hook into someone else's code.&lt;br /&gt;&lt;br /&gt;If we are creating a delegate that we invoke (such as the call to&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;act(people)&lt;/span&gt;&amp;nbsp;above), then we should definitely consider wrapping the invocation in a try/catch block. &amp;nbsp;When someone assigns a method to a delegate that we then invoke, we really have no control over what that assigned method does. &amp;nbsp;This means that we need to protect our code to make sure that someone else's mistake does not cause our code to crash. &amp;nbsp;We need to handle any exceptions that are generated by the invocation so that our application can continue to operate (or at least fail gracefully).&lt;br /&gt;&lt;br /&gt;Also, as we noted in "Get Func&amp;lt;&amp;gt;-y", we should be checking the delegate before invocation to make sure that it is not null. &amp;nbsp;In this code sample, it would look like the following:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; if(act != null)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; act(people);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If we try to invoke a delegate variable that does not have any methods assigned, then we will get a null reference exception. &amp;nbsp;Alternately, we could handle the NullReferenceException in our catch block, but it's usually better to avoid the exception if it can be anticipated.&lt;br /&gt;&lt;br /&gt;But what if we're on the other side of the delegate? &amp;nbsp;What if we are a developer who is assigning methods to a delegate to hook into someone else's code? &amp;nbsp;In that case, we need to follow standard practices for error handling in those methods. &amp;nbsp;We could easily add a try/catch block to the method that we assign to a delegate variable. &amp;nbsp;This way we would have the first shot at handling the exception. &amp;nbsp;And since the exception is happening in our code, we are probably in the best position to try to handle it. &amp;nbsp;If we cannot handle the exception, then we can let it bubble up (as we saw in the sample above). &amp;nbsp;How we handle this will depend on the type of delegates that we are working with, what our business processes are, and how we have designed our error handling and failure modes through the rest of the application.&lt;br /&gt;&lt;br /&gt;We always need to be on the lookout for the unexpected. &amp;nbsp;In the sample code that shows up in my demos, the error handling has been excluded (just so that we can more clearly focus on the topic at hand). &amp;nbsp;But when building our applications, we need to make sure that we are following good programming practices and making sure that we can handle the exceptions that may occur in our code.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7176566535266701271?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7176566535266701271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/11/exceptions-in-multi-cast-delegates.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7176566535266701271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7176566535266701271'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/11/exceptions-in-multi-cast-delegates.html' title='Exceptions in Multi-Cast Delegates'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7868301126693098725</id><published>2011-09-18T12:06:00.000-07:00</published><updated>2011-09-18T12:06:13.926-07:00</updated><title type='text'>Upcoming Code Camps</title><content type='html'>Code Camps are a great way to spend a day or two hearing great presentations, talking to other developers, and seeing what's hot in the dev community. &amp;nbsp;Best of all Code Camp is always FREE!&lt;br /&gt;&lt;br /&gt;If you are a developer, you have something to share. &amp;nbsp;Sign up as a speaker. &amp;nbsp;It's easy, it's fun, and you'll learn a lot doing it. &amp;nbsp;Here are some tips for Code Camp Speakers:&amp;nbsp;&lt;a href="http://jeremybytes.blogspot.com/2011/08/meet-next-code-camp-speaker-you.html"&gt;Meet the Next Code Camp Speaker: You!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;So Cal Code Camp - Los Angeles, CA&lt;/span&gt;&lt;br /&gt;&lt;b&gt;October 15 - 16, 2011&lt;/b&gt;&lt;br /&gt;If you're in the Southern California area (or are looking for an excuse to go there), come join us at the So Cal Code Camp. &amp;nbsp;There are a ton of sessions to choose from, lots of developers to meet, and always a good time to be had.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.socalcodecamp.com/"&gt;So Cal Code Camp&lt;/a&gt;&lt;br /&gt;I'll be speaking.&amp;nbsp;&amp;nbsp;&lt;a href="http://www.socalcodecamp.com/socalcodecamp/presenters.aspx"&gt;Will you?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Desert Code Camp - Chandler, AZ&lt;/span&gt;&lt;br /&gt;&lt;b&gt;November 5, 2011&lt;/b&gt;&lt;br /&gt;If you're in the Phoenix area (or are looking for a reason to head out to the desert), come join us at the Desert Code Camp. &amp;nbsp;There are great developers to meet, a ton of variety in the sessions offered, and even session tracks just for kids.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nov2011.desertcodecamp.com/home"&gt;Desert Code Camp&lt;/a&gt;&lt;br /&gt;I'll be speaking.&amp;nbsp;&amp;nbsp;&lt;a href="http://nov2011.desertcodecamp.com/speakers"&gt;Will you?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7868301126693098725?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7868301126693098725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/09/upcoming-code-camps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7868301126693098725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7868301126693098725'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/09/upcoming-code-camps.html' title='Upcoming Code Camps'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-1171670041549701934</id><published>2011-08-16T21:23:00.000-07:00</published><updated>2011-10-01T21:47:40.991-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Camp'/><title type='text'>Meet the Next Code Camp Speaker: You!</title><content type='html'>If you are in the So Cal area, the next code camp is only 8 weeks away. &amp;nbsp;It's the perfect time to sign up to be a speaker:&amp;nbsp;&lt;a href="http://www.socalcodecamp.com/"&gt;http://www.socalcodecamp.com/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Code Camp speakers come from the developer community. &amp;nbsp;That's you! &amp;nbsp;It turns out that most developers have something to say. &amp;nbsp;We have all picked up tips and tricks with each new project we work on. &amp;nbsp;In addition, we constantly find things in the development platform that we weren't familiar with before. &amp;nbsp;And many times we find ourselves saying, "I wish someone had told me about this before."&lt;br /&gt;&lt;br /&gt;Now's your chance. &amp;nbsp;Code Camp is an easy place to get started as a speaker. &amp;nbsp;As a developer, you are speaking to other developers. &amp;nbsp;We all understand each other. &amp;nbsp;Also since Code Camp is free, we're not expecting professional technical speakers (although, I'll admit that I've heard speakers at Code Camp who were better than some of the speakers at the professional conferences).&lt;br /&gt;&lt;br /&gt;I'm going to share some tips that I've learned along the way, including some things that I specifically set out to avoid. &amp;nbsp;There are no rules for speaking. &amp;nbsp;Everyone has a different style. &amp;nbsp;These are a set of tips which have worked for me. &amp;nbsp;They may or may not work for you.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Danger: You May Get Hooked&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I had done a few presentations for fellow developers within my department at work but never thought I would get up to speak in front of complete strangers. &amp;nbsp;But after speaking at my first Code Camp, I was hooked. &amp;nbsp;I signed up to speak at more Code Camps in my area, and let the local user groups know that I was interested in speaking.&lt;br /&gt;&lt;br /&gt;Here's what hooked me: there's nothing quite like helping other people. &amp;nbsp;The speaking part itself is a lot of fun for me, but what is most rewarding is if I get an email a week later from someone who let me know how they were able to use the information that I presented. &amp;nbsp;Being helpful to someone else really drives me forward.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;How Did I Get Started?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I got started as a speaker almost by accident. &amp;nbsp;In my mind, I didn't have anything ground-breaking to talk about. &amp;nbsp;I wasn't dealing with the latest beta products or cutting-edge software. &amp;nbsp;I was just a competent developer working with established technologies. &amp;nbsp;It seems like everyone was interested in whatever was new and shiny, so I didn't think I had anything to say.&lt;br /&gt;&lt;br /&gt;Then I was listening to &lt;a href="http://www.dotnetrocks.com/"&gt;.NET Rocks!&lt;/a&gt; (a really good podcast, by the way). &amp;nbsp;There was a panel discussion and one of the topics that came up was the lack of beginning and intermediate sessions for people who were new to development or just new to .NET. &amp;nbsp;When .NET was first released, there were all sorts of introductory sessions including the basics of the languages, the CLR, garbage collection, and just how to get started creating applications. &amp;nbsp;Then over the years, the introductory sessions faded away to be replaced by whatever the latest technologies were. &amp;nbsp;The panel agreed that there was a need for people to present those introductory topics to keep bringing more people into the world of .NET development.&lt;br /&gt;&lt;br /&gt;I thought, "Hey, I can do that." &amp;nbsp;And I took it as a challenge. &amp;nbsp;About 2 weeks after the podcast, I heard about an upcoming Code Camp and determined that I would put together three sessions for it. &amp;nbsp;(It may have been a lot to bite off my first time around, but I had 8 weeks to prepare).&lt;br /&gt;&lt;br /&gt;Those first sessions went very well. &amp;nbsp;And I attribute that primarily to the preparation.&lt;br /&gt;&lt;br /&gt;So let's take a look at some tips to get started with.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;One Rule&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Earlier I mentioned that there were no rules. &amp;nbsp;But that wasn't quite true. &amp;nbsp;In reality there is one rule: Have fun! &amp;nbsp;If you aren't going to enjoy this, then no one attending will enjoy it either. &amp;nbsp;It's okay if you are nervous. &amp;nbsp;But once you get started, just like any other performance, the nervousness usually fades away. Just go with it and have fun.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Picking a Topic&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;One of the first things you will need to do is pick a topic. &amp;nbsp;Pick a topic that you are passionate about, something you really love. &amp;nbsp;Okay, love is a bit of a strong word, but select something that you have found really useful in your development -- something that you wouldn't want anyone to take away from you.&lt;br /&gt;&lt;br /&gt;Here's a tip from Scott Hanselman: Give the presentation that you want to attend. &amp;nbsp;When you are thinking about a topic, go back to the "I wish someone had told me about this before" moment. &amp;nbsp;It may be a common subject; it may seem basic or simplistic. &amp;nbsp;That's okay. &amp;nbsp;If it is something that you wish you had known about earlier, chances are that there are a lot of other developers who don't know about it yet.&lt;br /&gt;&lt;br /&gt;One other thing about picking a topic: be aware of the scope. &amp;nbsp;You have limited time to present your session. &amp;nbsp;If you pick a topic that is too broad, then you may end up skimming over the top without going into any useful detail. &amp;nbsp;If you pick a topic that is too narrow, you may find that you don't have material to fill up the time slot.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Preparation&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I cannot say enough about being prepared for your presentation. &amp;nbsp;I know what I am going to say before I walk in the room. &amp;nbsp;If I end up giving the same presentation a second or third time, it will generally be almost exactly the same content each time.&lt;br /&gt;&lt;br /&gt;Often at Code Camp, you will see people in the back of the room frantically typing away. &amp;nbsp;These are usually speakers who are finishing up their slides or code samples. &amp;nbsp;This works for some people (people who love the "deadline"). &amp;nbsp;And if you are a veteran speaker, you can often get away with it. &amp;nbsp;It doesn't work for me. &amp;nbsp;Your first time out, you are going to have a lot of things on your mind (How do I use the AV equipment? &amp;nbsp;Is Visual Studio working right? &amp;nbsp;Can I find my slides?) &amp;nbsp;If you have your presentation nailed down, that is one less thing to worry about.&lt;br /&gt;&lt;br /&gt;The first step in preparation is to know your material. &amp;nbsp;By putting together a presentation, I find that I have big gaps in my knowledge about the topic. &amp;nbsp;This is usually because I needed to use a technology for a specific project with specific requirements. &amp;nbsp;But if you want to present the broader topic, you will find that there are parts of the technology that you have not used and need to learn about. &amp;nbsp;This doesn't mean you need to become an expert. &amp;nbsp;But you do need to at least know all of the terminology and have a general idea of how ti all works, even if you can't give the specific details.&lt;br /&gt;&lt;br /&gt;Once you have everything put together (topic, slides, demo code, etc.), then practice, practice, practice. &amp;nbsp;Run through the presentation all the way through multiple times. &amp;nbsp;And not just in your head. &amp;nbsp;Speak out loud (pets are a great audience for your first practice runs). &amp;nbsp;I generally run through a new presentation at least 4 times. &amp;nbsp;This helps me find the places where I stumble or need to clarify my thoughts. &amp;nbsp;Sometimes you get tongue-tied. &amp;nbsp;That's what practice is for. &amp;nbsp;Even if I am doing a repeat of a presentation that I've done before, I'll run through 1 or 2 practices to make sure that I still know what I'm talking about.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Stay on Time&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;One thing that all of the practice will help you with is to stay on time. &amp;nbsp;Is your presentation running long? &amp;nbsp;Figure out what you can cut or speed up. &amp;nbsp;Is your presentation short? &amp;nbsp;That may be okay. &amp;nbsp;It leaves more time for questions or to explore some of the items a little further.&lt;br /&gt;&lt;br /&gt;One of the worst things you can do at Code Camp is run long. &amp;nbsp;Code Camp is usually a very compressed day. &amp;nbsp;People have limited time to get from session to session (and to visit the restroom or grab a soda in between). &amp;nbsp;If you run long, then you will lose the attention of the people in the room anyway, so it's best to make sure that won't happen.&lt;br /&gt;&lt;br /&gt;Things don't always go according to plan. &amp;nbsp;My first time out, I thought that I had my timing down fine. &amp;nbsp;I was confident and took time for a few questions in the middle of the session. &amp;nbsp;But because I had practiced so much, I recognized about halfway through the time that I wasn't halfway through my material. &amp;nbsp;I made some quick mental cuts and decided what I could skip over. &amp;nbsp;I was able to do this on-the-fly without it being too obvious that I had done so.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Slides&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;No one likes slides at Code Camp. &amp;nbsp;We're not executives that want bullet points. &amp;nbsp;We want to see code in action. &amp;nbsp;So feel free to go light on the slides.&lt;br /&gt;&lt;br /&gt;With that said, I would not recommend ditching the slides entirely. &amp;nbsp;If you have slides, then the folks in the room know that you spent at least a little bit of time in preparation. &amp;nbsp;I've gone to a couple completely slide-free presentations, and they seemed to be completely ad-libbed (which could be fine depending on the topic). &amp;nbsp;My personal approach is to have a couple of slides that introduce me and the topic, but then I spend most of my time in the code. &amp;nbsp;This is just my style; other people approach this differently. &amp;nbsp;Again, the goal is to find what works best for you as a speaker.&lt;br /&gt;&lt;br /&gt;Remember the advice to give the presentation you would like to attend. &amp;nbsp;Do you want to see a lot of wordy slides with the presenter simply reading them? &amp;nbsp;Probably not. &amp;nbsp;The slides are there to augment what you have to say, not repeat it or replace it.&lt;br /&gt;&lt;br /&gt;One other thing that I do with my slides is have a reference links slide at the end of the presentation. &amp;nbsp;This would contain links to web sites, blog articles, MSDN articles, or other helpful materials. &amp;nbsp;I post my slides on my website so that people can get to these links without having to scribble them all down during the presentation.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Demo&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Code Campers love demos. &amp;nbsp;We want to see what you are talking about in action. &amp;nbsp;There are a lot of different styles for this part.&lt;br /&gt;&lt;br /&gt;First, there is the advice to never do a live demo. &amp;nbsp;There are too many things to go wrong. &amp;nbsp;And Murphy's Law says that it will probably all go wrong right in the middle of your presentation. &amp;nbsp;Personally, I think that preparation can mitigate a lot of this risk (and I'll talk about a few specific items of preparation that help in just a bit).&lt;br /&gt;&lt;br /&gt;If you have a demo set up that is very complex, such as one that requires multiple computers networked together or needs access to a specific web site, then you might consider doing a screen capture of the demo and then playing it during the presentation. &amp;nbsp;And even if you want to do this live, it doesn't hurt to have the video as a backup in case the network goes down or something else goes wrong.&lt;br /&gt;&lt;br /&gt;But the most effective demos are live demos. &amp;nbsp;How you approach this will depend on your topic and how deeply you want to cover things. &amp;nbsp;You may want to start with a blank project and build an entire application live. &amp;nbsp;This works well in a lot of cases, but be aware that you will be limited in how much you can show.&lt;br /&gt;&lt;br /&gt;You may want to start with several different projects that are in various stages of completion. &amp;nbsp;In this case, you can open the #1 project, add some code and show what it does. &amp;nbsp;Then move on to the #2 project which has more code in place, add some more code and show what that does. &amp;nbsp;This can be a very effective way of presenting a topic.&lt;br /&gt;&lt;br /&gt;Here's what I do -- again, take this as part of my personal style based on how I pick topics; it is what has worked well for me. &amp;nbsp;I generally start with a project that is prepared just enough for me to start putting in the important code. &amp;nbsp;For example, if I am doing an introduction to XAML, I start out with a completely new, blank project and move from there. &amp;nbsp;If I am speaking about lambda expressions, then I have the UI already laid out and start with mostly blank code behind the UI. &amp;nbsp;The idea is that anything that is already in place is not necessary to understand for the topic being discussed; it is part of the background.&lt;br /&gt;&lt;br /&gt;One other thing you can do. &amp;nbsp;If you have large blocks of code to add as part of your demo, don't make people watch you type. &amp;nbsp;This can be especially painful if you are not a good typist. &amp;nbsp;If you have large blocks of code, then create another file within your project that contains the code in comment blocks. &amp;nbsp;Then you can copy/paste the blocks of code into your project during the demo. &amp;nbsp;This saves you a lot of time, and it also helps to avoid typos.&lt;br /&gt;&lt;br /&gt;As part of my preparation, I have 2 copies of each of my projects. &amp;nbsp;The first copy is the "Starter" project. This is the mostly-blank project that I am going to fill in with the code during the presentation. &amp;nbsp;The second copy is the "Completed" project. &amp;nbsp;This is what the project looks like after I have completely run through the demo. &amp;nbsp;This is my safety net. &amp;nbsp;If something goes horribly wrong during the live code demo, I can always open up the completed application and show the pieces already in place. &amp;nbsp;The good news is that I have only had to do this once (knock on wood). &amp;nbsp;I attribute this to preparation; I have practiced the code demo so many times that I know exactly what I need to do. &amp;nbsp;And if something does go wrong, I've probably already seen that same issue during the practice runs.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;The Tools&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Feel free to ignore this tip. &amp;nbsp;This is a personal preference based on sessions that I have attended. &amp;nbsp;The tip: run naked. &amp;nbsp;Okay, don't do that literally (no one needs to see that). &amp;nbsp;What I mean is disable the add-ins in your development environment unless they are critical to what you are trying to demo. &amp;nbsp;When I see someone do a demo, I want to be able to go home and do exactly the same thing. &amp;nbsp;If the speaker is using an add-in that has magic keystrokes, then it makes it harder for me to follow.&lt;br /&gt;&lt;br /&gt;This primarily applies to non-free add-ins. &amp;nbsp;If you have free tools that you find useful, then by all means recommend them. &amp;nbsp;As developers we are always looking for new tools that can make our development faster and more effective.&lt;br /&gt;&lt;br /&gt;One other thing about tools: if you know any shortcuts that are native to the development environment, be sure to share them. &amp;nbsp;Not everyone is aware of what Ctrl+K,D does. &amp;nbsp;Not everyone is aware of what the little purple box means. &amp;nbsp;Not everyone is aware that you can press 2 keys to stub out an interface. &amp;nbsp;If you can fit these tips into your presentation, then go ahead and do it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Organization&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;How you organize things is part of your preparation. &amp;nbsp;You need to know where all of your slides, code samples, demos, and websites are. &amp;nbsp;I have been in a few presentations where the speaker opened the wrong projects and had trouble finding the code he was looking for. &amp;nbsp;Don't let this happen to you. &amp;nbsp;Something that I find useful is to create a folder that has shortcuts to everything I need. &amp;nbsp;You can put this folder on the desktop or even dock it to the taskbar. &amp;nbsp;If you have multiple shortcuts to code projects, then number the shortcuts so that you can open them in the correct order.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;During the Presentation&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;You will probably be jittery as the presentation starts. &amp;nbsp;That's fine. &amp;nbsp;This is normal. &amp;nbsp;A lot of times, this may lead to you speaking too quickly or getting tongue-tied. &amp;nbsp;If this happens, just pause and take a deep breath. &amp;nbsp;Have a bottle of water with you, and take a sip. &amp;nbsp;You don't have to fill every second with talking. &amp;nbsp;Taking a deep breath will give your brain a chance to catch up and organize your thoughts. &amp;nbsp;Then you can continue clearly and confidently.&lt;br /&gt;&lt;br /&gt;Watch your speed. &amp;nbsp;If you have practiced, then you should know where the quarter, half-way, and three-quarter marks are in your presentation. &amp;nbsp;When you hit those spots, how does that compare to the clock? &amp;nbsp;If you are ahead of time, then you may want to slow down, or pause to see if anyone has questions. &amp;nbsp;If you are running late, then you may want to start thinking about what you can skip later on or if you can simply speed up a little bit.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Focus on Individuals&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;When you are speaking, try to look at individuals in the room. &amp;nbsp;It is tempting to talk directly to one person (the one person who is paying most attention). &amp;nbsp;But make sure that you are talking to everyone. &amp;nbsp;Talking to "everyone" does not mean simply throwing your words into the room; you need to talk to the individual people in the room. &amp;nbsp;While speaking, take a few moments to make eye contact with one person, then move on to another person. &amp;nbsp;Remember that you are talking to actual people.&lt;br /&gt;&lt;br /&gt;I forgot this once. &amp;nbsp;I was on my third presentation of the day. &amp;nbsp;The other two presentations had full rooms with lots of energy. &amp;nbsp;The third presentation just had a few people in the room. &amp;nbsp;I tried to continue the energy into that room, but it didn't work. &amp;nbsp;It was awkward, and I bombed the presentation. &amp;nbsp;I got all of the information out there (because of the practice I had), but I never made a connection with anyone in the room. &amp;nbsp;Ultimately, I'm glad that it happened. &amp;nbsp;I learned from what I did wrong, and I've been better able to adjust my presentation style based on the situation.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Taking Questions&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;It's up to you to decide whether you want to take questions during your presentation. &amp;nbsp;If you are going to take questions freely, then plan your presentation so that it would normally end 10 to 15 minutes before the end of the allotted time. &amp;nbsp;If you want to save questions for the end (if there is time), that is fine, too. &amp;nbsp;Just let your attendees know how you would like to handle questions.&lt;br /&gt;&lt;br /&gt;If you take questions, stay on topic. &amp;nbsp;If someone asks a question that will take you off topic, it is okay to put the question off. &amp;nbsp;As developers, we always want to show off how much we know. &amp;nbsp;So if someone asks a question, your first instinct is to answer it. &amp;nbsp;But here's the problem: if the question takes the session off topic, it may be good for the one person in the room (the person who asked the question), but it will be horrible for the rest of the people in the room. &amp;nbsp;After all, they all came to hear you speak about a particular subject. &amp;nbsp;I have often been frustrated (as an attendee) when a session was derailed by someone asking questions that are relevant only to that one person.&lt;br /&gt;&lt;br /&gt;If you take questions, it's okay to defer. &amp;nbsp;It may be that the question is either off topic or that the question is on-topic but would take too long to answer. &amp;nbsp;If this is the case, then let the person know that you would be happy to talk to them about it later, either between sessions or in email.&lt;br /&gt;&lt;br /&gt;If you take questions, it's okay to not know the answer. &amp;nbsp;You don't have to know everything before you become a speaker. &amp;nbsp;I have often had people ask me a question that I did not know the answer to. &amp;nbsp;This is usually because they bring up a scenario that I had never thought through or tried before. &amp;nbsp;In these situations, I generally write down the question and then say that I will post the answer on my blog once I have time to research it. &amp;nbsp;Exactly how you handle the situation is up to you. &amp;nbsp;But it is better to say that you don't know than to make up an answer.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;After the Presentation&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;There are a couple things that you can do after the presentation to wrap things up. &amp;nbsp;First, if you have code samples or slides that you say you will make available for download, then do it. &amp;nbsp;I have been at professional conferences and had the speaker say that the code from the session would be on the website after a week. &amp;nbsp;I checked after a week, and it wasn't there. &amp;nbsp;I checked after two weeks, and it still wasn't there. &amp;nbsp;Because of curiosity, I went back two months later, and it still wasn't there. &amp;nbsp;If you say that you are going to post your code, then post your code. &amp;nbsp;And by the way, if you don't want to post your code, that's okay, too. &amp;nbsp;Just make sure that if you say you will do something, you follow up on it.&lt;br /&gt;&lt;br /&gt;Another "this works for me": I always post my code samples and slides on my website before the presentation starts. &amp;nbsp;This way, I don't have to worry about finding the time to do this later (because I'm very good at forgetting things). &amp;nbsp;It also has the side-effect of forcing me to prepare. &amp;nbsp;I can't post the slides and code samples until after my preparation is complete.&lt;br /&gt;&lt;br /&gt;Finally, follow up on questions. &amp;nbsp;If you say that you will post answers on your blog or follow up with an individual over email, then make sure you do that.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Final Words&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;So, we've talked about a lot of different tips. &amp;nbsp;As I noted, most of these things have worked well for me. &amp;nbsp;Some of them are things that have bothered me from sessions that I have attended. &amp;nbsp;But everyone is different.&lt;br /&gt;&lt;br /&gt;Remember the one rule: Have fun! &amp;nbsp;The fate of the world does not depend on you giving a good presentation. &amp;nbsp;If you mess up, no one's going to die. &amp;nbsp;You learn best when things go wrong.&lt;br /&gt;&lt;br /&gt;And make sure to be yourself. &amp;nbsp;Everyone has a different style of speaking. &amp;nbsp;Everyone has a different style of coding. &amp;nbsp;Don't pretend to be someone else when you are speaking. &amp;nbsp;Just be yourself. &amp;nbsp;If you are prepared, then things are bound to turn out just fine.&lt;br /&gt;&lt;br /&gt;Everyone has something to share with other developers. &amp;nbsp;Take the next step and sign up for the next Code Camp in your area. &amp;nbsp;You might find that you love it, and you'll be speaking more and more. &amp;nbsp;You might find that it's not your thing. &amp;nbsp;That's okay, too. &amp;nbsp;But you never know until you try.&lt;br /&gt;&lt;br /&gt;Happy speaking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-1171670041549701934?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/1171670041549701934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/08/meet-next-code-camp-speaker-you.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1171670041549701934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1171670041549701934'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/08/meet-next-code-camp-speaker-you.html' title='Meet the Next Code Camp Speaker: You!'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2746747032956375174</id><published>2011-05-10T13:09:00.000-07:00</published><updated>2011-05-10T13:09:51.457-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><title type='text'>Upcoming Speaking Engagements</title><content type='html'>I have a couple of speaking engagements scheduled later this month. &amp;nbsp;Come on out if you can.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;May 19, 2011&lt;/b&gt;&lt;br /&gt;Southern California .NET Architecture Users Group&lt;br /&gt;Santa Ana, CA&lt;br /&gt;&lt;a href="http://www.socaldotnetarchitecture.org/"&gt;http://www.socaldotnetarchitecture.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;May 24, 2011&lt;/b&gt;&lt;br /&gt;BiTKOO Webinar&lt;br /&gt;BiTKOO, a leader in authorization management software (and the company I work for), is hosting a free webinar on Tuesday, May 24 at 1:00 PDT. &amp;nbsp;The topic is "Leveling Up: Authorization in Your Application". &amp;nbsp;You can get more information on the topic and sign up here:&amp;nbsp;&lt;a href="https://www3.gotomeeting.com/register/975758094"&gt;https://www3.gotomeeting.com/register/975758094&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And next month...&lt;br /&gt;&lt;b&gt;June 25 &amp;amp; 26, 2011&lt;/b&gt;&lt;br /&gt;So Cal Code Camp - San Diego, CA&lt;br /&gt;It's code camp time once again. &amp;nbsp;Code camp is a great place to meet and talk to your fellow developers, find out what tools people are using, and what's working and what's not. &amp;nbsp;Plus, you get 2 solid days of FREE sessions -- over 100 to choose from. &amp;nbsp;If you can make it, be sure to hunt me down to say, "Hi".&lt;br /&gt;&lt;a href="http://www.socalcodecamp.com/"&gt;http://www.socalcodecamp.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2746747032956375174?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2746747032956375174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/05/upcoming-speaking-engagements.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2746747032956375174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2746747032956375174'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/05/upcoming-speaking-engagements.html' title='Upcoming Speaking Engagements'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7791299894020346839</id><published>2011-04-04T19:40:00.000-07:00</published><updated>2011-04-04T19:40:02.637-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>1,000 Attendees!</title><content type='html'>A big thank you to those of you who came to my sessions at the Desert Code Camp this weekend.&amp;nbsp; I had a great time, and it was good to see some of you back in my sessions again.&amp;nbsp; You helped me pass the 1,000 mark -- over 1,000 people have come to my sessions since I started speaking publicly in January 2010 (although I know it is fewer than 1,000 unique people since some of you have come to more than one of my sessions).&lt;br /&gt;&lt;br /&gt;Here's a breakdown of my speaking engagements:&lt;br /&gt;&lt;br /&gt;Jan 2010 - &lt;b&gt;So Cal Code Camp - Fullerton, CA&lt;/b&gt;&lt;br /&gt;135 attendees (3 sessions)&lt;br /&gt;&lt;br /&gt;Feb 2010 - &lt;b&gt;Disney .NET Developers Group - Burbank, CA&lt;/b&gt;&lt;br /&gt;30 attendees&lt;br /&gt;&lt;br /&gt;Jun 2010 - &lt;b&gt;So Cal Code Camp - San Diego, CA&lt;/b&gt;&lt;br /&gt;59 attendees (3 sessions)&lt;br /&gt;&lt;br /&gt;Jul 2010 - &lt;b&gt;LA C# User Group - Manhattan Beach, CA&lt;/b&gt;&lt;br /&gt;20 attendees&lt;br /&gt;&lt;br /&gt;Jul 2010 - &lt;b&gt;So Cal .NET Developers Group - Buena Park, CA&lt;/b&gt;&lt;br /&gt;25 attendees&lt;br /&gt;&lt;br /&gt;Oct 2010 - &lt;b&gt;ASP.NET SIG - San Diego, CA&lt;/b&gt;&lt;br /&gt;30 attendees&lt;br /&gt;&lt;br /&gt;Oct 2010 - &lt;b&gt;So Cal Code Camp - Los Angeles, CA&lt;/b&gt;&lt;br /&gt;339 attendees (8 sessions)&lt;br /&gt;&lt;br /&gt;Nov 2010 - &lt;b&gt;Desert Code Camp - Chandler, AZ&lt;/b&gt;&lt;br /&gt;77 attendees (3 sessions)&lt;br /&gt;&lt;br /&gt;Jan 2011 - &lt;b&gt;Inland Empire .NET User's Group - San Bernardino, CA&lt;/b&gt;&lt;br /&gt;20 attendees&lt;br /&gt;&lt;br /&gt;Jan 2011 - &lt;b&gt;Disney .NET Developers Group - Burbank, CA&lt;/b&gt;&lt;br /&gt;30 attendees&lt;br /&gt;&lt;br /&gt;Jan 2011 - &lt;b&gt;So Cal Code Camp - Fullerton, CA&lt;/b&gt;&lt;br /&gt;145 attendees (3 sessions)&lt;br /&gt;&lt;br /&gt;Feb 2011 - &lt;b&gt;Disney .NET Developers Group - Burbank, CA&lt;/b&gt;&lt;br /&gt;38 attendees&lt;br /&gt;&lt;br /&gt;Feb 2011 - &lt;b&gt;San Gabriel Valley .NET Developers Group - Monrovia, CA&lt;/b&gt;&lt;br /&gt;20 attendees&lt;br /&gt;&lt;br /&gt;Apr 2011 - &lt;b&gt;Desert Code Camp, Chandler AZ&lt;/b&gt;&lt;br /&gt;63 attendees (3 sessions)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Grand Total: 1,036!&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I've had a great time speaking.&amp;nbsp; Hopefully you've had a great time listening.&amp;nbsp; If you'd like to have me come to your user group or other event, just drop me a note.&amp;nbsp; As a reminder, if you've come to one of my sessions, you can download the session materials from my website: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7791299894020346839?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7791299894020346839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/04/1000-attendees.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7791299894020346839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7791299894020346839'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/04/1000-attendees.html' title='1,000 Attendees!'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-1235288533105990888</id><published>2011-03-20T21:07:00.000-07:00</published><updated>2011-03-20T21:07:47.345-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><title type='text'>Desert Code Camp - April 2nd</title><content type='html'>Desert Code Camp in Chandler, Arizona is coming up quickly (Saturday, April 2, 2011).&amp;nbsp; If you are in the Phoenix area -- or simply need an excuse to go for a road trip -- it's a great way to spend the day.&amp;nbsp; I was able to attend last October, and I'm looking forward to going back again.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Talk to your fellow developers, get some free training, and make some great contacts.&amp;nbsp; There are over 100 sessions on the schedule including a track just for kids.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://apr2011.desertcodecamp.com/"&gt;Desert Code Camp 2011.1&lt;/a&gt;&lt;br /&gt;April 2, 2011&lt;br /&gt;Chandler, AZ&lt;br /&gt;&lt;br /&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-1235288533105990888?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/1235288533105990888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/03/desert-code-camp-april-2nd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1235288533105990888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1235288533105990888'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/03/desert-code-camp-april-2nd.html' title='Desert Code Camp - April 2nd'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-8875669988501317617</id><published>2011-02-24T17:43:00.000-08:00</published><updated>2011-02-24T17:43:18.068-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><title type='text'>Additional Links for Design Patterns</title><content type='html'>I've had some folks who have attended my Design Patterns session suggest some links that they have found useful. &amp;nbsp;(And if you want to check out the session materials, just go to my website: &lt;a href="http://www.jeremybytes.com/Demos.aspx#LLDP"&gt;Learn the Lingo: Design Patterns&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Head First Labs - Head First Design Patterns&lt;/span&gt;&lt;br /&gt;&lt;a href="http://headfirstlabs.com/books/hfdp/"&gt;http://headfirstlabs.com/books/hfdp/&lt;/a&gt;&lt;br /&gt;This is the link for the "Head First Design Patterns" book that I've recommended. &amp;nbsp;And there's some really good news. &amp;nbsp;I noted that the book is written with Java samples, but that it's not too hard for a C# developer to follow along. &amp;nbsp;The good news is that the labs includes a link to a collection of C# samples. &amp;nbsp;Just search for "C#" on the labs page, and you should find it.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Head First Design Patterns Study Group&lt;/span&gt;&lt;br /&gt;&lt;a href="http://onjava.com/pub/a/onjava/2005/04/06/designpatterns.html"&gt;http://onjava.com/pub/a/onjava/2005/04/06/designpatterns.html &lt;/a&gt;&lt;br /&gt;The O'Reilly On Java website has suggestions on forming your own study group based on Head First Design Patterns. &amp;nbsp;I've heard from some folks who have done this, and they found that it was a good learning experience for everyone involved. &amp;nbsp;Discussion with other developers usually leads to new insights for everyone.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Do Factory - Design Pattern Framework 4&lt;/span&gt;&lt;br /&gt;&lt;a href="http://dofactory.com/Default.aspx"&gt;http://dofactory.com/Default.aspx&lt;/a&gt;&lt;br /&gt;This site sells a product called Design Pattern Framework 4. &amp;nbsp;As a disclaimer, I have not actually used this product, nor do I really know much about this. &amp;nbsp;But I have received recommendations from session attendees, so it may be something worth looking into further. &amp;nbsp;In going through the information, there is also an endorsement from Miguel Castro (who is one of the big players in the .NET community), so that leads me into wanting to look at this a little more closely.&lt;br /&gt;&lt;br /&gt;If you've had experiences with either the Head First Design Patterns study group or using the Design Pattern Framework 4, please drop me a line and let me know what you think.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-8875669988501317617?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/8875669988501317617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/02/additional-links-for-design-patterns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8875669988501317617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8875669988501317617'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/02/additional-links-for-design-patterns.html' title='Additional Links for Design Patterns'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-5585259073730516798</id><published>2011-02-06T17:27:00.000-08:00</published><updated>2011-02-06T17:30:07.488-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><title type='text'>Upcoming Speaking Engagements</title><content type='html'>I have a couple of speaking engagements scheduled in February.&amp;nbsp; Feel free to come out if you can.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Feburary 15, 2011&lt;/strong&gt;&lt;br /&gt;Disney .NET Developers Group - Burbank, CA&lt;br /&gt;Web cast available.&amp;nbsp; Disney employees and Cast Members can check TechSpot for details.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;February 16, 2011&lt;/strong&gt;&lt;br /&gt;San Gabriel Valley .NET Developers Group - Monrovia, CA&lt;br /&gt;&lt;a href="http://sgvdotnet.org/"&gt;http://sgvdotnet.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also, it looks like I'll be heading back to the Desert Code Camp on April 2, 2011 in Chandler, AZ.&amp;nbsp; More information here: &lt;a href="http://apr2011.desertcodecamp.com/"&gt;http://apr2011.desertcodecamp.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope to see you there!&amp;nbsp; And if you have a user group or other event you'd like me to come speak at, just drop me a line and let me know: &lt;a href="mailto:feedback@jeremybytes.com"&gt;feedback@jeremybytes.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-5585259073730516798?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/5585259073730516798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/02/upcoming-speaking-engagements.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5585259073730516798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5585259073730516798'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/02/upcoming-speaking-engagements.html' title='Upcoming Speaking Engagements'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-8158377341834307450</id><published>2011-02-01T19:09:00.000-08:00</published><updated>2011-02-01T19:09:53.678-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><title type='text'>Thank You for Coming!</title><content type='html'>I want to thank everyone who attended one of my sessions at the SoCal Code Camp this past weekend (and even those of you who were brave enough to attend more than one of my sessions). &amp;nbsp;As a reminder, the Walkthroughs, Slides, and Code Samples are all available for download:&amp;nbsp;&lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you have any questions, suggestions, or even session topics you'd like to see me present in the future, feel free to drop me a line at&amp;nbsp;&lt;a href="mailto:feedback@jeremybytes.com"&gt;feedback@jeremybytes.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Until next time...&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-8158377341834307450?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/8158377341834307450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/02/thank-you-for-coming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8158377341834307450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8158377341834307450'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/02/thank-you-for-coming.html' title='Thank You for Coming!'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-4314342254365089514</id><published>2011-01-18T20:50:00.000-08:00</published><updated>2011-01-18T20:50:05.423-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Book Review'/><title type='text'>Mini Review: Code - The Hidden Language of Computer Hardware and Software</title><content type='html'>I recently finished reading &lt;em&gt;Code: the Hidden Language of Computer Hardware and Software&lt;/em&gt; by Charles Petzold.&amp;nbsp; Here are a few quick thoughts:&lt;br /&gt;&lt;br /&gt;This is not really a programming book; it is a description of how computers work. Designed for the layman, it starts off with the basics of codes (Morse Code, Braille, binary codes) and then moves on to how to communicate those codes using electro-mechanical relays (such as telegraph relays). From there, it talks about how these relays can be combined in various ways to create logical operations and built up to a simple adder -- the basic building block of computer hardware. The components are pieced together from the earliest computers to modern machines (well, almost modern -- the book was written in 1999). As a non-CS major, I found this book to be very approachable and it gave me a good understanding of how software can be turned into instructions for the hardware.&lt;br /&gt;&lt;br /&gt;Overall, this was&amp;nbsp;an interesting&amp;nbsp;read.&amp;nbsp; For me, it went quite quickly (just a few weeks in small chunks), and I have a better feel for how computer hardware works at its most basic level.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-4314342254365089514?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/4314342254365089514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/mini-review-code-hidden-language-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/4314342254365089514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/4314342254365089514'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/mini-review-code-hidden-language-of.html' title='Mini Review: Code - The Hidden Language of Computer Hardware and Software'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-8032735239560721048</id><published>2011-01-09T14:37:00.000-08:00</published><updated>2011-01-09T14:37:45.136-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Lambda Expression'/><title type='text'>Update: Learn to Love Lambdas</title><content type='html'>Lambda Expressions have turned out to be a popular topic (I've got three presentations scheduled&amp;nbsp;for January alone).&amp;nbsp; With that in mind, I have expanded the &lt;em&gt;Learn to Love Lambdas&lt;/em&gt; walkthrough and demo code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Get It Here&lt;/span&gt;&lt;br /&gt;You can get the complete walkthrough (18 pages) and code samples here:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Demos.aspx#LLL"&gt;http://www.jeremybytes.com/Demos.aspx#LLL&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Direct Links:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/LearnToLoveLambdas.pdf"&gt;PDF Walkthrough&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/LearnToLoveLambdas2010.zip"&gt;Code Download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-8032735239560721048?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/8032735239560721048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/update-learn-to-love-lambdas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8032735239560721048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8032735239560721048'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/update-learn-to-love-lambdas.html' title='Update: Learn to Love Lambdas'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-4340683026639548016</id><published>2011-01-08T14:27:00.000-08:00</published><updated>2011-01-08T14:27:08.908-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Lambda Expression'/><title type='text'>Quick Bytes: Get Func-y</title><content type='html'>If you look into the LINQ extension methods, you will run across Func quite a bit.&amp;nbsp; If you see Func in a method definition, you can treat it like a big sign that says "Put your lambda expression here."&amp;nbsp; This quick demo will show that Func is simply a shorthand for creating a delegate and that Func and lambdas go together hand-in-hand.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Get It Here&lt;/span&gt;&lt;br /&gt;You can get the walkthrough (just 5 pages) and the code sample here: &lt;a href="http://www.jeremybytes.com/demos.aspx#QBGF"&gt;http://www.jeremybytes.com/demos.aspx#QBGF&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Direct Links:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/downloads/GetFuncY.pdf"&gt;PDF Walkthrough&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/downloads/GetFuncY.zip"&gt;Code Download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-4340683026639548016?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/4340683026639548016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/quick-bytes-get-func-y.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/4340683026639548016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/4340683026639548016'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/quick-bytes-get-func-y.html' title='Quick Bytes: Get Func-y'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-1899517556837996452</id><published>2011-01-03T20:22:00.000-08:00</published><updated>2011-01-03T20:22:49.072-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Book Review'/><title type='text'>Book Review: Pro ASP.NET MVC 2 Framework</title><content type='html'>I just finished reading &lt;em&gt;Pro ASP.NET MVC 2 Framework&lt;/em&gt; by Steven Sanderson (Apress).&amp;nbsp; What I found was a good introduction to ASP.NET MVC as well as a deeper dive into the majority of the features.&lt;br /&gt;&lt;br /&gt;This is labeled as "Intermediate to Advanced".&amp;nbsp; It assumes that you are familiar with C# and .NET, but it doesn't expect you to be an ASP.NET WebForms programmer.&amp;nbsp; If you are familiar with web technologies (HTML, CSS, Javascript), then you should be just fine.&amp;nbsp; And although this is covering the 2nd version of the ASP.NET MVC framework, it does not assume that you have any prior knowledge of version 1.&lt;br /&gt;&lt;br /&gt;There are several things I liked about this book.&amp;nbsp; First, it is very approachable.&amp;nbsp; The tone is inviting and easy to understand.&amp;nbsp; Next, the code samples are thorough.&amp;nbsp; Since ASP.NET MVC 2 can be used with either .NET 3.5 or .NET 4.0, it shows how to use the framework in either environment, and the differences are pointed out where the environments vary.&amp;nbsp; Finally, the overall organization makes you want to read more.&lt;br /&gt;&lt;br /&gt;Part 1 includes an introduction to ASP.NET MVC 2 and a sample application showing a real-world (although simplified)&amp;nbsp;implementation of the framework.&amp;nbsp; Since the MVC pattern lends itself to unit testing and test-driven development (TDD),&amp;nbsp;the book also shows&amp;nbsp;a few useful techniques including using dependency injection and mocking&amp;nbsp;with unit testing.&amp;nbsp; And to keep things more accessible, Sanderson uses free tools (such as NTest) for the examples since not all versions of Visual Studio include unit testing.&lt;br /&gt;&lt;br /&gt;Part 2 takes all of the features that were introduced in Part 1 and goes into them in detail.&amp;nbsp; This includes all of the core features of ASP.NET MVC including Routing, Controllers, Actions, Views, and Models.&amp;nbsp; But going beyond just a description of using what's "in the box", the book also talks about how you can extend the framework yourself, such as by creating custom controller classes, filters, or even your own view engine.&amp;nbsp; In addition, it gives a number of helpful techniques for putting together user interfaces including a trip into the world of&amp;nbsp;AJAX and jQuery.&lt;br /&gt;&lt;br /&gt;Part 3 covers some of the nitty-gritty details including Security and Deployment.&amp;nbsp; This is where the world of ASP.NET MVC and WebForms starts to overlap.&amp;nbsp; And this last part also goes through many of the features of the standard ASP.NET platform that you will want to make use of in your MVC applications.&lt;br /&gt;&lt;br /&gt;Unlike my previous review of an ASP.NET MVC book, I highly recommend this book.&amp;nbsp; The quality of the book is very high.&amp;nbsp; There are few errors (no book is perfect) and the code samples are well done and complete.&amp;nbsp; I have become a big fan of ASP.NET MVC.&amp;nbsp; Although it is not the "best" or "only" way to write web applications, it is a great tool to have in the toolbox.&amp;nbsp; I can think of a number of applications from my past that would have been much more elegant using ASP.NET MVC.&lt;br /&gt;&lt;br /&gt;If you are curious and want to get started in the technology, &lt;em&gt;Pro ASP.NET MVC2 Framework&lt;/em&gt; is&amp;nbsp;a great way to go.&amp;nbsp; Part 1 will give you a taste of the feature; Part 2 will take you through each one in depth; and Part 3 will show how MVC integrates with the rest of the&amp;nbsp;ASP.NET framework.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-1899517556837996452?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/1899517556837996452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/book-review-pro-aspnet-mvc-2-framework.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1899517556837996452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1899517556837996452'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/book-review-pro-aspnet-mvc-2-framework.html' title='Book Review: Pro ASP.NET MVC 2 Framework'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-5909688084452865561</id><published>2011-01-03T10:34:00.000-08:00</published><updated>2011-01-03T19:25:45.037-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><title type='text'>Upcoming Speaking Engagements</title><content type='html'>&lt;span class="Apple-style-span" style="color: #333333; line-height: 16px;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I have several speaking engagements coming up in January.&amp;nbsp; If you've always wanted to meet me in person, come on out.&amp;nbsp; I'd love to meet you.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&lt;b&gt;January 11, 2011&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;Inland Empire .NET User's Group - San Bernardino, CA&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 16px;"&gt;&lt;a href="http://iedotnetug.org/"&gt;http://iedotnetug.org/&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;b&gt;January 18, 2011&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;Disney .NET Developers Group - Burbank, CA&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;Web cast available. &amp;nbsp;Disney employees and Cast Members can check TechSpot for details.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;b&gt;January 29 - 30, 2011&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;So Cal Code Camp - Fullerton, CA&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif;"&gt;&lt;a href="http://www.socalcodecamp.com/"&gt;http://www.socalcodecamp.com/&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; line-height: 16px;"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Hope to see you there!&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-5909688084452865561?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/5909688084452865561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/upcoming-speaking-engagements.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5909688084452865561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5909688084452865561'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2011/01/upcoming-speaking-engagements.html' title='Upcoming Speaking Engagements'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7377134917244743923</id><published>2010-12-31T20:37:00.000-08:00</published><updated>2011-01-03T19:09:27.381-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Happy New Year!</title><content type='html'>I know it's been a while since I've posted anything new.&amp;nbsp; I decided to take the month of December a little easy.&amp;nbsp; Coming up soon I'll have some information on speaking engagements in January and also a review of &lt;em&gt;Pro ASP.NET MVC2&lt;/em&gt; by Steven Sanderson (preview: it's an excellent book).&lt;br /&gt;&lt;br /&gt;I wish you a Happy New Year!&amp;nbsp; And as always, Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7377134917244743923?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7377134917244743923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/12/happy-new-year.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7377134917244743923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7377134917244743923'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/12/happy-new-year.html' title='Happy New Year!'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-1593090450713414337</id><published>2010-11-20T22:12:00.000-08:00</published><updated>2011-09-08T08:18:31.269-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Lambda Expression'/><title type='text'>Learn to Love Lambdas Session Questions</title><content type='html'>Here are a couple of questions that came up during the Learn to Love Lambdas sessions at recent Code Camps.&amp;nbsp; If you would like to review the session, you can check out the walkthrough and code samples here: &lt;a href="http://www.jeremybytes.com/Demos.aspx#LLL"&gt;Learn to Love Lambdas&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Extension Methods&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Question&lt;/strong&gt;: Could the AddSort() and AddFilter() methods be rewritten as extension methods?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Answer&lt;/strong&gt;: This question came up during two presentations, so there are at least&amp;nbsp;two people who are&amp;nbsp;curious about this.&amp;nbsp; The answer in this case is no.&amp;nbsp; Let's look at the signuatures of the methods as we created them:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/TOixNjb9zhI/AAAAAAAAATU/vZjlnSQrGWQ/s1600/AddSort.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="22" ox="true" src="http://1.bp.blogspot.com/_tXOq_FsazuI/TOixNjb9zhI/AAAAAAAAATU/vZjlnSQrGWQ/s640/AddSort.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/TOixLxFTNyI/AAAAAAAAATQ/teWzQcRCsDc/s1600/AddFilters.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="24" ox="true" src="http://1.bp.blogspot.com/_tXOq_FsazuI/TOixLxFTNyI/AAAAAAAAATQ/teWzQcRCsDc/s640/AddFilters.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If we wanted to convert these to extension methods, we would need to make these methods "public" (instead of private) and "static" (instead of instance methods).&amp;nbsp; For a quick review of how to create and use extension methods, you can check here: &lt;a href="http://www.jeremybytes.com/Demos.aspx#QBEM"&gt;Quick Byte: Extension Methods&lt;/a&gt;.&amp;nbsp; The problem is that we cannot make these methods static since they reference specific UI elements on the form.&amp;nbsp; We could do some refactoring and pass in values (for example, the check box true/false values) as parameters.&amp;nbsp; That would allow us to make these methods static; however, this may not be a good idea.&lt;br /&gt;&lt;br /&gt;First, I like to reserve extension methods for generic methods that I am planning on re-using.&amp;nbsp; In this case, we have a very specific&amp;nbsp;use case&amp;nbsp;that we are&amp;nbsp;implementing based on UI elements.&amp;nbsp; Second, in making these methods public and static, it exposes them to broader usage than simply as private members of the class.&amp;nbsp; Because these methods are so specific, this may just end up resulting in errors if they are used elsewhere.&amp;nbsp; So, even though it is technically possible to convert these to extension methods, I would not recommend it in this case.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Captured Variables&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Question&lt;/strong&gt;: You metioned that if the callback method grew any larger, you would be tempted to refactor it out into a separate method.&amp;nbsp; How would this affect the captured variable?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Answer&lt;/strong&gt;: Even if we refactored the method, we would not eliminate the lambda expression itself; we would simply move the body of the lamba to another method.&amp;nbsp; In this case, we could add the captured variable as a parameter, and it would remain available to the separate method.&lt;br /&gt;&lt;br /&gt;Here's the refactored code: &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/TOixTebkNpI/AAAAAAAAATY/dzHZoSMhyes/s1600/CapturesVariables.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="326" ox="true" src="http://2.bp.blogspot.com/_tXOq_FsazuI/TOixTebkNpI/AAAAAAAAATY/dzHZoSMhyes/s640/CapturesVariables.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here, you can see that we take the "selPerson" variable (the variable that is captured by the lambda expression) and pass it as a parameter to the "UpdateUI" method.&amp;nbsp; Since the "UpdateUI" method is called within the body of the lambda expression,&amp;nbsp;we still has access to the captured variable which&amp;nbsp;we can pass through to the method.&amp;nbsp; This maintains the same functionality that we have before and allows us to keep the "selPerson" variable as a method-level variable.&lt;br /&gt;&lt;br /&gt;Thank you for the great&amp;nbsp;questions.&amp;nbsp; Feel free to drop me a note if you have any more.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-1593090450713414337?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/1593090450713414337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/11/learn-to-love-lambdas-session-questions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1593090450713414337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1593090450713414337'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/11/learn-to-love-lambdas-session-questions.html' title='Learn to Love Lambdas Session Questions'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_tXOq_FsazuI/TOixNjb9zhI/AAAAAAAAATU/vZjlnSQrGWQ/s72-c/AddSort.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-4574600005580920549</id><published>2010-11-15T21:28:00.000-08:00</published><updated>2010-11-16T07:47:48.195-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='BackgroundWorker'/><title type='text'>BackgroundWorker Session Questions</title><content type='html'>I want to thank everyone who attended my sessions at the So Cal Code Camp in Los Angeles, CA and at the Desert Code Camp in Chandler, AZ.&amp;nbsp; As I mentioned, I take the questions that come up in my sessions and look into them further.&amp;nbsp; Here's the good news: I have some answers for questions that came up regarding the BackgroundWorker Component.&amp;nbsp; (If you want to take a look at the session walkthrough and code download, you can get them here: &lt;a href="http://www.jeremybytes.com/Demos.aspx#KYUIR"&gt;Keep Your UI Responsive with the BackgroundWorker Component&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;Passing Additional Data During Progress Updates&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Question #1&lt;/strong&gt;: What is the "UserState" property that shows up in the ProgressChangedEventArgs?&lt;br /&gt;&lt;strong&gt;Question #2&lt;/strong&gt;: Is there a way to pass data from the background thread to the UI thread?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Answer&lt;/strong&gt;: As you might guess since I grouped these questions together, the UserState property can be used to pass additional information from the background thread to the UI thread during the ProgressChanged event.&lt;br /&gt;&lt;br /&gt;As a reminder, we call the ReportProgress method in the background thread which then fires the ProgressChanged event on the UI thread.&amp;nbsp; In the sample code, we used the ReportProgress method that takes a single integer paramter (the percentProgress).&amp;nbsp; But there is an overload that takes both a percentProgress and an additional object parameter called userState.&amp;nbsp; As you might imagine, this will populate the UserState property of our ProgressChangedEventArgs.&amp;nbsp; Let's take a look at updating our application.&lt;br /&gt;&lt;br /&gt;First, on the background thread, we will add an additional "update message" where we calculate the progress and call ReportProgress:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/TOIRQ6JqmeI/AAAAAAAAATE/lQ2AkyJKpnc/s1600/ReportProgress.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="166" px="true" src="http://3.bp.blogspot.com/_tXOq_FsazuI/TOIRQ6JqmeI/AAAAAAAAATE/lQ2AkyJKpnc/s640/ReportProgress.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This "update message" will contain a string such as "Iteration 45 of 150".&lt;br /&gt;&lt;br /&gt;Next, we'll use the new UserState to update the text in our output box:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/TOIRuiQoNvI/AAAAAAAAATI/wTZr-bjkON8/s1600/ProgressChanged.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="124" px="true" src="http://2.bp.blogspot.com/_tXOq_FsazuI/TOIRuiQoNvI/AAAAAAAAATI/wTZr-bjkON8/s640/ProgressChanged.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;And here's the output from the running application:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/TOIR5pb2xSI/AAAAAAAAATM/pI0oOAqEf60/s1600/Output.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" px="true" src="http://4.bp.blogspot.com/_tXOq_FsazuI/TOIR5pb2xSI/AAAAAAAAATM/pI0oOAqEf60/s1600/Output.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;As you can see we have now passed some relevant information from our background thread to our UI thread.&amp;nbsp; It is easy to imagine several uses for this type of behavior.&amp;nbsp; For example, if we were downloading multiple files, we could show the name of the current file in the UI.&amp;nbsp; In addition, since the parameter and UserState are of type "object", we can put anything we want in there, including complex types or collections of complex types.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;BackgroundWorker and MVVM&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Question&lt;/strong&gt;: The BackgroundWorker component can be used with WPF and Silverlight.&amp;nbsp; Does this mean that it can be used with MVVM (Model-View-ViewModel)?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Answer&lt;/strong&gt;: I've thought about this one quite a bit.&amp;nbsp; The question isn't just can the BackgroundWorker be used with MVVM, but whether it makes sense to do so.&amp;nbsp; I've decided that the answer is yes, it does fit in with MVVM.&lt;br /&gt;&lt;br /&gt;In the MVVM patthern, the UI elements on the screen (the View) are data-bound to properties and methods in the ViewModel.&amp;nbsp; The ViewModel&amp;nbsp;is responsible for making&amp;nbsp;data from the Model available to the View.&amp;nbsp; In this situation, we would place the BackgroundWorker in the ViewModel.&amp;nbsp; If we were to convert our sample application to MVVM, we could imagine a property for the percent complete that would be bound to the progress bar, and a property for the output that would be bound to the output text box.&lt;br /&gt;&lt;br /&gt;The BackgroundWorker would live in the ViewModel and kick off the long running process in the background.&amp;nbsp; When the ProgressChanged event fired (in the ViewModel), it would update the percent complete property (which would in turn update the View due to the data binding).&amp;nbsp; The same would be true of the output property.&amp;nbsp; This would prevent the ViewModel (and the View)&amp;nbsp;from "hanging" while waiting for the long-running process to complete.&lt;br /&gt;&lt;br /&gt;MVVM is a much larger topic, and there are a variety of different ways to implement it.&amp;nbsp; But it seems like the BackgroundWorker component may be a useful addition when we are making sure our UI stays responsive.&lt;br /&gt;&lt;br /&gt;Again, thank you for the great questions.&amp;nbsp; I hope that I'll see you at one of my sessions in the future.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-4574600005580920549?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/4574600005580920549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/11/backgroundworker-session-questions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/4574600005580920549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/4574600005580920549'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/11/backgroundworker-session-questions.html' title='BackgroundWorker Session Questions'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_tXOq_FsazuI/TOIRQ6JqmeI/AAAAAAAAATE/lQ2AkyJKpnc/s72-c/ReportProgress.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2187101340023734268</id><published>2010-10-30T19:06:00.000-07:00</published><updated>2010-11-16T10:09:20.539-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Book Review'/><title type='text'>Book Review: C# 4.0 in a Nutshell</title><content type='html'>A&amp;nbsp;few weeks ago, I finished reading &lt;i&gt;C# 4.0 in a Nutshell: The Definitive Reference&lt;/i&gt; by Joseph Albahari &amp;amp; Ben Albahari.&amp;nbsp; I'll start off by saying this is an extremely large "nutshell" (the index starts on page 997), and I spent several months reading it in small pieces.&amp;nbsp; The good news is that it was extremely worthwhile.&lt;br /&gt;&lt;br /&gt;I had not read a book dedicated to C# since .NET 1.0 came out.&amp;nbsp; And that was simply to get to know the language.&amp;nbsp; Through the years, I've read numerous .NET books, but mostly focused on a particular technology, not on the C# language itself.&amp;nbsp; So, this was a good chance for me to read up on the language from beginning to end.&amp;nbsp; This helped refresh things that I had learned long ago and forgotten, as well as fill me in on the pieces that I missed over the years, and finally including all of the new features that we got with C# 4.0 including dynamic types, code contracts, and the parallel library.&lt;br /&gt;&lt;br /&gt;In the preface, the book itself describes what it is not.&amp;nbsp; It is not a replacement for IntelliSense or on-line help; meaning, it does not have a complete listing of all members of each class.&amp;nbsp; Instead, it gives a good overview of select classes and the primary members that you need to know to utilize those classes.&amp;nbsp; Also, it is not a beginner book or a replacement for tutorials that introduce a new programmer to specific topics.&lt;br /&gt;&lt;br /&gt;With that said, I found the book extremely useful.&amp;nbsp; The chapters are well laid-out, and I have found it easy to go back and use this as a reference book for particular topics when needed.&amp;nbsp; Here's a list of the chapters:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Introducing C# and the .NET Framework&lt;/li&gt;&lt;li&gt;C# Language Basics&lt;/li&gt;&lt;li&gt;Creating Types in C#&lt;/li&gt;&lt;li&gt;Advanced C#&lt;/li&gt;&lt;li&gt;Framework Overview&lt;/li&gt;&lt;li&gt;Framework Fundamentals&lt;/li&gt;&lt;li&gt;Collections&lt;/li&gt;&lt;li&gt;LINQ Queries&lt;/li&gt;&lt;li&gt;LINQ Operators&lt;/li&gt;&lt;li&gt;LINQ to XML&lt;/li&gt;&lt;li&gt;Other XML Technologies&lt;/li&gt;&lt;li&gt;Disposal and Garbage Collection&lt;/li&gt;&lt;li&gt;Diagnostics and Code Contracts&lt;/li&gt;&lt;li&gt;Streams and I/O&lt;/li&gt;&lt;li&gt;Networking&lt;/li&gt;&lt;li&gt;Serialization&lt;/li&gt;&lt;li&gt;Assemblies&lt;/li&gt;&lt;li&gt;Reflection and Metadata&lt;/li&gt;&lt;li&gt;Dynamic Programming&lt;/li&gt;&lt;li&gt;Security&lt;/li&gt;&lt;li&gt;Threading&lt;/li&gt;&lt;li&gt;Parallel Programming&lt;/li&gt;&lt;li&gt;Asynchronous Methods&lt;/li&gt;&lt;li&gt;Application Domains&lt;/li&gt;&lt;li&gt;Native and COM Interoperability&lt;/li&gt;&lt;li&gt;Regular Expressions&lt;/li&gt;&lt;/ol&gt;As you can see, there are quite a few chapters that cover pretty much every part of the C# language (as well as parts of the .NET framework itself).&amp;nbsp; I really can't go into details on each of the topics.&lt;br /&gt;&lt;br /&gt;One thing that is nice about this book that makes it a complete reference is that it covers parts of the language even if they are no longer the recommended techniques.&amp;nbsp; For example, there is a complete chapter on LINQ to XML.&amp;nbsp; For those of you who have not yet tried LINQ to XML, take a look at it.&amp;nbsp; After trying it, you will never go back to the "old" way of parsing and creating XML documents.&amp;nbsp; With that said, the book also has a chapter on "other" XML technologies.&amp;nbsp; This is important because even if you are not creating new code using these technologies, you may experience existing code that uses them.&lt;br /&gt;&lt;br /&gt;There are a number of advanced topics, which further complements the "not a beginner book" statement in the preface.&amp;nbsp; These include things like reflection, the insides of building, signing and deploying assemblies, the security model (such as trusted callers and encryption), and the ins and outs of threading.&lt;br /&gt;&lt;br /&gt;The new features in C# 4.0 are covered as well.&amp;nbsp; This includes a full chapter on the parallel library.&amp;nbsp; There were some interesting points that were made here including showing how the order that things happen in the parallel processes is indeterminate.&amp;nbsp; Also, there is a discussion of the various ways of "partitioning" -- helping the parallel library know how to best split up the tasks.&amp;nbsp; (Of course, you can also let the framework take it's best shot at splitting up the tasks, and this will work most of the time.)&lt;br /&gt;&lt;br /&gt;Overall, this was an excellent (if extremely long) read.&amp;nbsp; For me, I was reminded of some of the fundamentals of the C# language, I picked up a few tips on things I didn't know existed, and I also learned about the new pieces that were added to the 4.0 version of the language.&lt;br /&gt;&lt;br /&gt;I'll recommend this book to intermediate level .NET programmers or experienced programmers who are new to C#.&amp;nbsp; I'll keep this as a reference on my shelf and refer to it frequently.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2187101340023734268?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2187101340023734268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/10/book-review-c-40-in-nutshell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2187101340023734268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2187101340023734268'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/10/book-review-c-40-in-nutshell.html' title='Book Review: C# 4.0 in a Nutshell'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-5226006280346232373</id><published>2010-10-25T20:50:00.000-07:00</published><updated>2010-10-25T20:57:40.857-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Thanks for Coming - SoCal Code Camp Los Angeles</title><content type='html'>Thank you to everyone who came to my sessions at the SoCal Code Camp this last weekend.&amp;nbsp; And a special thank you to all of you who came to more than one of my sessions.&amp;nbsp; I had a great time doing the presentations and meeting all of you.&amp;nbsp; I hope that you found it worthwhile.&amp;nbsp; As a reminder, the slides, code samples and walkthroughs are available on my website: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I've collected a number of questions that came up and will have answers posted here in the near future.&amp;nbsp; A couple questions even came up in both the Saturday and Sunday sessions, so those will go to the top of the list.&lt;br /&gt;&lt;br /&gt;Still coming, I also have&amp;nbsp; a book review for C# 4.0 in a Nutshell by Albahari &amp;amp; Albahari.&amp;nbsp; Short version: excellent book in a gigantic nutshell (over 1,000 pages).&amp;nbsp; I've been a little delayed in getting the review out with my preparation for Code Camp (plus, I started a new job this week).&amp;nbsp; I've started reading my next book: Pro ASP.NET MVC 2 Framework by Steven Sanderson.&amp;nbsp; This has been a great read so far and will most likely end up on my "recommended" list.&lt;br /&gt;&lt;br /&gt;In the meantime...&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-5226006280346232373?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/5226006280346232373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/10/thanks-for-coming-socal-code-camp-los.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5226006280346232373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5226006280346232373'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/10/thanks-for-coming-socal-code-camp-los.html' title='Thanks for Coming - SoCal Code Camp Los Angeles'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-6871200923692471507</id><published>2010-09-28T20:24:00.000-07:00</published><updated>2010-09-28T20:24:33.361-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><title type='text'>Upcoming Speaking Engagements</title><content type='html'>I have several speaking engagements coming up in October and November.&amp;nbsp; If you've always wanted to meet me in person, come on out.&amp;nbsp; I'd love to meet you.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;October 19, 2010&lt;/strong&gt;&lt;br /&gt;ASP.NET SIG - San Diego, CA&lt;br /&gt;&lt;a href="http://www.sandiegodotnet.com/"&gt;http://www.sandiegodotnet.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;October 23 - 24, 2010&lt;/strong&gt;&lt;br /&gt;So Cal Code Camp - Los Angeles, CA&lt;br /&gt;&lt;a href="http://www.socalcodecamp.com/"&gt;http://www.socalcodecamp.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;November 13, 2010&lt;/strong&gt;&lt;br /&gt;Desert Code Camp - Chandler, AZ&lt;br /&gt;&lt;a href="http://nov2010.desertcodecamp.com/"&gt;http://nov2010.desertcodecamp.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-6871200923692471507?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/6871200923692471507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/09/upcoming-speaking-engagements.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/6871200923692471507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/6871200923692471507'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/09/upcoming-speaking-engagements.html' title='Upcoming Speaking Engagements'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2432766799399409301</id><published>2010-09-21T14:15:00.000-07:00</published><updated>2010-09-21T14:15:55.670-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><title type='text'>Learn the Lingo: Design Patterns</title><content type='html'>You already use Design Patterns but probably don't know it. Observer, Adapter, Iterator, Proxy -- Learning the lingo allows you to better communicate your ideas with other developers. We'll take a look at several GoF patterns that we regularly use without realizing it. Don't know who the GoF is? Read on to find out. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Get It Here&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;You can get the walkthrough and sample code here: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Direct Links:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/DesignPatterns.pdf"&gt;Walkthrough (PDF)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/DesignPatterns2010.zip"&gt;Code Download&lt;/a&gt;&amp;nbsp;-- Visual Studio 2010&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/DesignPatterns2008.zip"&gt;Code Download&lt;/a&gt;&amp;nbsp;-- Visual Studio 2008&lt;br /&gt;&lt;br /&gt;I'll be presenting this topic at the upcoming &lt;a href="http://www.socalcodecamp.com/"&gt;So Cal Code Camp&lt;/a&gt;, October 23rd and 24th in Los Angeles, CA.&amp;nbsp; Hope to see you there!&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2432766799399409301?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2432766799399409301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/09/learn-lingo-design-patterns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2432766799399409301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2432766799399409301'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/09/learn-lingo-design-patterns.html' title='Learn the Lingo: Design Patterns'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7493377219890099098</id><published>2010-09-20T21:24:00.000-07:00</published><updated>2010-09-21T14:09:20.087-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>So Cal Code Camp - Los Angeles</title><content type='html'>The &lt;a href="http://www.socalcodecamp.com/"&gt;So Cal Code Camp&lt;/a&gt; is coming to Los Angeles October 23rd &amp;amp; 24th.&amp;nbsp; As always, Code Camp is FREE!&amp;nbsp; It's a great chance to get some training and hook up with other developers / coders / hackers in your area.&amp;nbsp; I'll be presenting several sessions, so it's your chance to see me, too.&lt;br /&gt;&lt;br /&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7493377219890099098?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7493377219890099098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/09/so-cal-code-camp-los-angeles.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7493377219890099098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7493377219890099098'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/09/so-cal-code-camp-los-angeles.html' title='So Cal Code Camp - Los Angeles'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-4453729643645745335</id><published>2010-08-24T19:38:00.000-07:00</published><updated>2010-09-21T14:07:23.813-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Lambda Expression'/><title type='text'>Learn To Love Lambdas</title><content type='html'>Lambda expressions can be confusing the first time you walk up to them. But once you get to know them, you’ll see that they are a great addition to your toolbox. Used properly, they can add elegance and simplicity to your code. And some .NET constructs (such as LINQ) lend themselves to lambda expressions. We’ll take a look at how lambda expressions work and see them in action.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Get It Here&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;You can get the walkthrough and sample code here: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Direct Links:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/LearnToLoveLambdas.pdf"&gt;PDF Walkthrough&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/LearnToLoveLambdas2010.zip"&gt;Code Download&lt;/a&gt;&amp;nbsp;-- Visual Studio 2010 (Silverlight 4) &lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/LearnToLoveLambdas2008.zip"&gt;Code Download&lt;/a&gt;&amp;nbsp;-- Visual Studio 2008 (Silverlight 3)&lt;br /&gt;&lt;br /&gt;I'll be presenting this topic at the upcoming &lt;a href="http://www.socalcodecamp.com/"&gt;So Cal Code Camp&lt;/a&gt;, October 23rd and 24th in Los Angeles, CA.&amp;nbsp; Hope to see you there!&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-4453729643645745335?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/4453729643645745335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/08/learn-to-love-lambdas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/4453729643645745335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/4453729643645745335'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/08/learn-to-love-lambdas.html' title='Learn To Love Lambdas'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-3409245741122294996</id><published>2010-08-19T19:28:00.000-07:00</published><updated>2011-01-08T14:21:08.042-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Extension Method'/><title type='text'>Quick Bytes: Extension Methods</title><content type='html'>Extension methods allow you to add functionality to existing types by adding new methods -- no subtyping required. Here's a quick overview of how they work.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Get It Here&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;You can get the walkthrough (just a short 3-page one) and sample code here:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Direct Links:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/ExtensionMethods.pdf"&gt;PDF Walkthrough&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/ExtensionMethods.zip"&gt;Code Download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As always, feel free to let me know what you think: &lt;a href="mailto:feedback@jeremybytes.com"&gt;feedback@jeremybytes.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-3409245741122294996?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/3409245741122294996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/08/quick-bytes-extension-methods.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/3409245741122294996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/3409245741122294996'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/08/quick-bytes-extension-methods.html' title='Quick Bytes: Extension Methods'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-5352207400777258784</id><published>2010-08-03T22:12:00.000-07:00</published><updated>2010-08-04T06:44:21.596-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>The Ticker Class - Ready for Production?</title><content type='html'>My "Introduction to XAML" code samples -- both the WPF and Silverlight versions --&amp;nbsp;include a Ticker class that does the work behind the scenes.&amp;nbsp; (You can find the walkthroughs and code samples here: &lt;a href="http://www.jeremybytes.com/Downloads.aspx"&gt;http://www.jeremybytes.com/Downloads.aspx&lt;/a&gt;.)&amp;nbsp; The Ticker.cs file contains the following comment at the top:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// This class is a simple time ticker class. Note: this&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// class is for the included demo only and would require&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;// modifications before using in a production application&lt;/span&gt;&lt;/blockquote&gt;I recently received an e-mail from Tim M. asking&amp;nbsp;about this comment.&amp;nbsp; Let's take a closer look to see why this class may or may not be "Ready for Production."&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;No Guarantees&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;This class uses a DispatchTimer that fires a Tick event based on a specified interval.&amp;nbsp; Our sample application&amp;nbsp;uses a 100 millisecond interval.&amp;nbsp; But here's the trick: the Tick event is not guaranteed to fire at exactly the interval specified.&amp;nbsp; The only guarantee that we have is that the Tick event will never fire *before* the interval has elapsed.&amp;nbsp; And depending on what else your computer is doing at the time, the discrepancies may be quite significant.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Let's Experiment&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;So let's take a look at the completed code sample from "Introduction to XAML with WPF".&amp;nbsp; (This will work the same with the Silverlight version.)&lt;br /&gt;&lt;br /&gt;1. Navigate to the Ticker.cs file in the WPFStopWatch project.&lt;br /&gt;2. Modify the "UpdateValues" method so it looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/TFjrXArYluI/AAAAAAAAASc/VnkL0xfg-Xs/s1600/UpdateValues1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" bx="true" height="203" src="http://3.bp.blogspot.com/_tXOq_FsazuI/TFjrXArYluI/AAAAAAAAASc/VnkL0xfg-Xs/s640/UpdateValues1.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;We've modified the last line to include milliseconds in our display.&amp;nbsp; Now, if you run the app and click the Start and Stop buttons repeatedly, you will notice that the display&amp;nbsp;doesn't stop at&amp;nbsp;exactly a 100 millisecond interval.&amp;nbsp; Here's a screenshot from my run:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/TFjr4T9TAXI/AAAAAAAAASk/MOHbuxt-WY8/s1600/UpdatedApp.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" bx="true" src="http://3.bp.blogspot.com/_tXOq_FsazuI/TFjr4T9TAXI/AAAAAAAAASk/MOHbuxt-WY8/s320/UpdatedApp.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;But it's still hard to see exactly what's going on here.&amp;nbsp; Let's add each "tick" to an output that we can look at more closely.&lt;br /&gt;&lt;br /&gt;3. Add one more line to the "UpdateValues" method to output the value to the Console:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/TFjsXozr60I/AAAAAAAAASs/QDNyBsAMOsg/s1600/UpdateValues2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" bx="true" height="232" src="http://4.bp.blogspot.com/_tXOq_FsazuI/TFjsXozr60I/AAAAAAAAASs/QDNyBsAMOsg/s640/UpdateValues2.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;4. Open the "Output" window in Visual Studio -- on the "View" menu if you don't already have it showing.&lt;br /&gt;5. Run the application in "Debug" mode.&lt;br /&gt;&lt;br /&gt;Now when you click the Start / Stop buttons, each interval&amp;nbsp;value is recorded in the Output window.&amp;nbsp; (The Output window is the standard output for "Console" when running a WPF application.).&amp;nbsp; Here's a screenshot of the output from one my application runs:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/TFjtL7xGAeI/AAAAAAAAAS0/954CGw8MSRY/s1600/OutputWindow.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" bx="true" src="http://4.bp.blogspot.com/_tXOq_FsazuI/TFjtL7xGAeI/AAAAAAAAAS0/954CGw8MSRY/s320/OutputWindow.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;What you can see here is that the "1 second" tick occurs a full 1/10th of a second after the 1 second mark.&amp;nbsp; The time drift on my machine is between 4 and 12 milliseconds for this run.&amp;nbsp; But this is based on my computer/processor (a 2.66 GHz Core2Duo) and what was happening at the time.&amp;nbsp; If my machine was busy doing something else, then the tick events would fire further apart.&amp;nbsp; The good news is that the time reported (the DisplayInterval property of the class) is correct.&amp;nbsp; So, the "00:01.100" value itself is accurate.&lt;br /&gt;&lt;br /&gt;You can do further experimentation by changing the DispatchTimer interval to 10 milliseconds or even 1 millisecond.&amp;nbsp; By doing this, you can see the minimum time resolution that you can get on your computer with the Ticker class as it currently exists.&amp;nbsp; On my machine, it varies between 10 and 20 milliseconds with only Visual Studio and this application running.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Is This Really So Bad?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;For a simple timer (like we created in the sample), this behavior&amp;nbsp;really isn't a big deal. I&amp;nbsp;keep a timer such as this on my desktop to get a rough idea how long other processes take (such as running a report or fetching data from a web service). It works great for that. But if I wanted to do a "real" stop watch that could be used for high resolution timing (such as millisecond), then I would want to approach this a little differently. &lt;br /&gt;&lt;br /&gt;I haven't had to create a high-resolution timer, so I don't have a recommendation on exactly what to do.&amp;nbsp; A first step may be looking at the DispatcherPriority (an optional parameter in the constructor).&amp;nbsp; The default DispatcherPriority for the DispatchTimer is Background, which according to the documentation means "Operations are processed after all other non-idle operations are completed."&amp;nbsp; You can find a complete listing of values on MSDN here: &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Also, we need to consider the limitations of the .NET Framework and the underlying operating system.&amp;nbsp; Desktop PCs just weren't designed for ultra-high resolution timing purposes.&amp;nbsp; People who do have time-critical activities, such as complex music sequencing, often have specialized hardware and software (although software-only solutions have become more practical with the increase in processor speed and number of cores).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Ready for Production?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;So what we see is that the Ticker class will work perfectly well for a simple timer (which is what we created in the sample project).&amp;nbsp; But we can also see that there are&amp;nbsp;limitations in the timer resolution.&amp;nbsp; The good news is that the&amp;nbsp;DisplayInterval value&amp;nbsp;is always&amp;nbsp;correct -- this value does not drift; the drift is in the times between the Tick event firing.&lt;br /&gt;&lt;br /&gt;So whether this class is ready for production depends on your needs.&amp;nbsp; I added the caveat in the comments since there are&amp;nbsp;quirks&amp;nbsp;that need to be considered.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-5352207400777258784?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/5352207400777258784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/08/ticker-class-ready-for-production.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5352207400777258784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5352207400777258784'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/08/ticker-class-ready-for-production.html' title='The Ticker Class - Ready for Production?'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_tXOq_FsazuI/TFjrXArYluI/AAAAAAAAASc/VnkL0xfg-Xs/s72-c/UpdateValues1.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-873515387152348198</id><published>2010-07-28T21:03:00.000-07:00</published><updated>2010-07-28T21:04:38.783-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>The Use and Misuse of Design Patterns</title><content type='html'>Design Patterns have always been of great interest to me.&amp;nbsp; (If you doubt this, you can see that I have a section of my &lt;a href="http://www.jeremybytes.com/bookshelf.aspx#DP"&gt;Bookshelf&lt;/a&gt; dedicated to the topic.)&amp;nbsp; One of the greatest advantages to learning the basic patterns is to share a common language with your fellow developers, so when you talk about a Factory Method or Decorator, I know what you are talking about.&amp;nbsp; But at the same time, I see a tendency for some developers to use patterns for the sake of using patterns without fully considering the benefits and costs.&lt;br /&gt;&lt;br /&gt;Rocky Lhotka has a great article about what developers should think about when considering patterns in their projects.&amp;nbsp; You can find it here: &lt;a href="http://www.lhotka.net/weblog/OnTheUseAndMisuseOfPatterns.aspx"&gt;On the use and misuse of patterns&lt;/a&gt;.&amp;nbsp; Go take a look at it now.&amp;nbsp; Don't worry; I'll wait.&lt;br /&gt;&lt;br /&gt;Okay, are you done reading it?&amp;nbsp; Go back and read it again.&amp;nbsp; It's that important.&lt;br /&gt;&lt;br /&gt;Welcome back.&amp;nbsp; I've experienced a few of the issues that Rocky mentions.&amp;nbsp; First, I have seen the "Pattern of the Year" phenomenon.&amp;nbsp; It seems like some of the developers in my group get stuck on the current popular pattern.&amp;nbsp; I won't mention any specifics, because as Rocky notes, there's nothing wrong with the pattern itself.&amp;nbsp; The problem is that the popularity leads to a sort of cult of people who feel like they need to implement the pattern whether it fits in with the application or not.&lt;br /&gt;&lt;br /&gt;Second, I have seen developers that get so enamored with a particular pattern than they try to use it at every turn.&amp;nbsp; Rocky's analogy is great on this:&lt;br /&gt;&lt;blockquote&gt;"It is kind of like a carpenter who spends a lot of money buying some really nice new power tool.&amp;nbsp; And then trying to use that power tool for every part of the construction process -- even if that means being less efficient or increasing the complexity of the job -- just to use the tool."&lt;/blockquote&gt;Design patterns are just tools.&amp;nbsp; Part of being a good developer is understanding the strengths and weaknesses of each of those tools.&amp;nbsp; As developers, we need to focus on the problem space that we are working on and pick the appropriate tools for that job.&amp;nbsp; (As a side note, this extends beyond design patterns to the technologies that we use -- whether WPF, Silverlight, or WebForms -- and even further out to the platform -- whether .NET, LAMP, Java, or whatever.)&lt;br /&gt;&lt;br /&gt;I do have an issue that I'm not quite sure how to approach: I have worked with a developer and talked about the benefits and costs of a specific design pattern.&amp;nbsp; We both agreed on the strengths (what the pattern was trying to solve for) and the weaknesses (the added complexity).&amp;nbsp; And we also agreed that we would not get the benefits of the pattern in the current application we were discussing.&amp;nbsp; The frustration is that the other developer still wanted to use the pattern because "we might need it later."&amp;nbsp; Experience shows that this would be unlikely.&lt;br /&gt;&lt;br /&gt;So, if you have any suggestions on how to approach this type of situation, let me know.&amp;nbsp; I'll be sure to share the good responses here.&amp;nbsp; Send them to &lt;a href="mailto:feeback@jeremybytes.com"&gt;feeback@jeremybytes.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you are new to the design patterns world, I would encourage you to learn the benefits and costs of each pattern.&amp;nbsp; And above all, consider their usage carefully.&amp;nbsp; Patterns are a wonderful tool.&amp;nbsp; But don't get so wrapped up in the tool that you forget the problem you are trying to solve.&lt;br /&gt;&lt;br /&gt;Before you go, go back and read Rocky's article one more time:&amp;nbsp;&lt;a href="http://www.lhotka.net/weblog/OnTheUseAndMisuseOfPatterns.aspx"&gt;On the use and misuse of patterns&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-873515387152348198?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/873515387152348198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/07/use-and-misuse-of-design-patterns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/873515387152348198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/873515387152348198'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/07/use-and-misuse-of-design-patterns.html' title='The Use and Misuse of Design Patterns'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-3951732783265403387</id><published>2010-07-10T22:26:00.000-07:00</published><updated>2010-08-04T22:00:47.926-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Intro to XAML Questions</title><content type='html'>While presenting the Intro to XAML session at recent code camp and user groups, a few questions came up.&amp;nbsp; Here's&amp;nbsp;some more information on those topics that I didn't have at my fingertips at the time.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;FrameworkElement in the Ticker Class&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Question:&lt;/b&gt; Why does the Ticker class in the demo code descend from FrameworkElement?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Answer:&lt;/b&gt; As I noted during the session, the Ticker class exposes the DisplayInterval property as a DependencyProperty.&amp;nbsp; A DependencyProperty is a WPF/Silverlight construct that adds functionality above a normal property.&amp;nbsp; This is used for features such as animation, styles, and data binding.&amp;nbsp; We used it for data binding in our sample.&lt;br /&gt;&lt;br /&gt;So where does FrameworkElement come in?&amp;nbsp; A dependency property can only be added to a DependencyObject (or a class that descends from DependencyObject).&amp;nbsp; FrameworkElement happens to be a descendent of DependencyObject.&amp;nbsp; And since it is also the base class for most of the elements in WPF and Silverlight, it also makes a convenient base class for our custom Ticker class.&lt;br /&gt;&lt;br /&gt;If you want more information on dependency properties, you can check out MSDN here: &lt;a href="http://msdn.microsoft.com/en-us/library/ms752914.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms752914.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;User Controls in WPF/Silverlight&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Question:&lt;/b&gt; Can you create user controls in XAML that would allow you to use the same control on multiple screens?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Answer:&lt;/b&gt; The answer to this is definitely yes.&amp;nbsp; "UserControl" is one of the common root-level elements in XAML UIs (in addition to "Window" and "Page").&amp;nbsp; UserControl is now the default root element for Silverlight, but you can create your own user controls and embed them in other screens (whether they are Window, Page, or another UserControl).&lt;br /&gt;&lt;br /&gt;I do have an example in Silverlight that creates a UserControl in a separate XAML file and then uses it on a screen.&amp;nbsp; The sample is available here: &lt;a href="http://jeremybytes.blogspot.com/2009/06/more-silverlight-part-2-user-controls.html"&gt;http://jeremybytes.blogspot.com/2009/06/more-silverlight-part-2-user-controls.html&lt;/a&gt;.&amp;nbsp; There is a small caveat to this, though: it is Silverlight 2.&amp;nbsp; Fortunately, the part that shows how to create a user control and use it in your application is still relevant in Silverlight 4 (and WPF as well).&amp;nbsp; The section on events is also still accurate; however, there is a much easier way to build this particular sample in Silverlight 3 or 4 by using object binding instead of events.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Attached Properties&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Question:&lt;/b&gt; The XAML syntax for attached properties is intriguing.&amp;nbsp; How do they work?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Answer:&lt;/b&gt; An attached property&amp;nbsp;is a construct in WPF and Silverlight, and how the framework handles it internally is more information that you probably want.&amp;nbsp; So, let's just take a look at a short sample.&lt;br /&gt;&lt;br /&gt;In the demo code, we use an attached property by setting Grid.Row="0" inside of our TextBlock.&amp;nbsp; Here's a reminder of the code:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/TDlRQoxAvuI/AAAAAAAAASQ/5r4wJ4BL4HY/s1600/Snippet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="176" rw="true" src="http://2.bp.blogspot.com/_tXOq_FsazuI/TDlRQoxAvuI/AAAAAAAAASQ/5r4wJ4BL4HY/s640/Snippet.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;To get an idea of how this property gets set, let's take a look at how we would set this property in code rather than in the XAML.&amp;nbsp; We'll assume that our text block is named&amp;nbsp;"myTextblock".&amp;nbsp; There are actually 2 ways we can set the property: either from the point of view of the Grid or from the point of view of the TextBlock.&lt;br /&gt;&lt;br /&gt;From the Grid's viewpoint, the property is set like this:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Grid.SetRow(myTextBlock, 0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;From the TextBlock's viewpoint, the property is set like this:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;myTextBlock.SetValue(Grid.RowProperty, 0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Although this doesn't explain the internals, it does give you an idea of how it works.&amp;nbsp; With the first method, we are passing the element (myTextBlock) and value (0) to the Grid's SetRow method.&amp;nbsp; SetRow is a static method of the Grid class that allows for the "Row" attached property to be set.&amp;nbsp; With the second method, we use the SetValue method which allows us to set an attached property from the element (myTextBlock)&amp;nbsp;itself.&lt;br /&gt;&lt;br /&gt;Of course, there is more info on attached properties available on MSDN: &lt;a href="http://msdn.microsoft.com/en-us/library/ms749011.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms749011.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;ZoomIt&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Question:&lt;/b&gt; Where can I get the zooming tool used during the presentation?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Answer:&lt;/b&gt; ZoomIt is a tool that was created by a Microsoft employee (Mark Russinovich) for his own use in presentations.&amp;nbsp; It has several features including zooming the screen (like a magnifier), adding annotations (either drawing or text), and showing a break timer.&amp;nbsp; I ran across it while watching a webcast where the speaker was using the tool.&lt;br /&gt;&lt;br /&gt;You can download ZoomIt for free here: &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897434.aspx"&gt;http://technet.microsoft.com/en-us/sysinternals/bb897434.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Additional XAML Samples&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Not exactly a questions, but there are additional XAML samples available on my website.&amp;nbsp; The Target Practice application is a sample I built to see if I could build an application using XAML only.&amp;nbsp; I did this in both WPF and Silverlight 3.&amp;nbsp; Here are the links to the walkthroughs:&lt;br /&gt;&lt;br /&gt;WFP: &lt;a href="http://jeremybytes.blogspot.com/2009/03/wpf-xaml-sample.html"&gt;http://jeremybytes.blogspot.com/2009/03/wpf-xaml-sample.html&lt;/a&gt;&lt;br /&gt;Silverlight: &lt;a href="http://jeremybytes.blogspot.com/2009/09/target-practice-silverlight-3-xaml.html"&gt;http://jeremybytes.blogspot.com/2009/09/target-practice-silverlight-3-xaml.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As with all of my samples, the code can be downloaded from my website: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That's it for now.&amp;nbsp; If you have any questions, feel free to send them to &lt;a href="mailto:feedback@jeremybytes.com"&gt;feedback@jeremybytes.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-3951732783265403387?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/3951732783265403387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/07/intro-to-xaml-questions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/3951732783265403387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/3951732783265403387'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/07/intro-to-xaml-questions.html' title='Intro to XAML Questions'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_tXOq_FsazuI/TDlRQoxAvuI/AAAAAAAAASQ/5r4wJ4BL4HY/s72-c/Snippet.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-3459769303478140684</id><published>2010-07-08T07:30:00.000-07:00</published><updated>2010-07-08T08:01:00.527-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Languages'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>What's Wrong with VB.NET?</title><content type='html'>VB.NET has the reputation of being a second class language in the .NET world.&amp;nbsp; A lot of this has to do with the history of VB and its transformation from VB6 into VB.NET.&amp;nbsp; Conversely, there is a perception that C# is the "real" .NET language, and I think that comes from its (much shorter) history.&lt;br /&gt;&lt;br /&gt;At a recent user group meeting, someone joked that VB had been deprecated, and I will admit that I picked up and echoed that joke.&amp;nbsp; I hope that folks could tell that I wasn't serious.&amp;nbsp; When I'm talking to people, I try to point out VB resources where I can -- for example, my favorite Silverlight and WPF books have both VB and C# versions available -- but I'm personally more familiar with the C# resources since those are the ones I use on a day-to-day basis. &lt;br /&gt;&lt;br /&gt;Today, VB.NET and C# are pretty much the same language with different syntax (at least that's how I like to think of them).&amp;nbsp; And the great thing about .NET is that whatever language you work with still gets compiled down to the same IL, and you can use assemblies in your project that are created in any .NET language (in fact, you probably don't even know what language a third-party assembly was created with).&lt;br /&gt;&lt;br /&gt;Real programmers don't get stuck on syntax.&amp;nbsp; Programmers in general are opinionated and have their tools and languages of choice.&amp;nbsp; Good programmers generally have several different languages under their belts (and not just .NET languages, but things like Ruby, Python, Perl, Delphi, and Java).&amp;nbsp; I have my language of choice (which is currently C#, but has been different in the past), and before I start a task I try to make sure there isn't another tool that would do the job better.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Why the Bum Rap?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;So, why does VB.NET have this reputation?&amp;nbsp; My theory is based on looking at the history of .NET.&amp;nbsp; When .NET launched, it was a brand new platform.&amp;nbsp; Along with that launch, Microsoft was promoting a brand new language (C#) that was created just for that platform.&amp;nbsp; In order for .NET to succeed, Microsoft had to get as many people on board as possible.&amp;nbsp; C# was the vehicle they used for most of their demonstrations.&amp;nbsp; This was because C# had all of the capabilities of .NET (at the time).&amp;nbsp; Because of this, C# became equated in many people's minds as the "primary" .NET language.&lt;br /&gt;&lt;br /&gt;But Microsoft also knew that there were millions of people invested in VB.&amp;nbsp; They could not succeed if they forced all of the programmers who were comfortable with the VB syntax to switch over to a C-based syntax.&amp;nbsp; And more importantly, they couldn't force those developers to abandon all of their existing code.&amp;nbsp; So, we got VB.NET.&amp;nbsp; And that's sort of where the problems started.&lt;br /&gt;&lt;br /&gt;First of all, VB.NET was very different from VB6.&amp;nbsp; There were a number of "features" that were put in to VB.NET to make migration of existing VB6 code easier.&amp;nbsp; But if programmers wanted to really start using the .NET platform to its full potential, they needed to re-write quite a bit of code to fit in with the new paradigm. &lt;br /&gt;&lt;br /&gt;VB.NET and C# had quite a few differences in the early versions.&amp;nbsp; There were some constructs in C# that did not have an equivalent in VB.NET (and vice-versa).&amp;nbsp; In addition, Visual Studio tended to favor C# when it came to features such as refactoring and IntelliSense.&amp;nbsp; C# would get these feature updates first, and then they were made available to VB.NET later (as much later as the next release).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Forget Everything You Thought You Knew&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;But it's time to forget everything you thought you knew about the differences between VB.NET and C#.&amp;nbsp; With the latest release of .NET 4, the languages are almost equivalent; there are a few minor differences, but for all intents and purposes, you can accomplish the same tasks in similar ways.&lt;br /&gt;&lt;br /&gt;Steve K. pointed me to this blog article from Steve Wiltamuth regarding the futures of both languages: &lt;a href="http://blogs.msdn.com/b/scottwil/archive/2010/03/09/vb-and-c-coevolution.aspx"&gt;VB and C# Coevolution&lt;/a&gt;.&amp;nbsp; In short, Microsoft is committed to moving both languages forward in the same direction and keep parity in the features and tools (such as the refactoring and IntelliSense features in Visual Studio).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Wrap Up&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;The good news of the similarities between the languages is that both C# and VB.NET programmers can take advantage of the vast amount of sample code that's available on the net. &lt;br /&gt;&lt;br /&gt;Having both C# and VB.NET is great for the .NET development community.&amp;nbsp; C# (and the C-based syntax) provided a comfortable migration for folks using Java and C++; VB.NET provide a comfortable migration path for folks using VB.&amp;nbsp; Together, this has created a mix of developers that can share code and still hang on to their preferred syntax.&amp;nbsp; That sounds like the best of both worlds to me.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-3459769303478140684?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/3459769303478140684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/07/real-programmers-use-vbnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/3459769303478140684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/3459769303478140684'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/07/real-programmers-use-vbnet.html' title='What&apos;s Wrong with VB.NET?'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-3730082311907733286</id><published>2010-06-28T21:26:00.000-07:00</published><updated>2010-06-28T21:26:38.977-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Upcoming User Groups</title><content type='html'>I'll be presenting at a couple of upcoming users groups in the Greater Los Angeles area.&amp;nbsp; Here are the dates and links to the websites:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tuesday, July 6&lt;/b&gt;&lt;br /&gt;LA C# (Manhattan Beach, CA) - &lt;a href="http://www.lacsharp.org/"&gt;http://www.lacsharp.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Wednesday, July 7&lt;/b&gt;&lt;br /&gt;SoCal .NET (Buena Park, CA) - &lt;a href="http://www.socaldotnet.org/"&gt;http://www.socaldotnet.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Meetings start at 6:00 p.m., and it's a great chance to interact with other developers in your local area.&amp;nbsp; Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-3730082311907733286?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/3730082311907733286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/06/upcoming-user-groups.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/3730082311907733286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/3730082311907733286'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/06/upcoming-user-groups.html' title='Upcoming User Groups'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-8459358577062263836</id><published>2010-06-27T16:13:00.000-07:00</published><updated>2010-06-27T16:13:20.766-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Thanks for Coming - SoCal Code Camp San Diego</title><content type='html'>Thank you to everyone who took the time to attend my sessions at the SoCal Code Camp this weekend.&amp;nbsp; I had a great time doing the presentations, and I hope you found the information useful.&lt;br /&gt;&lt;br /&gt;As a reminder, all of my sessions are available on my website here: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;JeremyBytes.com - Demos&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you liked the sessions (or didn't like the sessions), feel free to drop me a note at &lt;a href="mailto:feedback@jeremybytes.com"&gt;feedback@jeremybytes.com&lt;/a&gt;.&amp;nbsp; I'll also be glad to answer any follow-up questions you may have.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-8459358577062263836?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/8459358577062263836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/06/thanks-for-coming-socal-code-camp-san.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8459358577062263836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8459358577062263836'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/06/thanks-for-coming-socal-code-camp-san.html' title='Thanks for Coming - SoCal Code Camp San Diego'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-6259240790870520627</id><published>2010-06-20T15:27:00.000-07:00</published><updated>2010-06-20T15:27:49.694-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Book Review'/><title type='text'>Book Review: Effective C# - Second Edition</title><content type='html'>I just finished up &lt;em&gt;Effective C#: 50 Specific Ways to Improve your C#&lt;/em&gt; (Second Edition) by Bill Wagner.&amp;nbsp; This is a collection of expert tips&amp;nbsp;presentented in a clear and concise manner.&amp;nbsp; These are targeted at the intermediate/advanced developer; it is assumed that you understand the basics of C# programming.&amp;nbsp; With that said, this is an excellent resource for folks like me.&amp;nbsp; Bill Wagner brings to light best practices, some pitfalls, and issues to consider, especially if you are designing libraries/APIs for consumption by other developers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is an updated version of &lt;em&gt;Effective C#&lt;/em&gt; (First Edition) and &lt;em&gt;More Effective C#&lt;/em&gt;.&amp;nbsp; Each of these covered different versions of the .NET framework.&amp;nbsp; This edition covers C# 4; the content is not limited to "what's new in C# 4."&amp;nbsp; It covers items that&amp;nbsp;go back to the earliest versions of .NET, but also&amp;nbsp;includes new&amp;nbsp;items such as dynamic typing and parallel&amp;nbsp;programming&amp;nbsp;with PLINQ.&lt;br /&gt;&lt;br /&gt;As the title suggests, there are 50 "items" (spread over 6 chapters).&amp;nbsp; The book is a fairly brief 300 pages; which translates into an average of 6 pages per item.&amp;nbsp; The items are well-presented with an introduction to the problem space, a recommendation (based on a set of parameters), and clearly written code snippets.&amp;nbsp; Each item is also summarized in a closing paragraph that reiterates the problem and solution.&lt;br /&gt;&lt;br /&gt;Here's one thing that I like: Bill Wagner does not say "always do this."&amp;nbsp; Each recommendation includes the pros and cons as well as&amp;nbsp;when you may want to do things one way versus another.&amp;nbsp; Many items will also refer to other items in the book.&amp;nbsp; This helps build a cohesion to the overall text.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;Chapters&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Here's a quick&amp;nbsp;listing of the chapters with a few items from each to give you an idea of the types of things covered in each:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;C# Language Idioms&lt;/strong&gt;&lt;br /&gt;Item 3: Prefer the is or as Operators to Cast&lt;br /&gt;Item 5: Always Provide ToString()&lt;br /&gt;Item 8: Prefer Query Syntax to Loops&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET Resource Management&lt;/strong&gt;&lt;br /&gt;Item 14: Minimize Duplicate Initialization Logic&lt;br /&gt;Item 15: Utilize using and try/finally for Resource Cleanup&lt;br /&gt;Item 18: Distinguish Between Value Types and Reference Types&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Expressing Designs in C#&lt;/strong&gt;&lt;br /&gt;Item 22: Prefer Defining and Implementing Interfaces to Inheritance&lt;br /&gt;Item 24: Express Callbacks with Delegates&lt;br /&gt;Item 25: Implement the Event Pattern for Notifications&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Working with the Framework&lt;/strong&gt;&lt;br /&gt;Item 32: Avoid ICloneable&lt;br /&gt;Item 35: Learn how PLINQ Implements Parallel Algorithms&lt;br /&gt;Item 37: Construct Parallel Algorithms with Exceptions in Mind&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dynamic Programming&lt;/strong&gt;&lt;br /&gt;Item 38: Understand the Pros and Cons of Dynamic&lt;br /&gt;Item 40: Use Dynamic for Parameters That Receive Anonymous Types&lt;br /&gt;Item 44: Minimize Dynamic Objects in Public APIs&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Miscellaneous&lt;/strong&gt;&lt;br /&gt;Item 45: Minimize Boxing and Unboxing&lt;br /&gt;Item 47: Prefer the Strong Exception Guarantee&lt;br /&gt;Item 48: Prefer Safe Code&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;A Couple Specific Examples&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Item 8: Prefer Query Syntax to Loops&lt;/strong&gt;&lt;br /&gt;Wagner takes a look at advantages that query syntax (LINQ) has over loops (for, while, do, foreach).&amp;nbsp; He doesn't say that standard loops are bad or that we should stop using them.&amp;nbsp; Instead, he shows some specific examples that illustrate&amp;nbsp;how query syntax can make your code more readable and&amp;nbsp;maintainable.&lt;br /&gt;&lt;br /&gt;Personally, I've become a big fan of LINQ.&amp;nbsp; But it did take me a while to get to that point.&amp;nbsp; Wagner challenges the developer to step out of his/her comfort zone (loops) and take a look at query syntax and to consider the difference between the imperative model (telling your code how to do the task) and the declarative model (telling your code what task you want to do).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Item 14: Minimize Duplicate Initialization Logic&lt;/strong&gt;&lt;br /&gt;Wagner points out the pitfalls of having multiple constructors as part of your class and having "copy/paste" code in each of the constructors.&amp;nbsp; This seems obvious once you think about it; after all, we always strive to minimize duplicate logic.&amp;nbsp; The first tendency may be to move all of the logic into a shared private method, but Wagner points out that this is not the optimum solution.&amp;nbsp; Instead look toward having the simpler constructors (those with fewer or no parameters) call the more complex constructors (those with several parameters).&lt;br /&gt;&lt;br /&gt;Then he goes a step further and shows specific cases where you may introduce bugs in your code if you are not careful with how you implement the shared logic.&amp;nbsp; In addition, he takes a look at the efficiency of the code generated by the C# compiler in various situations.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;Overall Quality&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;The overall quality of the text is very good.&amp;nbsp; I did notice a few typos here and there (no one is perfect -- I'm sure you'll also find some typos in this post).&amp;nbsp; There was only one item (#23) that had what I would consider significant issues with the code samples.&amp;nbsp; Fortunately, there is&amp;nbsp;a blog on the SRT Solutions (co-founded by Wagner) web site that lists the errata.&amp;nbsp; Be sure to check this out.&lt;br /&gt;&lt;br /&gt;Tech books are notoriously hard to produce due to how quickly technology changes (especially Microsoft technologies).&amp;nbsp; The errors that I noticed were well within the tolerable range and did not distract from my understanding of the content.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;I would definitely recommend this book to intermediate and advanced C# developers.&amp;nbsp; There are a number of items (especially in the dynamic and parallel items) that gave me insight into things to watch for as I look into the new features in C# 4.&amp;nbsp; As any developer advances, he/she usually ends up creating shared libraries (shared utilities, for example). Wagner includes many items that cover best practices for creating shared libraries and APIs that are consumed by other developers.&amp;nbsp; This is also&amp;nbsp;helpful when one works as part of of a team on projects that have multiple interoperating assemblies/modules.&lt;br /&gt;&lt;br /&gt;So, pick this book up.&amp;nbsp; It has bite-sized&amp;nbsp;chunks of good information and some good tips on new C# features.&lt;br /&gt;&lt;br /&gt;Happy Coding!&amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-6259240790870520627?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/6259240790870520627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/06/book-review-effective-c-second-edition.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/6259240790870520627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/6259240790870520627'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/06/book-review-effective-c-second-edition.html' title='Book Review: Effective C# - Second Edition'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2359482397157931465</id><published>2010-05-31T10:46:00.000-07:00</published><updated>2010-06-04T06:36:44.382-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Value Converter'/><category scheme='http://www.blogger.com/atom/ns#' term='Threading'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Template'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='BackgroundWorker'/><title type='text'>Updated Sessions</title><content type='html'>I have updated a number of my sessions for Visual Studio 2010 and/or Silverlight 4.&amp;nbsp; I will be presenting three of these sessions at the So Cal Code Camp coming up on June 26 &amp;amp; 27, 2010.&amp;nbsp; These are all available for download here: &lt;a href="http://www.jeremybytes.com/demos.aspx"&gt;http://www.jeremybytes.com/demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Introduction to the BackgroundWorker Component with WPF&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Long running processes are a user experience killer. How many times have you had an application "lock up" while trying to do some function? The BackgroundWorker component in .NET allows you to spawn those long running processes in the background and keep your WPF, Silverlight, or WinForms user interface responsive. We'll take a look at the features of the BackgroundWorker in a WPF application including running a background process, updating the progress in the UI, and cancelling the process before it has completed. &lt;br /&gt;&lt;br /&gt;&lt;i&gt;This session has been expanded to include Exception Handling and additional error checking.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Walkthrough: &lt;a href="http://www.jeremybytes.com/Downloads/BackgroundWorker-WPF2010.pdf"&gt;BackgroundWorker-WPF2010.pdf&lt;/a&gt;&lt;br /&gt;Sample Code: &lt;a href="http://www.jeremybytes.com/Downloads/BackgroundWorker-WPF2010.zip"&gt;BackgroundWorker-WPF2010.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Introduction to Data Templates and Value Converters in Silverlight&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Business applications are all about data, and laying out that data is critical to creating a good user experience. Silverlight has several tools, including Data Templates and Value Converters, that make this easier for the business developer to manage. By the time we're done, you will have a good understanding of the basics of both of these valuable tools.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This session has been updated for Silverlight 4.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Walkthrough: &lt;a href="http://www.jeremybytes.com/Downloads/DataTemplatesAndConverters2010.pdf"&gt;DataTemplatesAndConverters2010.pdf&lt;/a&gt;&lt;br /&gt;Sample Code: &lt;a href="http://www.jeremybytes.com/Downloads/DataTemplatesAndConverters2010.zip"&gt;DataTemplatesAndConverters2010.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Introduction to XAML - WPF 2010 / Silverlight 4&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Understanding XAML (eXtensible Application Markup Language) is a key to creating the latest .NET user experiences in WPF and Silverlight. We will introduce the basic concepts around XAML and take a look at various features such as namespaces, elements, properties, events, attached properties and some basic layout. We’ll create a simple WPF&amp;nbsp;or Silverlight application that covers these fundamentals. Although you will probably end up doing most of your UI design with a drag-and-drop tool such as Expression Blend, knowing the internals gives you a leg up in making the final tweaks to ensure an excellent user experience.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This session has been updated to include both WPF and Silverlight versions.&amp;nbsp; The same core XAML features are covered in each environment.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Walkthr&lt;a href="http://www.blogger.com/"&gt;&lt;/a&gt;&lt;span id="goog_229251154"&gt;&lt;/span&gt;&lt;span id="goog_229251155"&gt;&lt;/span&gt;ough (WPF): &lt;a href="http://www.jeremybytes.com/Downloads/IntroToXAML-WPF2010.pdf"&gt;IntroToXAML-WPF2010.pdf&lt;/a&gt;&lt;br /&gt;Sample Code (WPF): &lt;a href="http://www.jeremybytes.com/Downloads/IntroToXAML-WPF2010.zip"&gt;IntroToXAML-WPF2010.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Walkthrough (Silverlight): &lt;a href="http://www.jeremybytes.com/Downloads/IntroToXAML-Silverlight4.pdf"&gt;IntroToXAML-Silverlight4.pdf&lt;/a&gt;&lt;br /&gt;Sample Code (Silverlight): &lt;a href="http://www.jeremybytes.com/Downloads/IntroToXAML-Silverlight4.zip"&gt;IntroToXAML-Silverlight4.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As always, your feedback/questions on any of these sessions&amp;nbsp;is appreciated: &lt;a href="mailto:feedback@jeremybytes.com"&gt;feedback@jeremybytes.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2359482397157931465?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2359482397157931465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/05/updated-sessions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2359482397157931465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2359482397157931465'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/05/updated-sessions.html' title='Updated Sessions'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-6596529848399925682</id><published>2010-05-15T20:54:00.000-07:00</published><updated>2010-05-15T20:54:31.775-07:00</updated><title type='text'>So Cal Code Camp - San Diego Coming in June</title><content type='html'>The &lt;a href="http://www.socalcodecamp.com/"&gt;So Cal Code Camp&lt;/a&gt; is coming to San Diego June 26th &amp;amp; 27th.&amp;nbsp; As always, Code Camp is FREE!&amp;nbsp; It's a great chance to get some training and hook up with other developers / coders / hackers in your area.&amp;nbsp; I'll be presenting&amp;nbsp;a few sessions, so it's your chance to see me, too.&lt;br /&gt;&lt;br /&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-6596529848399925682?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/6596529848399925682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/05/so-cal-code-camp-san-diego-coming-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/6596529848399925682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/6596529848399925682'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/05/so-cal-code-camp-san-diego-coming-in.html' title='So Cal Code Camp - San Diego Coming in June'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-9110812118234849281</id><published>2010-04-29T19:58:00.000-07:00</published><updated>2010-05-05T22:13:06.263-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>More Thoughts on ASP.NET MVC</title><content type='html'>I've had two months to work with ASP.NET MVC since my &lt;a href="http://jeremybytes.blogspot.com/2010/02/new-to-me-aspnet-mvc.html"&gt;last post on the topic&lt;/a&gt;.&amp;nbsp; Since then, I've worked through two projects and have picked up some good experience.&amp;nbsp; There are plenty of pros and cons (more pros in my opinion).&amp;nbsp; Let's take a look at how it differs from other .NET web technologies.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Routing&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;ASP.NET MVC is more than just Model-View-Controller pattern (the MVC which lends its name).&amp;nbsp; One of the key features is routing.&amp;nbsp; With routing, a URL does not point to a physical resource on the server.&amp;nbsp; Instead, it contains information that allows the Controller to instantiate the appropriate Model and send the data to a specific View.&amp;nbsp; You're probably familiar with the pattern.&amp;nbsp; Let's take a look at the URL for my previous post: http://jeremybytes.blogspot.com/2010/02/new-to-me-aspnet-mvc.html.&lt;br /&gt;&lt;br /&gt;The first part is (http://jeremybytes.blogspot.com) points to the server.&amp;nbsp; The next part (2010) would normally be parsed as a physical path (file folder) on the server.&amp;nbsp; But instead, it is a parameter that references the year of the post.&amp;nbsp; The same is true of the "02" portion (the original post is from February 2010).&amp;nbsp; The final part is the name of the article.&amp;nbsp; Now, I can't tell you what lies behind the blogspot link or how it is parsed, but I'm pretty sure that there are no physical directories that refer to the year and month of my posts.&lt;br /&gt;&lt;br /&gt;You use this same type of routing in the ASP.NET MVC world.&amp;nbsp; The default is for a URL to take the form of {controller}/{action}/{id}, but you can alter this default implementation however you like.&amp;nbsp; As an example: http://www.example.com/sales/customer/217.&amp;nbsp; This would call the "Sales" controller and ask for Customer #217.&lt;br /&gt;&lt;br /&gt;As mentioned previously, this is an "action-first" or "resource-first" model (as opposed to WebForms "page-first" model).&amp;nbsp; I say "action" or "resource" because that will depend on what you are doing.&amp;nbsp; In the above example, we are requesting a specific Customer resource.&amp;nbsp; But we could just as well be requesting an action, such as "UpdateCustomer".&lt;br /&gt;&lt;br /&gt;This strikes me as very REST-ful, although that is a topic for another time.&amp;nbsp; The good news for those who like the idea of routing but aren't ready to dive into the rest of ASP.NET MVC: Routing is included in ASP.NET 4.0 (it's actually also available somewhat in 3.5 but requires some extra work).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;ASP.NET MVC vs. WebForms: Repeaters&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I spent 3 years developing WebForms apps, so I've tried quite a few different techniques for displaying data.&amp;nbsp; The control I ended up liking best is the Repeater.&amp;nbsp; This gives me the most flexibility in laying out my data.&amp;nbsp; But it does have one severe limitation: you cannot nest Repeaters.&lt;br /&gt;&lt;br /&gt;The idea of a Repeater is that it will loop through your data set and "repeat" a specified section for each record.&amp;nbsp; This is fine for single level lists, but it gets more complex when you have parent-child relationships.&lt;br /&gt;&lt;br /&gt;Let's say that I have data that includes Category, Sub-Category, and Details.&amp;nbsp; I only want to display the Category label at the top of each Category (not on each record).&amp;nbsp; The same is true for Sub-Category.&amp;nbsp; But since I can't nest Repeaters, that means that I must include Category, Sub-Category, and Detail in every single one of my records (flattened data rather than a hierarchy).&amp;nbsp; Then, to get the display that I want, I hook into the Event that runs before displaying each record.&amp;nbsp; In that event handler, I check to see if the current Category is the same as the Category of the previous record.&amp;nbsp; If so, then I suppress (hide) the Category display.&amp;nbsp; Same for Sub-Category.&amp;nbsp; This creates quite a bit of messy, conditional code.&lt;br /&gt;&lt;br /&gt;ASP.NET MVC handles this situation entirely different.&amp;nbsp; You are much closer to the metal.&amp;nbsp; So, if I wanted to implement the above scenario, it's quite a bit more elegant.&amp;nbsp; In the View, I simply have a foreach loop that goes through all of the Categories and displays the Category header.&amp;nbsp; Inside there, I have a nested loop that goes through the Sub-Categories and displays that.&amp;nbsp; And inside there, I have a nested loop that goes through the details.&amp;nbsp; This means that I can have a much more natural structure to my data (Model) with a parent-child-grandchild relationship.&amp;nbsp; Add some LINQy goodness, and you have an easily understandable solution without the messy conditionals.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;ASP.NET MVC vs. WebForms: File Size&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Yes, file size is still important -- just take a look at how prominent smart phones and other mobile devices are becoming.&amp;nbsp; I took an existing WebForms application and converted it to ASP.NET MVC.&amp;nbsp; This was a proof-of-concept so I could try out the technologies.&amp;nbsp; Since the existing application had a well-defined business layer and clear separation from the UI, it was easy to put the ASP.NET MVC front end in place.&lt;br /&gt;&lt;br /&gt;Here's what I found: a particular page on the WebForms apps that was 24KB was only 9KB in the ASP.NET MVC version!&lt;br /&gt;&lt;br /&gt;I know your initial reaction: just turn off ViewState, moron.&amp;nbsp; But ViewState was turned off.&amp;nbsp; The WebForms page is so much bigger because it uses server-generated names for all of the controls.&amp;nbsp; This can look like "ctl00_mainRepeater_headerLabel_001".&amp;nbsp; When you multiply this by the number of controls for each record and the number of records in the data set, it all adds up.&lt;br /&gt;&lt;br /&gt;Conversely, the majority of the ASP.NET MVC output is text -- the equivalent of using a Response.Write instead of using a server-side control.&amp;nbsp; When you look at the output (view source in the browser), it looks like hand-coded HTML rather than machine-generated code.&amp;nbsp; This will vary depending on how you code up your Views, of course.&amp;nbsp; My experience is that the output is pretty straight forward compared to WebForms output.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;ASP.NET MVC vs. Silverlight&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I won't really get into this debate.&amp;nbsp; Both technologies have their uses and benefits.&amp;nbsp; I was recently listening to&amp;nbsp;&lt;a href="http://www.dotnetrocks.com/"&gt;.NET Rocks!&lt;/a&gt; and heard about a "challenge" that took place at the Visual Studio 2010 Launch Event.&amp;nbsp; Apparently Phil Haack (and team) and Rocky Lhotka (and team) were tasked with creating an application in ASP.NET MVC and Silverlight, respectively.&amp;nbsp; I have a great deal of respect for both of these guys, so I'll just leave that discussion there.&lt;br /&gt;&lt;br /&gt;After using Silverlight myself, I was determined that I would never create another WebForms app again (the programming style is just so much more natural).&amp;nbsp; But there is a problem (mentioned above): mobile users.&lt;br /&gt;&lt;br /&gt;The reason that I started using ASP.NET MVC is because I needed to create a solution for Blackberry users.&amp;nbsp; And I'm not talking about the shiny-new Blackberry Bolds.&amp;nbsp; I'm talking about (relatively) old devices with browsers that are a step above WAP.&amp;nbsp; Obviously, Silverlight was not an option.&amp;nbsp; ASP.NET MVC, however, allowed me to put together a clean and efficient application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;One Last Thing: Parameters&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;There are a number of things I like about ASP.NET MVC, but I'll wrap up with one item: Action parameters.&amp;nbsp; The ASP.NET MVC framework does everything it can to automatically pull in the parameters for you.&lt;br /&gt;&lt;br /&gt;Let's say that I have an Action (method) like this: UpdateCustomer(int Id, string firstName, string lastName).&amp;nbsp; When this method gets called, the framework tries to populate the parameters from the following locations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Routing Parameters: These are the parameters that appear as part of the URL "path", such as the "217" in the Customer example above.&lt;/li&gt;&lt;li&gt;Query String: These are additional parameters that are part of the URL query string.&amp;nbsp; These are separated from the rest of the URL with a question mark and take the form name=value (separated by ampersands).&lt;/li&gt;&lt;li&gt;Form Data: These are pulled from fields that are posted back in a form. &lt;/li&gt;&lt;li&gt;Post Parameters: These are the parameters provided as part of a POST (not necessarily part of a form).&lt;/li&gt;&lt;li&gt;Header Information: These items can be pulled from the request header.&lt;/li&gt;&lt;/ul&gt;If the framework can find matching, case-insensitive names that match the parameter names, it will pass them through to your method.&amp;nbsp; There's something about this that strikes me as very cool -- anything that makes my life easier is good.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Wrap Up&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;I've grown to like ASP.NET MVC.&amp;nbsp; At a later date, I'll put together a case study with my actual code to give you a better idea of exactly how the technology works.&amp;nbsp; For now, we'll just stay with what we've discussed so far.&lt;br /&gt;&lt;br /&gt;ASP.NET MVC 2 is now shipping as part of Visual Studio 2010.&amp;nbsp; I've only taken a cursory look at it, but it seems to have added some good features to make views even easier and cleaner to generate.&amp;nbsp; Plus, having it included in Visual Studio means that other members of your team will also have it available without having to install the bits separately.&amp;nbsp; If you're doing web programming, this is definitely something to look into.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-9110812118234849281?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/9110812118234849281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/04/more-thoughts-on-aspnet-mvc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/9110812118234849281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/9110812118234849281'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/04/more-thoughts-on-aspnet-mvc.html' title='More Thoughts on ASP.NET MVC'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-1836474635232366186</id><published>2010-04-06T22:13:00.000-07:00</published><updated>2010-04-06T22:14:10.502-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Book Review'/><title type='text'>A Programmer's Bookshelf</title><content type='html'>Due to several requests, I added a &lt;a href="http://www.jeremybytes.com/Bookshelf.aspx"&gt;Bookshelf&lt;/a&gt;&amp;nbsp;to my website.&amp;nbsp; This has a listing of many of the books that I have read over the last several years.&amp;nbsp; My ultimate goal is to create a searchable Silverlight application, but I'm waiting for Silverlight 4 to come out before I get started on that.&amp;nbsp; In the meantime, we'll have to settle for a static list.&lt;br /&gt;&lt;br /&gt;If you have any books that you are fond of, feel free to drop me a note.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-1836474635232366186?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/1836474635232366186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/04/programmers-bookshelf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1836474635232366186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1836474635232366186'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/04/programmers-bookshelf.html' title='A Programmer&apos;s Bookshelf'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2889554598144882175</id><published>2010-04-05T21:07:00.000-07:00</published><updated>2010-04-06T13:06:06.718-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='BackgroundWorker'/><title type='text'>BackgroundWorker Component Questions</title><content type='html'>I recently received an e-mail with a few questions regarding the BackgroundWorker Component (&lt;a href="http://jeremybytes.blogspot.com/2009/12/introduction-to-background-worker.html"&gt;original article&lt;/a&gt;).&amp;nbsp; I decided to share the answers here.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Page Navigation with the BackgroundWorker&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Question:&lt;/b&gt; I want to navigate to another page in the BackgroundWorker thread -- for example: "frameNavigator.Navigate(new OtherPage());" in the DoWork method.&amp;nbsp; I tried this, but an exception occurred because the Page class uses the main thread whereas the BackgroundWorker uses a separate thread.&amp;nbsp; How can I get around this?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Answer:&lt;/b&gt;&amp;nbsp; As you noticed, things like Pages, Winodws and ListBoxes are all items on the UI thread (and they need to stay on the UI thread).&amp;nbsp; And the BackgroundWorker component processes items on a different thread (not the UI thread).&amp;nbsp; So, you will not be able to do things like "Navigate" in the DoWork method.&lt;br /&gt;&lt;br /&gt;But here's what you should do: try to figure out why the navigation process is slow.&amp;nbsp; This is usually due to something that happens when your new Page loads -- it could be loading data from a database, transferring a file across the network, or calling a web service.&amp;nbsp; So, even though you cannot put the "Navigate" into the background, you may be able to take whatever is in your Page Load process and put that in the background.&amp;nbsp; In this type of scenario, you could put the database call method or the file transfer method into the background, not the entire Page object.&amp;nbsp; This will have the effect of keeping your UI thread running and responsive while your data loads in the background.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Using the Progress Bar&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Question:&lt;/b&gt; I want to get the progress completed from the actual process time, not from a predetermined time as you used in the walkthrough.&amp;nbsp; The application must know how much time the BackgroundWorker process will take to navigate to the target page and then show a progress bar based on this information.&amp;nbsp; How can I accomplish this?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Answer:&lt;/b&gt; Progress is a tricky subject.&amp;nbsp; In the example in my walkthrough, I am not technically doing the progress bar based on a predetermined time; I am calculating the progress (a percentage) based on the number of iterations completed in the loop.&amp;nbsp; I purposely kept my background process simple so that I could focus on the methods, events and properties of the BackgroundWorker component itself.&amp;nbsp; But you can use the progress event for anything you can calculate a percentage complete for.&amp;nbsp; For a more complex example, you can look at the BackgroundWorker examples on MSDN: &lt;a href="http://msdn.microsoft.com/en-us/library/c8dcext2.aspx"&gt;http://msdn.microsoft.com/en-us/library/c8dcext2.aspx&lt;/a&gt;.&amp;nbsp; One in particular, calculates a Fibonacci sequence using a recursive method call and calculates a percentage for a progress bar.&lt;br /&gt;&lt;br /&gt;As an example of a calculation: if you are doing a file transfer, you can calculate a percentage based on the number of bytes received compared to the total number of bytes.&amp;nbsp; So, if you have received 257 bytes of a 1,356 byte file, you are 19% complete.&amp;nbsp; The limitation is that you have to know how far along you are in the process.&amp;nbsp; If you are doing something like making a database call or a web service call, you may not know how long it will take to complete or how much data you are getting back.&amp;nbsp; In those situations, you cannot calculate a percentage and so you may be better off using a "busy animation" (and there are plenty of examples available on the web for WPF and Silverlight).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Complex Results&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Question:&lt;/b&gt; I don't like examples of BackgroundWorker using results of "string" or "int".&amp;nbsp; I want a real object.&amp;nbsp; How would I do this?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Answer:&lt;/b&gt; The e.Result parameter in the DoWork and RunWorkerCompleted can be as simple or as complex as you like.&amp;nbsp; In my example, I simply use an "int", but e.Result is of type "object", so you can put whatever you want in there (including an entire database result set).&amp;nbsp; There are a few limitations such as the objects that need to be on the UI thread (like we mentioned above).&amp;nbsp; As another option, you can use a separate variable (or set of variables) that is accessible to both the UI and the background process.&amp;nbsp; If you do this, you will want to look into the "lock" method to ensure that you don't end up with multiple processes trying to modify the value at the same time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Round Up&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;The BackgroundWorker component is not the right solution for everything.&amp;nbsp; But it can be helpful in quite a few situations.&amp;nbsp; As we saw above, you may not be able to do exactly what you want (such as navigating in the background), but if you think about the problem a little differently, you can often come up with a workable solution.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2889554598144882175?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2889554598144882175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/04/backgroundworker-component-questions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2889554598144882175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2889554598144882175'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/04/backgroundworker-component-questions.html' title='BackgroundWorker Component Questions'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-1581876253332444395</id><published>2010-04-02T20:50:00.000-07:00</published><updated>2010-04-02T20:50:29.654-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight 3'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><title type='text'>Target Practice Live Demo</title><content type='html'>I have finally posted a live demo of the Silverlight 3 Target Practice demo application:&amp;nbsp;&lt;a href="http://www.jeremybytes.com/SilverlightDemos/SilverlightTargetPractice.aspx"&gt;Target Practice Live Demo&lt;/a&gt;.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;As a reminder, this is a mini-app created entirely with XAML (no code-behind).&amp;nbsp; The original article is here: &lt;a href="http://jeremybytes.blogspot.com/2009/09/target-practice-silverlight-3-xaml.html"&gt;Silverlight Target Practice&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And you can get the source code here: &lt;a href="http://www.jeremybytes.com/Downloads/SilverlightTargetPractice.zip"&gt;SilverlightTargetPractice.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-1581876253332444395?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/1581876253332444395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/04/target-practice-live-demo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1581876253332444395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1581876253332444395'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/04/target-practice-live-demo.html' title='Target Practice Live Demo'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2548214518115647344</id><published>2010-03-01T21:58:00.000-08:00</published><updated>2010-03-03T13:25:50.281-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Book Review'/><title type='text'>Book Review: ASP.NET MVC Framework Unleashed</title><content type='html'>I just finished reading &lt;em&gt;ASP.NET MVC Framework Unleased&lt;/em&gt; by Stephen Walther.&amp;nbsp; It was an extremely fast read: I finished it in a little under two weeks.&amp;nbsp; Unfortunately, I was able to finish it so quickly because it contained very little information.&amp;nbsp; I was rather disappointed by the content.&amp;nbsp; I really don't like giving bad reviews, but I feel like I should get my thoughts down for other folks who may be interested in this topic.&amp;nbsp; Please note, this is a review of the book itself, not the underlying ASP.NET MVC technology.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;strong&gt;Beginner, Intermediate, or Advanced?&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;My biggest problem with &lt;i&gt;Unleashed&lt;/i&gt; is that it cannot decide what level it is targeted at.&amp;nbsp; The cover lists it as "User Level: Intermediate-Advanced," but the actual content seems to&amp;nbsp;jump from one level to another.&amp;nbsp; For example, there are step-by-step instructions on configuring and using the ASP.NET Membership Database (ASPNETDB.mdf).&amp;nbsp; I would consider this to be "beginner" level content.&amp;nbsp;&amp;nbsp;For&amp;nbsp;the majority of real-world applications, you will not use the ASPNETDB.mdf database for your user authentication / authorization, instead going for&amp;nbsp;a more robust security model&amp;nbsp;such as&amp;nbsp;implementing&amp;nbsp;a custom MembershipProvider.&amp;nbsp; This is not covered, however.&lt;br /&gt;&lt;br /&gt;But the&amp;nbsp;text does not qualify as Intermediate or Advanced as there is very little actual content.&amp;nbsp; The majority of the book is code samples.&amp;nbsp; Code samples are generally a good thing, but the code samples here are full-files.&amp;nbsp; This means that when looking at the various elements (such as Views and Controllers), you end up seeing the same "boiler-plate" code over and over again.&amp;nbsp; Many times there are only a few unique lines of code in a 30 line listing.&amp;nbsp; In addition, descriptions of the code samples are limited to a paragraph or two with no in-depth&amp;nbsp;description&amp;nbsp;of the concepts at hand.&amp;nbsp; This is combined with listings in both C# and VB (again, not necessarily a bad thing).&amp;nbsp; I often felt like I was "skimming" a 30 page chapter in just 10 minutes or so due to the use of code samples and lack of description.&lt;br /&gt;&lt;br /&gt;As a final example, there are 2 chapters devoted to AJAX and jQuery. &amp;nbsp;In the introduction to the book, the author assumes that the reader is familiar with HTML and .NET (either C# or VB). &amp;nbsp;However, it does not mention AJAX or jQuery as pre-requisites. &amp;nbsp;AJAX is used much differently in ASP.NET MVC than it is in Web Forms, yet there is no discussion of those differences. &amp;nbsp;There is just a handful of samples with little explanation.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Lack of Focus&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Another problem&amp;nbsp;is the lack&amp;nbsp;of focus.&amp;nbsp; ASP.NET MVC has many unique features, but many of the concepts are shared with&amp;nbsp;ASP.NET Web Forms&amp;nbsp;and the .NET framework at large.&amp;nbsp; I wanted the book to focus on the concepts that differ from non-ASP.NET MVC applications, but there was&amp;nbsp;a lot of&amp;nbsp;overlap.&lt;br /&gt;&lt;br /&gt;To expand on the example above (the Membership database), the security concepts (users, roles, principles, etc.) are the same as ASP.NET Web Forms applications, but there were several large sections dedicated to authentication.&amp;nbsp; And as noted above, this was only at the "beginner" level and did not touch on intermediate or advanced topics.&lt;br /&gt;&lt;br /&gt;As another example, &lt;i&gt;Unleashed&lt;/i&gt; spends a lot of time with the Entity Framework.&amp;nbsp; There are step-by-step instructions on creating a SQL Express database and setting up Entity Framework entities.&amp;nbsp; In addition, it also spends a bit of time talking about the Repository pattern&amp;nbsp;and Service layers of the application.&amp;nbsp; These all related to the "M" (Model) of MVC.&amp;nbsp; But the point of the "M" is that you can implement your model in an infinite number of ways.&amp;nbsp; Again, this may be appropriate for a "beginner" level book, but it should go beyond merely mentioning other options if it is trying to be something more.&lt;br /&gt;&lt;br /&gt;Ironically, I think that the topic covered best by this book is Test Driven Development (TDD).&amp;nbsp; Throughout the text, there is a focus on the "Red / Green / Refactor" methodology of TDD.&amp;nbsp; And the final part of the book (6 chapters on building a sample application) is a very good walkthrough of using the test-first method to fulfill the use cases. &amp;nbsp;Had this book been called &lt;i&gt;Test Driven Development with ASP.NET MVC&lt;/i&gt;, I would probably give this book a much better review.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Summary&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Ultimately, the only reason that I was able to follow this book is because I went through ASP.NET MVC training. &amp;nbsp;But the reason that I purchased the book was so that I could have a reference with more detail.&amp;nbsp; As an example, I was looking for details on HTML Helpers, both the helpers "in the box" and custom helpers.&amp;nbsp; The book has a few mentions of the existing helpers, but does not go into any detail on the options and parameters available.&amp;nbsp; As for creating custom helpers, there is an example of it, but nothing much beyond the sample code.&lt;br /&gt;&lt;br /&gt;I really don't like giving bad reviews.&amp;nbsp; I realize that putting any technical book together is a lot of work.&amp;nbsp; However, technical books are also my life-blood.&amp;nbsp; They are my primary source of in-depth learning.&amp;nbsp; In addition, they are quite expensive.&amp;nbsp; I do have enough information to complete my project (which was the primary goal of training + book), but I'm still looking for a good reference book.&amp;nbsp; Since ASP.NET MVC version 2 is just around the corner (releasing with .NET 4.0 in April), I'll probably hold out before purchasing another.&lt;br /&gt;&lt;br /&gt;In working with ASP.NET MVC, I'm becoming a fan of it.&amp;nbsp; So, I'll be posting more about the technology topic in the future.&amp;nbsp; I'll also keep you informed of other useful resources that I run across.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2548214518115647344?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2548214518115647344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/03/book-review-aspnet-mvc-framework.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2548214518115647344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2548214518115647344'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/03/book-review-aspnet-mvc-framework.html' title='Book Review: ASP.NET MVC Framework Unleashed'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-8185959819051500271</id><published>2010-02-23T21:34:00.000-08:00</published><updated>2010-03-01T09:11:39.564-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>New to Me: ASP.NET MVC</title><content type='html'>&lt;span style="font-size: large;"&gt;&lt;b&gt;ASP.NET MVC was New 18 Months Ago&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;I first heard about ASP.NET MVC in October 2008 (at the VSLive! conference).&amp;nbsp; Scott Hanselman gave a keynote that presented an overview and announced the beta release.&amp;nbsp; At that point, it looked interesting, but with all of the new technologies that have been thrown at us over the last several years, I couldn't devote any time to look into it.&amp;nbsp; Plus, I was comfortable with WebForms, having spent the previous 3 years developing fairly significant web apps.&lt;br /&gt;&lt;br /&gt;So, here we are a year and a half later.&amp;nbsp; I was struggling with a project at work.&amp;nbsp; I knew that I could accomplish the task with WebForms, but all of my UI designs that I had worked through on the whiteboard seemed to come out as a mess.&amp;nbsp; I had a nagging feeling that ASP.NET MVC was the solution to this problem.&amp;nbsp; I took some time to look into it some more, and it turns out that it was the right direction.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Why ASP.NET MVC was the Answer&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;My main problem is that I needed to present data to the user in a different format depending on the record type.&amp;nbsp; And I wouldn't know the record type until run time.&amp;nbsp; ASP.NET WebForms is a "page first" model.&amp;nbsp; This means that the user requests a particular page (through a URL).&amp;nbsp; The page is then processed on the server which then presents the output to the user.&amp;nbsp; ASP.NET MVC is an "action first" model.&amp;nbsp; This means that instead of requesting a physical page, the user requests an action (also through a URL).&amp;nbsp; This action is processed by a Controller.&amp;nbsp; In my situation, the Controller can instantiate the Model (from my business layer) and then, based on the record type, can present the specific View (aspx page) that is appropriate.&lt;br /&gt;&lt;br /&gt;So, I've taken a crash course in ASP.NET MVC.&amp;nbsp; After going through some on-line training and working through a simple test app, I'm convinced that this is the right solution for this particular project.&amp;nbsp; The design is much cleaner and will be easier to maintain.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Resources &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;I was fortunate enough to win a 1-year subscription to the &lt;a href="http://www.pluralsight.com/main/"&gt;Pluralsight&lt;/a&gt; OnDemand! library.&amp;nbsp; In the library is a 10 hour on-line course for ASP.NET MVC, and I took a couple of days last week to go through it.&amp;nbsp; This was an excellent resource.&amp;nbsp; (If you are interested in trying Pluralsight OnDemand! yourself, just stop by the website; they offer 7-day trial subscriptions if you drop them a note.)&lt;br /&gt;&lt;br /&gt;In addition, I picked up "ASP.NET MVC Framework Unleashed" by Stephen Walther as a printed reference.&amp;nbsp; I'm still working my way through the book, but I've found a lot of useful information so far.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;More to Come&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Stay tuned for more to come.&amp;nbsp; My project at work is still in progress.&amp;nbsp; I'll have a lot of learnings from it (as I do with most of my projects).&amp;nbsp; When I run across interesting items, good tips, and pitfalls, I'll be sure to post them here.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-8185959819051500271?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/8185959819051500271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/02/new-to-me-aspnet-mvc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8185959819051500271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8185959819051500271'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/02/new-to-me-aspnet-mvc.html' title='New to Me: ASP.NET MVC'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7158793653730087850</id><published>2010-02-17T09:23:00.000-08:00</published><updated>2010-03-03T09:28:41.001-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Jeremy on .NET Rocks! (sort of)</title><content type='html'>Okay, so now that I have your attention, I wasn't really on &lt;a href="http://www.dotnetrocks.com/"&gt;.NET Rocks!&lt;/a&gt;.&amp;nbsp; But Carl and Richard did read my e-mail on show #525.&amp;nbsp; Here's a link (if you're curious): &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=525"&gt;.NET Rocks! Show #525&lt;/a&gt;.&amp;nbsp; You can skip ahead to about 4 minutes in.&lt;br /&gt;&lt;br /&gt;And BTW, they are sending me a hoody.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7158793653730087850?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7158793653730087850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/02/jeremy-on-net-rocks-sort-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7158793653730087850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7158793653730087850'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/02/jeremy-on-net-rocks-sort-of.html' title='Jeremy on .NET Rocks! (sort of)'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2635194257743962849</id><published>2010-02-13T22:06:00.000-08:00</published><updated>2010-02-13T22:06:37.168-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Lambda Expression'/><title type='text'>Quick Byte: Statement Lambdas</title><content type='html'>&lt;strong&gt;&lt;span style="font-size: large;"&gt;Overview&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;The first time I came across a lambda expression, I was perplexed.&amp;nbsp; I could tell that something important was going on, but I got stuck on the new syntax.&amp;nbsp; As I studied them some more, I had an "aha" moment, and it all clicked into place.&amp;nbsp; This is a brief runthrough of that process with statement lambdas.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Get It Here&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;You can get the walkthrough (just a short 3-page one) and sample code here: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Direct Links:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/StatementLambdas.pdf"&gt;PDF Walkthrough&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/StatementLambdas.zip"&gt;Code Download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let me know what you think.&amp;nbsp; If you find this useful (or not), drop me a note at &lt;a href="mailto:feedback@jeremybytes.com"&gt;feedback@jeremybytes.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2635194257743962849?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2635194257743962849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/02/quick-byte-statement-lambdas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2635194257743962849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2635194257743962849'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/02/quick-byte-statement-lambdas.html' title='Quick Byte: Statement Lambdas'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-5595514421625596407</id><published>2010-01-31T18:01:00.000-08:00</published><updated>2010-01-31T18:02:06.652-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>SoCal Code Camp</title><content type='html'>&lt;b&gt;&lt;span style="font-size: large;"&gt;Thank you!&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A big thank you to everyone who attended my sessions at the SoCal Code Camp.&amp;nbsp; I had a great time, and I hope that all of you did, too.&lt;br /&gt;&lt;br /&gt;As a reminder, for all of my sessions: the slides, code samples, and walkthroughs are available here: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Drop me a note if you had a chance to attend.&amp;nbsp; I'd love to hear what you thought.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-5595514421625596407?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/5595514421625596407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/01/socal-code-camp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5595514421625596407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5595514421625596407'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/01/socal-code-camp.html' title='SoCal Code Camp'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7685002935426236141</id><published>2010-01-10T15:08:00.000-08:00</published><updated>2010-01-10T15:10:14.450-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><title type='text'>Introduction to XAML with WPF</title><content type='html'>&lt;em&gt;(Editor's note: I will be presenting this topic at the SoCal Code Camp Jan 30 &amp;amp; 31, 2010.)&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Overview&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Understanding XAML (eXtensible Application Markup Language) is a key to creating the latest .NET user experiences in WPF and Silverlight. We will introduce the basic concepts around XAML and take a look at various features such as namespaces, elements, properties, events, attached properties and some basic layout. We’ll create a simple WPF application that covers these fundamentals. Although you will probably end up doing most of your UI design with a drag-and-drop tool such as Expression Blend, knowing the internals gives you a leg up in making the final tweaks to ensure an excellent user experience.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Get It Here&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;As mentioned in a previous post, the demos are now available in PDF form here: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Direct Links:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/IntroductonToXAML.pdf"&gt;PDF Walkthrough&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/IntroductionToXAML.zip"&gt;Code Download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7685002935426236141?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7685002935426236141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/01/introduction-to-xaml-with-wpf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7685002935426236141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7685002935426236141'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/01/introduction-to-xaml-with-wpf.html' title='Introduction to XAML with WPF'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2991208589625335288</id><published>2010-01-04T19:27:00.000-08:00</published><updated>2010-01-16T20:30:32.286-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Value Converter'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight 3'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Template'/><title type='text'>Introduction to Data Templates and Value Converters in Silverlight 3</title><content type='html'>&lt;em&gt;(Editor's note: I will be presenting this topic at the SoCal Code Camp Jan 30 &amp;amp; 31, 2010.)&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: 130%;"&gt;Overview&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Business applications are all about data, and laying out that data is critical to creating a good user experience. Fortunately, Silverlight 3 has several tools, including Data Templates and Value Converters, that make this easier for the business application developer to manage. Today, we'll take a look at consuming a WCF service and creating the layout of the data. By the time we're done, you should have a good understanding of the basics of Data Templates and Value Converters.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size: 130%;"&gt;Get It Here&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;As mentioned in a previous post, the demos are now available in PDF form here: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here's some direct links:&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/DataTemplatesAndConverters.pdf"&gt;PDF Walkthough&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.jeremybytes.com/Downloads/DataTemplatesAndConverters.zip"&gt;Code Download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2991208589625335288?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2991208589625335288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/01/introduction-to-data-templates-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2991208589625335288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2991208589625335288'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/01/introduction-to-data-templates-and.html' title='Introduction to Data Templates and Value Converters in Silverlight 3'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7559403903529889149</id><published>2010-01-01T19:20:00.000-08:00</published><updated>2010-02-14T21:04:35.212-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>More Demos Coming</title><content type='html'>&lt;b&gt;&lt;span style="font-size: 130%;"&gt;A New Direction&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Okay, so I've posted several demo articles here so far. The unfortunate thing is that the blogging tool I've been using is not the easiest thing to use for these demos. One of the primary shortcomings is the inability to have code samples that can easily be copy/pasted. With this in mind, I've decided to post upcoming demos as PDFs (along with downloadable code samples). I think this should improve usability for me and my readers.&lt;br /&gt;&lt;br /&gt;You can get the PDFs and code samples here: &lt;a href="http://www.jeremybytes.com/Demos.aspx"&gt;http://www.jeremybytes.com/Demos.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you miss the HTML walkthroughs and really want to see them again, just post me a message at &lt;a href="mailto:feedback@jeremybytes.com"&gt;feedback@jeremybytes.com&lt;/a&gt;, and I'll see what I can do for future articles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7559403903529889149?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7559403903529889149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2010/01/more-demos-coming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7559403903529889149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7559403903529889149'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2010/01/more-demos-coming.html' title='More Demos Coming'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-237584742797745636</id><published>2009-12-31T16:25:00.000-08:00</published><updated>2010-01-01T09:52:44.504-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Threading'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='BackgroundWorker'/><title type='text'>Introduction to the Background Worker Component in WPF</title><content type='html'>&lt;em&gt;(Editor's Note: I will be presenting this topic at the SoCal Code Camp Jan 30 &amp;amp; 31, 2010.)&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We've all experienced it: the application UI that hangs. You get the dreaded "Not Responding" message, and you have to decide if you should wait it out or simply kill the process. If you have long-running processes in your application, you should consider putting them on a separate thread so that your UI remains responsive. However, threading is a daunting subject. We've heard horror stories about race conditions and deadlocks, and needing to use the thread dispatcher to communicate between background threads and UI threads. At this point, it sounds like a subject best left to the experts.&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;The Solution&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Fortunately, the .NET framework provides a simple way to get started in threading with the BackgroundWorker component. This wraps much of the complexity between your background thread and your UI thread without doing any special coding. You can use this component with WinForms and WPF applications. We'll be using it with WPF here.&lt;br /&gt;&lt;br /&gt;The BackgroundWorker offers several features which include spawning a background thread, the ability to cancel the background process before it has completed, and the chance to report the progress back to your UI. We'll be looking at all of these features.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;The Set Up&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;We'll start with a fairly simple WPF application that has a long-running process that blocks the application until it has completed. You can download the source code for the application here: &lt;a href="http://www.jeremybytes.com/Downloads.aspx"&gt;http://www.jeremybytes.com/Downloads.aspx&lt;/a&gt;. The download includes the starter application and the completed code. The starter application includes the following.&lt;br /&gt;&lt;br /&gt;1. A Simple WPF form:&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1B5FRwKwI/AAAAAAAAAQ8/ljDgPj5ZO9E/s1600-h/1-StarterApp.PNG"&gt;&lt;img style="WIDTH: 300px; HEIGHT: 250px" id="BLOGGER_PHOTO_ID_5421561975348931330" border="0" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1B5FRwKwI/AAAAAAAAAQ8/ljDgPj5ZO9E/s400/1-StarterApp.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can find the XAML for this in the download. It consists of 2 Text Boxes (Iterations and Output), a Progress Bar, and 2 Buttons (Start and Cancel).&lt;br /&gt;&lt;br /&gt;2. A long-running process (in the code-behind the form):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1B1BGG0WI/AAAAAAAAAQs/5athM5WZhao/s1600-h/3-LongRunningProcess.PNG"&gt;&lt;img style="WIDTH: 359px; HEIGHT: 244px" id="BLOGGER_PHOTO_ID_5421561905506865506" border="0" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1B1BGG0WI/AAAAAAAAAQs/5athM5WZhao/s400/3-LongRunningProcess.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can see that we're using the famously slow process Sleep(100) that loops based on the parameter value.&lt;br /&gt;&lt;br /&gt;3. Event-handlers for the buttons (in the code-behind):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1B0-HVNoI/AAAAAAAAAQk/tSdX_O-eXys/s1600-h/4-ButtonClickEvents.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 216px" id="BLOGGER_PHOTO_ID_5421561904706696834" border="0" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1B0-HVNoI/AAAAAAAAAQk/tSdX_O-eXys/s400/4-ButtonClickEvents.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When you run the application and click the Start button, you'll see that the application hangs until the process is finished. If you try to move or resize the window while the process is running, nothing will happen for several seconds. And you'll see the "Not Responding" message if you look in Task Manager:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/Sz1B1VC-2SI/AAAAAAAAAQ0/4lic8KQxLKk/s1600-h/2-NotResponding.PNG"&gt;&lt;img style="WIDTH: 359px; HEIGHT: 400px" id="BLOGGER_PHOTO_ID_5421561910862469410" border="0" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/Sz1B1VC-2SI/AAAAAAAAAQ0/4lic8KQxLKk/s400/2-NotResponding.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When the process is completed, you will see the value from the Iterations box mirrored in the Output box. This is simply a confirmation that the process completed. You can try this with different values. Since we are using a Sleep(100), a value of 50 iterations will translate into a 5 second process; a value of 100 is 10 seconds, and so on. Just as a side note, I chose a value of 1/10th of a second for the Sleep rather than the usual 1 second so that we will have a smoother progress update later on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Adding the BackgroundWorker&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The BackgroundWorker is a non-visual component. In the WinForms world, this would mean that we could just drag the BackgroundWorker from the Tool Box onto the Form, and it would show up as a non-visual component. In WPF, things are a little bit different. We need to add the BackgroundWorker as a window resource that we can reference throughout our code. Here's the steps:&lt;br /&gt;&lt;br /&gt;1. Add the System.ComponentModel namespace to the XAML. We do this in the markup for the Window. The good news is that Visual Studio IntelliSense helps you out quite a bit with this. We'll give the namespace a "cm" alias so we can reference it easily. Here's the Window markup with the namespace included:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1B0Y0XzbI/AAAAAAAAAQc/pMbdBAdu9BI/s1600-h/5-XAMLNamespace.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 63px" id="BLOGGER_PHOTO_ID_5421561894695062962" border="0" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1B0Y0XzbI/AAAAAAAAAQc/pMbdBAdu9BI/s400/5-XAMLNamespace.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2. Add a BackgroundWorker as a Window Resource.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/Sz1B0LG_O2I/AAAAAAAAAQU/Kci3XavMkdc/s1600-h/6-AddingResource.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 48px" id="BLOGGER_PHOTO_ID_5421561891015048034" border="0" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/Sz1B0LG_O2I/AAAAAAAAAQU/Kci3XavMkdc/s400/6-AddingResource.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Hooking Things Up&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;To use the basic functionality of the BackgroundWorker, we need to do a couple of things. First, we need to hook up two event handlers: DoWork and RunWorkerCompleted. These events are much like they sound. To kick off the background process we call the RunWorkerAsync method of the BackgroundWorker and pass any parameters needed. This fires the DoWork event (which is where we'll put our long-running process). The RunWorkerCompleted event fires after that process is done. At that point, we can update our UI and do clean up (if required).&lt;br /&gt;&lt;br /&gt;So, let's put our process into the background. We'll start by creating the handlers for the events mentioned above. As a reminder, Visual Studio IntelliSense helps us out quite a bit with this. In our BackgroundWorker markup that we created above, just type "DoWork=" and you'll get the option for "New Event Handler&lt;new&gt;". This will create the stub and give the handler a name based on our component. We'll do the same for "RunWorkerCompleted" and end up with the following XAML: &lt;/new&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1BrrCsvvI/AAAAAAAAAQM/8qK05wkePik/s1600-h/7-InitialEventHandlers.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 50px" id="BLOGGER_PHOTO_ID_5421561744968171250" border="0" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1BrrCsvvI/AAAAAAAAAQM/8qK05wkePik/s400/7-InitialEventHandlers.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now we'll flip over to the code-behind and implement these handlers. Let's look at the code, then we'll talk through it. Note, in addition to the code below, I have also added a "using System.ComponentModel;" to make things a little less verbose:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/Sz1BrensqbI/AAAAAAAAAQE/Ua7fDXSM_3A/s1600-h/8-HandlerImplementation.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 219px" id="BLOGGER_PHOTO_ID_5421561741633694130" border="0" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/Sz1BrensqbI/AAAAAAAAAQE/Ua7fDXSM_3A/s400/8-HandlerImplementation.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First, you'll see that our DoWork event calls the DoSlowProcess method (our long-running process). You'll note that we are getting an integer argument from the DoWorkEventArgs (we'll see how this gets passed in just a minute). The e.Argument is of type Object, so we have to cast it to the integer type that our method is expecting. Next, you'll note that we're passing the result back to the DoWorkEventArgs in e.Result. This will be used in the next handler.&lt;br /&gt;&lt;br /&gt;The RunWorkerCompleted event fires after the long-running process is complete. You can see that the first thing we do is check to see if an error occurred. If not, then we'll go ahead and populate the output box with the result of our method. The e.Result here is actually the same e.Result from the DoWork event. In our case, the DoSlowProcess returns an integer that we populate in the output. In addition, you can see that we are enabling and disabling the buttons as appropriate.&lt;br /&gt;&lt;br /&gt;The important thing is what you &lt;strong&gt;don't&lt;/strong&gt; see. Notice that our completed handler is manipulating our UI elements without any use of the Dispatcher or Invoke methods that you need to do if you are handling the threading on your own. Instead, we just reference the elements on the UI thread directly. The BackgroundWorker takes care of all of the complexity on the back end.&lt;br /&gt;&lt;br /&gt;Finally, we need to kick off the DoWork event in our Start Button handler. In order to do this, we need a reference to the BackgroundWorker component in our window. The problem is that it is simply a resource right now. The first task is to get a reference to it. We'll put this code at the top of our Window class and modify the constructor:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/Sz1BrHLXyYI/AAAAAAAAAP8/5ADU0MLla20/s1600-h/9-ResourceReference.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 105px" id="BLOGGER_PHOTO_ID_5421561735340870018" border="0" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/Sz1BrHLXyYI/AAAAAAAAAP8/5ADU0MLla20/s400/9-ResourceReference.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this code, you see that we create a private variable to reference the BackgroundWorker component. Then in the constructor, we pull the component out of the resources by using the FindResource method. Now we can use the component in our code.&lt;br /&gt;&lt;br /&gt;Here's our updated code in the Start Button Click event handler:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/Sz1Bq-QqLmI/AAAAAAAAAP0/ASQFNmR8H8w/s1600-h/10-StartButtonClick.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 146px" id="BLOGGER_PHOTO_ID_5421561732947127906" border="0" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/Sz1Bq-QqLmI/AAAAAAAAAP0/ASQFNmR8H8w/s400/10-StartButtonClick.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You'll notice that instead of calling the DoSlowProcess directly, we are now calling the RunWorkerAsync method of the BackgroundWorker. This method takes an optional object parameter. In our case, we will use this to pass the number of iterations through. This is the value that shows up in the e.Argument of the DoWork handler that we saw above.&lt;br /&gt;&lt;br /&gt;The next thing we do is update the button states appropriately. Since the Cancel button is not yet implemented, it won't have too much effect. But we'll get to that in a bit.&lt;br /&gt;&lt;br /&gt;Finally, note that we are clearing the output text. Remember that since we are running the process in the background, our UI still remains responsive. We want to clear out the output while the process is running, and then populate it agian after the process is complete. This is handled by the RunWorkerCompleted event that we saw above.&lt;br /&gt;&lt;br /&gt;Now we have a fully-functional application with a background process. If you run the application now, you'll notice different behavior from what we saw before. After you click the Start button, the UI remains responsive: you can move and resize the window, type in the boxes, or whatever. When the process if finished, the output box is updated.&lt;br /&gt;&lt;br /&gt;But we're not done yet. We still need to look at the Cancel and Progress functions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Updating Progress&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Next we'll look at reporting progress back from our long-running process. One thing to keep in mind if you want to have a progress bar in your UI: you will need to come up with some type of metric for the percent complete. For example, I have used the BackgroundWorker for long-running SQL queries. In this case, I was unable to report percentage because I had no idea exactly how long the process would take. In our sample here, we can use some fairly simple math to report the percentage completed.&lt;br /&gt;&lt;br /&gt;The BackgroundWorker has a property we need to set (WorkerReportsProgress) and an event handler (ProgressChanged). These are fairly straight forward to implement. But here's where things get a little complicated. We need to update the progress in our DoSlowProcess method. This means that we need a reference to the BackgroundWorker.&lt;br /&gt;&lt;br /&gt;Let's start with the easy parts. First the updated XAML:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1BqnHIPuI/AAAAAAAAAPs/hq6HiLGV3ME/s1600-h/11-XAMLProgress.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 72px" id="BLOGGER_PHOTO_ID_5421561726733139682" border="0" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1BqnHIPuI/AAAAAAAAAPs/hq6HiLGV3ME/s400/11-XAMLProgress.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here we just set the WorkerReportsProgress to True (the default is False) and add the stub for the ProgressChanged event handler. As we did above, we'll just let Visual Studio create a New Event Handler &lt;new&gt;for us.&lt;br /&gt;&lt;/new&gt;&lt;br /&gt;To implement the event handler, we'll just set the value of the progress in our UI:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1BhTSnSDI/AAAAAAAAAPk/YK6oEJ3cqhg/s1600-h/12-ProgressChangedEvent.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 69px" id="BLOGGER_PHOTO_ID_5421561566793779250" border="0" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1BhTSnSDI/AAAAAAAAAPk/YK6oEJ3cqhg/s400/12-ProgressChangedEvent.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now we'll make updates to some of our existing code. First, the DoSlowProcess method:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/Sz1Bg1CY3QI/AAAAAAAAAPc/GVTGRfrqd0g/s1600-h/13-SlowProcessWithProgress.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 307px" id="BLOGGER_PHOTO_ID_5421561558672661762" border="0" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/Sz1Bg1CY3QI/AAAAAAAAAPc/GVTGRfrqd0g/s400/13-SlowProcessWithProgress.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We've added both BackgroundWorker and DoWorkEventArgs parameters to the DoSlowProcess method. In order to update the progress, we'll add some code to each iteration of the loop. First, we check to make sure that the BackgroundWorker parameter was populated; then we check the WorkerReportsProgress property to see if the BackgroundWorker reports progress. If false, then we'll skip the code. If true, then we calculate the percentage and call the BackgroundWorker.ReportProgress method. This will fire the ProgressChanged event that we implemented above.&lt;br /&gt;&lt;br /&gt;Now, since we've added additional parameters to DoSlowProcess, we'll need to update the method call. As a reminder, this was in the DoWork event. Here's the updated code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1Bgq2WlzI/AAAAAAAAAPU/nHr4ttcEsyY/s1600-h/14-DoWorkWithProgress.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 62px" id="BLOGGER_PHOTO_ID_5421561555937826610" border="0" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1Bgq2WlzI/AAAAAAAAAPU/nHr4ttcEsyY/s400/14-DoWorkWithProgress.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We'll just cast the sender to a BackgroundWorker and pass it on through. We'll just pass the DoWorkEventArgs parameter through as well.&lt;br /&gt;&lt;br /&gt;Finally, we'll add a line of code to the RunWorkerCompleted event to zero out the progress bar after it has completed:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1Bge7FYhI/AAAAAAAAAPM/5CYm_EDxKho/s1600-h/15-CompletedWithProgress.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 195px" id="BLOGGER_PHOTO_ID_5421561552736444946" border="0" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1Bge7FYhI/AAAAAAAAAPM/5CYm_EDxKho/s400/15-CompletedWithProgress.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The reason for this is if you are using Windows Vista or Windows 7, the progress bar continues to animate even after it is as 100%. This makes it difficult to tell that the progress is complete. So, we'll just set it back to 0 after it's done.&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/Sz1BT8J-XjI/AAAAAAAAAOk/Ng6mRWPvqLQ/s1600-h/20-FinalOutput.PNG"&gt;&lt;img style="WIDTH: 300px; HEIGHT: 250px" id="BLOGGER_PHOTO_ID_5421561337245228594" border="0" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/Sz1BT8J-XjI/AAAAAAAAAOk/Ng6mRWPvqLQ/s400/20-FinalOutput.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Now, if we run the application again, we'll see that we have a functional progress bar. The last step is to add cancellation.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Canceling the Background Process&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;Before implementing cancellation in your application, you will need to take a few things into consideration. First, when you cancel a BackgroundWorker process, there is no event that fires, and the process does not stop immediately. Instead, a cancellation flag gets set on the BackgroundWorker. It is up to your long-running process to check for this flag and to stop running if necessary. In my example above with the long-running SQL query, I could not implement cancellation because there was no "iteration" in my process -- it was simply waiting for the query to return.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;In our example here, since we are using a loop, we have a perfect place to check for cancellation and stop our process. Here's an overview of the steps we'll take, then we'll look at each in more detail.&lt;/div&gt;&lt;br /&gt;First, we need to set a property on the BackgroundWorker ("WorkerSupportsCancellation"). Then we'll tell the component we want to cancel in the Cancel Button event handler. Next we'll add the cancellation code to our DoSlowProcess method. And finally, we'll make a few changes to the RunWorkerCompleted event handler to behave differently if the process was canceled.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;First, the XAML:&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1BgLKWrJI/AAAAAAAAAPE/tJpg6-fHD1I/s1600-h/16-XAMLCancel.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 83px" id="BLOGGER_PHOTO_ID_5421561547431783570" border="0" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1BgLKWrJI/AAAAAAAAAPE/tJpg6-fHD1I/s400/16-XAMLCancel.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Next, the Cancel Button event handler:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1BUzCFeiI/AAAAAAAAAO8/sqcfMAAoOMU/s1600-h/17-CancelHandler.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 52px" id="BLOGGER_PHOTO_ID_5421561351976090146" border="0" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1BUzCFeiI/AAAAAAAAAO8/sqcfMAAoOMU/s400/17-CancelHandler.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;You can see that we're simply calling the CancelAsync method of the BackgroundWorker.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Next, add the cancellation logic to the DoSlowProcess:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1BUY9r4OI/AAAAAAAAAO0/iXwXuCqpN3c/s1600-h/18-SlowProcessCancel.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 373px" id="BLOGGER_PHOTO_ID_5421561344978313442" border="0" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1BUY9r4OI/AAAAAAAAAO0/iXwXuCqpN3c/s400/18-SlowProcessCancel.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;You can see that we added another conditional to check CancellationPending. If so, then we'll set the e.Cancel property of the DoWorkEventArgs and return from our method.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;And finally, the RunWorkerCompleted:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;(click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1BUNoEMdI/AAAAAAAAAOs/QqA41gDNV2Q/s1600-h/19-CompletedWithCancel.PNG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 258px" id="BLOGGER_PHOTO_ID_5421561341934842322" border="0" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1BUNoEMdI/AAAAAAAAAOs/QqA41gDNV2Q/s400/19-CompletedWithCancel.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here, you can see that we are checking the e.Cancelled property of the EventArgs. If it's true, then we'll put "Canceled" in the output box. One thing you'll note: we are not resetting the progress bar in event of cancellation. This is so that if you stop the process, you can still see how far it got before the cancellation.&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1BTqa8BTI/AAAAAAAAAOc/jP5vElXYpk8/s1600-h/21-Canceled.PNG"&gt;&lt;img style="WIDTH: 300px; HEIGHT: 250px" id="BLOGGER_PHOTO_ID_5421561332484539698" border="0" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/Sz1BTqa8BTI/AAAAAAAAAOc/jP5vElXYpk8/s400/21-Canceled.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now, when we run the application, we'll see that we have a long-running process that runs in the background (keeping the UI responsive), an updating progress bar, and a working Cancel button.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Wrap Up&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;The BackgroundWorker component allows us to put long-running processes onto a background thread without the usual complexities of threading. We have seen how we can get progress updates that we can show in our UI as well as how to cancel a process before it has completed. In addition, we've seen that even when updating our UI, we don't have to worry about communicating across threads. It is all handled for us in the component.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Probably the best thing about the BackgroundWorker is that it allows us to get our feet wet in the world of threading in an easy and relatively safe way. Think about this the next time you come across an application that is "Not Responding". And do what you can to keep your UIs responsive for your users.&lt;/div&gt;&lt;br /&gt;Happy coding!&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-237584742797745636?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/237584742797745636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/12/introduction-to-background-worker.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/237584742797745636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/237584742797745636'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/12/introduction-to-background-worker.html' title='Introduction to the Background Worker Component in WPF'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_tXOq_FsazuI/Sz1B5FRwKwI/AAAAAAAAAQ8/ljDgPj5ZO9E/s72-c/1-StarterApp.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-8298907680618040473</id><published>2009-12-27T17:07:00.000-08:00</published><updated>2009-12-27T17:12:07.339-08:00</updated><title type='text'>Where's Jeremy?</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;strong&gt;I'm Still Here&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, it's been a while since I've posted anything. But I've still been working. Coming up at the end of January, I will be doing some presentations as the &lt;a href="http://www.socalcodecamp.com/"&gt;SoCal Code Camp&lt;/a&gt;. The good news is that it's forcing me to put together another 3-4 demos. So, if you check back over the next month, you should see them pop up.&lt;br /&gt;&lt;br /&gt;In addition, I've got a website where you can download the sample code for all of the demos that I've presented so far. It's at &lt;a href="http://www.jeremybytes.com/"&gt;http://www.jeremybytes.com/&lt;/a&gt;. Just check out the Downloads section. (I'll be adding links to my various blog posts as well).&lt;br /&gt;&lt;br /&gt;Lots of exciting things coming up.&lt;br /&gt;&lt;br /&gt;Happy New Year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-8298907680618040473?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/8298907680618040473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/12/im-still-here.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8298907680618040473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8298907680618040473'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/12/im-still-here.html' title='Where&apos;s Jeremy?'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-9062473206757517995</id><published>2009-09-04T09:57:00.001-07:00</published><updated>2009-09-05T12:10:12.417-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight 3'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>Target Practice - Silverlight 3 / XAML Sample</title><content type='html'>XAML has intrigued me ever since I took a close look at it. In a previous post, I created an entire &lt;a href="http://jeremybytes.blogspot.com/2009/03/wpf-xaml-sample.html"&gt;WPF application using only XAML&lt;/a&gt; (it's trivial, yet functional). When I got started with Silverlight 2, I wanted to replicate that application. Unfortunately, there were limitations to Silverlight 2 (such as a lack of triggers) that kept me from implementing it. I could have built the same application, but it would have required some code-behind to handle the animation.&lt;br /&gt;&lt;br /&gt;The good new is that Silverlight 3 has additional support that allows us to replicate the XAML-only version of the application. It does vary a little bit from the WPF version, so even if you've looked through the previous post, you're likely to learn something new. I'll point out the differences as we come across them.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Scenario&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;We'll be creating a simple shooting gallery-type application. I call it "Target Practice" since it will require some more work to turn it into an actual game. In the final version, we will have a 3 x 3 grid of targets. Each of these is clickable adn will result in a "hit" animation. After 3 seconds, the target will reset to its previous state -- all inside the XAML. You can scroll down to the bottom to see the finished product.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Step 1 - Application Set-Up&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;We'll start by creating a new Silverlight 3 application. You'll need Visual Studio 2008, plus the Silverlight 3 bits (start here if you need them: &lt;a href="http://silverlight.net/GetStarted/"&gt;http://silverlight.net/GetStarted/&lt;/a&gt;). Create a new project by selecting File -&gt; New -&gt; Project. From there, choose the "Silverlight" category under "Visual C#" and then select "Silverlight Application". I named my application "SilverlightTargetPractice".&lt;br /&gt;&lt;br /&gt;You'll be asked if you want to create a web application to host the project. Go ahead and leave the defaults (create a new ASP.NET Web Site). This will give you 2 projects: "SilverlightTargetPractice" is your Silverlight application, and "SilverlightTargetPractice.Web" is the hosting web site. Whenever you run the project, you will want to run the web application.&lt;br /&gt;&lt;br /&gt;In the Silverlight project, you will find the "MainPage.xaml" file. That's where we are going to start. Open up the xaml file, and you'll see the xaml editor. Note: There is no Silverlight 3 designer support in Visual Studio 2008; for that, you'll need Expression Blend 3. You can see my notes on this in a &lt;a href="http://jeremybytes.blogspot.com/2009/08/silverlight-3-doh-and-woo-hoo.html"&gt;previous post&lt;/a&gt;. Here's the default page the project template creates:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SqFJIUAlbVI/AAAAAAAAAMc/PclmruEJjkA/s1600-h/1-Intial+XAML.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659837216025938" style="width: 400px; height: 111px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SqFJIUAlbVI/AAAAAAAAAMc/PclmruEJjkA/s400/1-Intial+XAML.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We're going to make a couple changes in the "UserControl" tag.  Update the following properties:&lt;br /&gt;&lt;br /&gt;d:DesignWidth="335"&lt;br /&gt;d:DesignHeight="335"&lt;br /&gt;&lt;br /&gt;Next, we'll replace the Grid with a set of nested StackPanels.  The nested StackPanels will set up our 3 x 3 grid.  As mentioned in the previous post, you can use a Grid here if you'd like, but I chose the StackPanels to keep the Button tags a little "cleaner".  For the outer StackPanel, I set the Background to Black.  Inside each of the nested StackPanels, I have placed 3 buttons.  The buttons have fairly arbitrary names; this is just so we can tell them apart when we're doing the design work.  The updated XAML looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFJILsDvpI/AAAAAAAAAMU/Bm_nCctQCHI/s1600-h/2-Button+Set+Up.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659834982448786" style="width: 400px; height: 241px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFJILsDvpI/AAAAAAAAAMU/Bm_nCctQCHI/s400/2-Button+Set+Up.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you build and run the application at this point, you'll see this result.  (Remember to run the Web application).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFJHpmRPcI/AAAAAAAAAMM/BKquy2zvYbE/s1600-h/3-Button+Set+Up+Output.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659825831361986" style="width: 308px; height: 400px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFJHpmRPcI/AAAAAAAAAMM/BKquy2zvYbE/s400/3-Button+Set+Up+Output.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Step 2 - Templates&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Now we're going to take advantage of the "lookless" controls in XAML and replace the default Button template.  This will allow us full control over the way our buttons look and behave.  This varies a little bit from the WPF sample: in the WPF sample, I used a combination of Templates and Styles; in this sample, we'll use only a Template.&lt;br /&gt;&lt;br /&gt;We'll start our Template by adding a local resource to the file.  Add a tag "UserControl.Resources" just above the outer StackPanel.  As we've seen before, Visual Studio IntelliSense is very helpful when hand-editing XAML; so, let the code-completion do a lot of the work for you.  You can also do this entire application in Expression Blend, but that's a lesson for another time.  Inside the Resources section, we'll add a ControlTemplate for our buttons.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFJHKSDPPI/AAAAAAAAAME/IxitVox5ABM/s1600-h/4-New+Control+Template.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659817425059058" style="width: 400px; height: 182px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFJHKSDPPI/AAAAAAAAAME/IxitVox5ABM/s400/4-New+Control+Template.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A few key things to point out.  The TargetType is set to Button.  This means that we can apply this template to Button controls (or their descendents) and only Button controls.  Next is the x:Key.  This gives a name to the Template that we can use to assign it elsewhere.  Next we have a Canvas (our drawing surface with a Margin to space things out a little) and an Ellipse (which is just a DarkRed circle at this point).  Note: the Ellipse is named "Outer Red Stripe" in the comments because we will be adding more to this template in just a bit.&lt;br /&gt;&lt;br /&gt;Now we'll need to apply our new Template to our Buttons.  We do this by assigning the Template property of each button to the StaticResource that we just created.  The highlighted code below is repeated for each button.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SqFI9CySirI/AAAAAAAAAL8/B8Csd9Q-mGM/s1600-h/5-Applying+the+Template.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659643614104242" style="width: 400px; height: 330px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SqFI9CySirI/AAAAAAAAAL8/B8Csd9Q-mGM/s400/5-Applying+the+Template.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's our result (ignore the jpeg artifacts in the picture; it actually looks much better in person):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFI8tR1egI/AAAAAAAAAL0/thFnD8e-iRY/s1600-h/6-Red+Circles+Output.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659637840837122" style="width: 310px; height: 400px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFI8tR1egI/AAAAAAAAAL0/thFnD8e-iRY/s400/6-Red+Circles+Output.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Something to note: the red circles are still buttons.  They are clickable (although they don't visibly change when you click on them), and they have standard button events (such as Click).  Notice that the Content does not appear in the buttons.  This is because our Template does not have a ContentManager, nor do we need one for this application.  Because we aren't displaying the Content, we can remove the Content properties from each of our buttons to clean up the code.&lt;br /&gt;&lt;br /&gt;Now, let's spice up our visuals.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Step 3 - Eye Candy&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Now we'll take the boring red circles and make them into glassy 3-D buttons.  As I mentioned in the WPF XAML sample, the best way to learn how to do this is by looking at some Photoshop tutorials.  The same techniques (gradient opacity ellipses) can be used in Expression Blend.  I take no credit for the "glow" parts of the design template; I copied them from a demo by Walt Ritscher.  He's also a good resource for WPF styles and templates.&lt;br /&gt;&lt;br /&gt;First, the top glow.  This is simply added to our Control Template below the "Outer Red Stripe" code.  It is just an ellipse with a radial gradient that moves from white to transparent.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SqFI8YVUpyI/AAAAAAAAALs/Vt8qKG7rJ5s/s1600-h/7-Top+Glow.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659632218318626" style="width: 400px; height: 187px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SqFI8YVUpyI/AAAAAAAAALs/Vt8qKG7rJ5s/s400/7-Top+Glow.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The bottom glow is much the same: just an ellipse with a radial gradient.  We'll put this directly below the "Top Glow" code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFI74XMwhI/AAAAAAAAALk/zD8XqylErKo/s1600-h/8-Bottom+Glow.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659623636255250" style="width: 400px; height: 132px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFI74XMwhI/AAAAAAAAALk/zD8XqylErKo/s400/8-Bottom+Glow.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you build and run the application now, you'll see a distinct difference compared to what we had before:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFI7qEtZFI/AAAAAAAAALc/GkWGlae0b2w/s1600-h/9-Glow+Output.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659619800605778" style="width: 304px; height: 400px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFI7qEtZFI/AAAAAAAAALc/GkWGlae0b2w/s400/9-Glow+Output.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Cool, huh?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Step 4 - Completing the Targets&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Next, we just need to complete the visual design of the Targets.  This is just a set of ellipses, each smaller than the last, alternating between Red and White.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFIyVLG7-I/AAAAAAAAALU/FepkgEj3i6M/s1600-h/10-Completed+Target.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659459571478498" style="width: 400px; height: 298px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFIyVLG7-I/AAAAAAAAALU/FepkgEj3i6M/s400/10-Completed+Target.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A few things to note here.  First you'll see that we are moving the Canvas.Left and Canvas.Top properties because the Top Left corner is considered to be the starting point for drawing on a Canvas.  We are moving down and a bit to the right to keep the smaller circle centered on the previous one.&lt;br /&gt;&lt;br /&gt;Order is important here.  The XAML parser processes items in the order that they appear in the file.  This means that the "Outer Red Stripe" is drawn first, and then each smaller circle is drawn on top of it.  The same is true of the "glows".  We want these on top of the rest, so we specify them last in the file.  The Canvas in Silverlight 3 does have a Z-Order property, so you can adjust this if you have a more complex drawing.&lt;br /&gt;&lt;br /&gt;We're done with the visuals for our Targets.  Now they look like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SqFIx-_raYI/AAAAAAAAALM/eyEKlweCE3s/s1600-h/11-Completed+Target+Output.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659453617957250" style="width: 306px; height: 400px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SqFIx-_raYI/AAAAAAAAALM/eyEKlweCE3s/s400/11-Completed+Target+Output.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Step 5 - The Action&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;The last step is to add the behavior.  &lt;em&gt;This entire section is quite a bit different from the WPF sample, and all brand new to Silverlight 3.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;As a reminder, when we click on any of the target buttons, we want it to animate by "falling over" and then reset after 3 seconds.  The animation will work by using a Transform.  The first step is to define an empty Transform to our Canvas.  I have this inside the closing Canvas tag, but below all of the visuals we added above.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFIxWeSw_I/AAAAAAAAALE/Gaqco4M_1Zk/s1600-h/12-Render+Transform.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659442740511730" style="width: 385px; height: 62px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFIxWeSw_I/AAAAAAAAALE/Gaqco4M_1Zk/s400/12-Render+Transform.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is where things really start to get interesting.  For the Animation to be triggered by a Click, we need to add some References to our project: Microsoft.Expression.Interactions and System.Windows.Interactivity (noted below).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SqFIxEhlY8I/AAAAAAAAAK8/H9bC-j6_mrg/s1600-h/13-Interactivity+References.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659437922476994" style="width: 248px; height: 220px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SqFIxEhlY8I/AAAAAAAAAK8/H9bC-j6_mrg/s400/13-Interactivity+References.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now we need to add a namespace reference to these assemblies.  We add these at the top of the file with the other "xmlns" references.  The good news is that you don't have to type all of this in (see the image below).  Instead, IntelliSense will help you out.  After you type the "=", you will get a pop-up of the assmeblies that are available from the project references.  The completed namespace references should look like the image below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFIw0J83AI/AAAAAAAAAK0/5C6OcRSCoV4/s1600-h/14-Interactivity+Namespaces.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659433528384514" style="width: 400px; height: 15px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFIw0J83AI/AAAAAAAAAK0/5C6OcRSCoV4/s400/14-Interactivity+Namespaces.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Next, we'll add an Interaction section to the Template that includes an EventTrigger.  This needs to be placed before the closing Canvas tag.  (I have it between the Transform and the end of the Canvas.)  The EventTrigger specifies that it acts on the "MouseLeftButtonDown" event.  And inside of that, we have an Animation Storyboard.  Take a look at the EventTrigger and Animation specified below.  Then we'll walk through it step by step.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFIm_VggWI/AAAAAAAAAKs/4Q_vt3A1a2c/s1600-h/15-Animation.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659264730956130" style="width: 400px; height: 224px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SqFIm_VggWI/AAAAAAAAAKs/4Q_vt3A1a2c/s400/15-Animation.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First, note the "i:Interaction.Triggers" tag.  The "i:" is specifying that we are using an object in the System.Windows.Interactivity namespace that we referenced above.  Next, we define our Event Trigger (also in the "i" namespace) and specify that it will act on the MouseLeftButtonDown event.&lt;br /&gt;&lt;br /&gt;Now, we move on to the "im:ControlStoryboardAction" tag.  The "im:" is referencing the Microsoft.Blend.Interactions namespace.  This is denoting that we want to "Play" the Storyboard when the EventTrigger fires.  Finally, we'll define the actual Storyboard in the "ControlStoryboardAction.Storyboard" section.&lt;br /&gt;&lt;br /&gt;This contains a standard-looking Animation storyboard that we have named "ClickAnimaton".  Let's look at each of the 2 animations in a little more detail.&lt;br /&gt;&lt;br /&gt;The "DoubleAnimationUsingKeyFrames" says that we want to animate a double property (in this case the Y-Scale of the Canvas) and that we want to use KeyFrames to control the flow of the animation.  The "Storyboard.Target" tells what object the storyboard is acting on (the Canvas in our Template), and the "Storyboard.TargetProperty" tells what property we are acting on.  As noted before, we are operating on the Y-Scale of the Canvas by using the RenderTransform we defined earlier.  Duration is 1.5 seconds and Auto-Reverse is true.  This means that our total animation will be 3 seconds long.&lt;br /&gt;&lt;br /&gt;Here's how we want our animation to work: first, we want it to "fall over" quickly (in 0.5 seconds), then stay "laying down" for a while, then pop back up quickly (also 0.5 seconds).  They KeyFrames will let us do this.  In the first "LinearKeyFrameAnimation", we are giving the starting position of 1, meaning set y-scaling to 100%.  In the next, we want the y-scale to be set to 1% (almost invisible) at the half-second mark.  The third shows that we want the y-scale to sill be at 1% at the 1.5 second mark.  The auto-reverse runs the animation backwards (starting with the third KeyFrame and working up).  This gives us a total animated time of 3 seconds.&lt;br /&gt;&lt;br /&gt;The second animation is required because the origin of the Canvas is at the Top Left.  This means that if we only had the first animation, the target would shrink up (toward the origin).  The second animation says that we want to move the center point of the Canvas down so that it will shrink down and "fall over".&lt;br /&gt;&lt;br /&gt;You'll have to run it yourself to see the final result.  Here's a screen shot of things in action:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SqFImsCmJcI/AAAAAAAAAKk/1nCMpIWyQ0c/s1600-h/16-Final+Output.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5377659259551360450" style="width: 306px; height: 400px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SqFImsCmJcI/AAAAAAAAAKk/1nCMpIWyQ0c/s400/16-Final+Output.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Round Up&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;So, Silverlight 3 allows us to do much more in the XAML than Silverlight 2 allowed.  We were able to reproduce the WPF XAML sample with a few changes.  I expect that by the time .NET 4.0 and the next version of WPF rolls around, that WPF and Silverlight will look pretty much the same.  But we'll still have to wait and see with that.&lt;br /&gt;&lt;br /&gt;This is a good example of the power of declarative programming with XAML.  The more I use it, the more I like it.  When I think about trying to do an application like this in WinForms, I just shudder.  It would be a mess of custom drawing code, timers, and crazy calculations.  XAML gives me the freedom to easily take control over the layout and appearance of my application.  And as we've seen here, it's not just limited to "look and feel", we can also program quite a bit of functionality with it.&lt;br /&gt;&lt;br /&gt;You can add some code-behind and create a full fledged shooting gallery game that keeps track of scores and gives you a time limit.  But I'll leave that as an exercise for the reader.&lt;br /&gt;&lt;br /&gt;Happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-9062473206757517995?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/9062473206757517995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/09/target-practice-silverlight-3-xaml.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/9062473206757517995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/9062473206757517995'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/09/target-practice-silverlight-3-xaml.html' title='Target Practice - Silverlight 3 / XAML Sample'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_tXOq_FsazuI/SqFJIUAlbVI/AAAAAAAAAMc/PclmruEJjkA/s72-c/1-Intial+XAML.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7064593617114578214</id><published>2009-08-02T21:08:00.000-07:00</published><updated>2009-09-04T18:21:27.888-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight 3'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>Silverlight 3 -- D'oh! and Woo Hoo!</title><content type='html'>In July, Microsoft released Silverlight 3. On the one hand, it's good to see the features moving forward at a good pace. On the other hand, we only had 9 months with Silverlight 2. I just thought I was starting to understand how to work with Silverlight 2 effectively, and wham! new version.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;The Bad&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;First, the bad. I was surprised by some of the items that are included in the Silverlight 3 release notes. Fortunately, I read these &lt;em&gt;before&lt;/em&gt; installing the bits.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. Silverlight 2 &amp;amp; Silverlight 3 compatability&lt;/strong&gt;&lt;br /&gt;&lt;blockquote&gt;Silverlight 2 projects cannot be created with the Silverlight 3 Tools for Visual Studio 2008. To create Silveright 2 projects, uninstall the Silverlight 3 runtime and the Silverlight 3 Tools from Add or Remove Programs and re-install the Silverlight 2 Tools for Visual Studio 2008.&lt;/blockquote&gt;This was a showstopper for me at work. As I've mentioned, I've been developing a Silverlight 2 application at my day job. Due to certain circumstances, I can't upgrade the project to Silverlight 3 (yet). Since I still need to support it in the meantime, I need to keep the Silverlight 2 bits installed on my machine.&lt;br /&gt;&lt;br /&gt;There are some blog posts out there with tips on how to switch back and forth between the 2 versions, but it's making things a bit more complicated than I would like. So, the work machine stays on Silverlight 2 (but Silverlight 3 immediately gets installed at home).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. Design Preview in Visual Studio 2008&lt;/strong&gt;&lt;br /&gt;&lt;blockquote&gt;Due to performance and rendering issues, the preview window has been disabled in the Silverlight 3 Tools for Visual Studio 2008. The functionality of the XAML editor remains intact, including IntelliSense, error messages, and the ability to drag controls from the Toolbox into the editor. WYSIWYG XAML design can be done by using Expression Blend or Visual Studio 2010.&lt;/blockquote&gt;This limitation is somewhat disappointing to me. I'm a XAML guy. I'm comfortable typing in the design code directly (and IntelliSense works great in Visual Studio). But I did use the preview window to see how things look. Now, I have to have Expression Blend open to check the preview. I wouldn't mind so much if I used Blend more extensively (which I probably should anyway), but right now it seems like a bit of a kludge to have to toggle back and forth.&lt;br /&gt;&lt;br /&gt;There are other notes as well, and I would encourage you to read them in full. These are the ones that jumped out at me as being disappointments.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;The Good&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;So, now the good parts. These are just the items that struck me as useful. There are plenty of other new features (such as out-of-browser support and 3-D support that are interesting but not very applicable in my world).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. WCF Service Support&lt;/strong&gt;&lt;br /&gt;Silverlight 3 has support for the full WCF stack. This means that we are no longer limited to basicHttpBinding for our WCF services that are consumed by Silverlight. We can use WS* bindings or any of the other bindings.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. Controls&lt;/strong&gt;&lt;br /&gt;In addition, there are plenty of new contols available (including a TreeView) and loads of new layout controls. The Silverlight 3 toolbox is starting to look a lot closer to the WPF toolbox (and excels it in a few cases).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3. Improved XAML&lt;/strong&gt;&lt;br /&gt;New features such as Behaviors and Triggers greatly enhance the ability to define things declaratively in XAML as opposed to having to implement them in code.&lt;br /&gt;&lt;br /&gt;Here's my example: One of my first demos on this blog was a WPF application that was written entirely in XAML. It included a visual re-design of buttons and animation that triggered by clicking the button. It was fully functional with absolutely no code-behind. You can see that entry here: &lt;a href="http://jeremybytes.blogspot.com/2009/03/wpf-xaml-sample.html"&gt;WPF Target Practice&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When I first started getting into Silverlight 2, my goal was to reproduce the same application in Silverlight. However, due to limitations (specifically a lack of Triggers), the only way to implement the animation would be in code. I moved forward with learning how to do the animation that way (and implemented some pretty cool visuals in my application at work), but I never posted the results since they missed the goal of using XAML only. &lt;p&gt;&lt;/p&gt;&lt;p&gt;Silverlight 3 has some additional assemblies available that allow you to implement the triggers and fire off animations. So, in an entry in the near future, I'm planning on posting the Silverlight 3 version of Target Practice. So be sure to stay tuned! &lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;To use Silverlight 3, you'll need Visual Studio 2008, plus the Silverlight 3 bits. Start at the Silverlight site here: &lt;a href="http://silverlight.net/GetStarted/"&gt;http://silverlight.net/GetStarted/&lt;/a&gt;. As mentioned above, you want Expression Blend 3 (there are trials available if you don't want to purchase the full suite). Be sure to take a thorough look through the release notes as well.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Wrap Up&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;So, like most things in life, there is the bad along with the good. I'm hoping that by the time Visual Studio 2010 comes out, we'll have some better options available. In the meantime, the Silverlight 3 does have a lot to offer (I just scratched the surface with a few items that interested me).&lt;br /&gt;&lt;br /&gt;Keep learning!&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7064593617114578214?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7064593617114578214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/08/silverlight-3-doh-and-woo-hoo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7064593617114578214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7064593617114578214'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/08/silverlight-3-doh-and-woo-hoo.html' title='Silverlight 3 -- D&apos;oh! and Woo Hoo!'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-8158097648664674880</id><published>2009-06-13T23:19:00.000-07:00</published><updated>2009-07-01T18:55:24.205-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Event'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><category scheme='http://www.blogger.com/atom/ns#' term='User Control'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>More Silverlight Part 2 - User Controls &amp; Events</title><content type='html'>&lt;div&gt;The story so far: In &lt;a href="http://jeremybytes.blogspot.com/2009/06/more-silverlight-part-1-data-templates.html"&gt;More Silverlight Part 1&lt;/a&gt;, we created a Silverlight 2 application and a WCF service.  We then used a DataTemplate and various ValueConverters to format and display the data in the ListBox.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Here's what the app looked like when we left off:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6XhiclsI/AAAAAAAAAJ8/8PPxubMHEXc/s1600-h/1-StartProject.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888645502310082" style="width: 252px; height: 291px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6XhiclsI/AAAAAAAAAJ8/8PPxubMHEXc/s400/1-StartProject.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Now, we're going to move on, first by creating a Detail panel, then abstracting out the ListBox to a User Control, and finally creating an Event that will let us know when a new Person record is selected.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Creating a Detail Panel&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We'll start by adding a Detail panel that shows the First Name, Last Name, Birth Date, and Age for a single Person (the Person selected in the ListBox).  This will be a StackPanel that is in the 2nd column of the Grid in our Page.xaml.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SkW6XdtiUPI/AAAAAAAAAJ0/DeYic_vOUmM/s1600-h/2-DetailPanel.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888644475080946" style="width: 400px; height: 201px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SkW6XdtiUPI/AAAAAAAAAJ0/DeYic_vOUmM/s400/2-DetailPanel.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The code is pretty self-explanatory.  We set up TextBlocks to serve as labels for the data, and TextBlocks with data binding to hold the data.  You'll notice that we are using the same DateConverter and AgeConverter that we used in the ListBox.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Getting Data into the Detail Panel&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We want the Detail Panel to update whenever the selection changes in the ListBox.  To do this, we'll hook up a "SelectionChanged" event to the ListBox.  As a reminder, you can just type "SelectionChanged=" and Visual Studio will give you the option to add a New Event Handler.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SkW6Xa7Pm-I/AAAAAAAAAJs/6ISYi84g8Kc/s1600-h/3-AddSelectionChanged.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888643727268834" style="width: 400px; height: 70px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SkW6Xa7Pm-I/AAAAAAAAAJs/6ISYi84g8Kc/s400/3-AddSelectionChanged.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now, we'll navigate to the Event Handler in the Page.cs file.  What we need to do here is set the DataContext of the DetailPanel.  But the question is, what should we bind to?  Do we need to make a service call?&lt;br /&gt;&lt;br /&gt;The answer comes through the fact that Silverlight data binding is extremely flexible.  We can bind to any object, including an object that exists somewhere else on the page.  In this case, we want to bind to the Person that is selected in the ListBox.  So, we do just that.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6XLkq5BI/AAAAAAAAAJk/BPmY0MCrtZE/s1600-h/4-SelectionChangedHandler.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888639606055954" style="width: 400px; height: 85px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6XLkq5BI/AAAAAAAAAJk/BPmY0MCrtZE/s400/4-SelectionChangedHandler.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A couple of things to note here.  First, you see that we are getting the SelectedItem for the ListBox and then casting it as a Person.  What you should be aware of is that this may result in a null value.  The SelectionChanged event will fire whenever the currently selected item changes; this includes when an item is un-selected.  When a ListBox is first loaded, the default is to have no selection.  This event will fire, and the SelectedItem will be null.&lt;br /&gt;&lt;br /&gt;In many circumstances, you will want to check the "var p" to see if it is null after the assignment.  In our case, we will want to let p be null (we'll see why in just a bit).&lt;br /&gt;&lt;br /&gt;After we get the SelectedItem cast as a Person, we just assign this as the DataContext of our DetailPanel.  Pretty straightforward, huh?  Here's the result:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6PWH1YPI/AAAAAAAAAJc/lA9U-1g75B0/s1600-h/5-DetailPanelResult.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888504998945010" style="width: 400px; height: 291px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6PWH1YPI/AAAAAAAAAJc/lA9U-1g75B0/s400/5-DetailPanelResult.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To see how the nulls are handled in the Event, simply click the Button again.  This will clear the selected item in the ListBox, which will in turn clear out the DetailPanel data.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Creating a User Control&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But what if we want to re-use the Person ListBox multiple places in our application?  Rather than duplicating code, it would be better to abstract out this piece as a separate User Control.  That's what we'll do right now.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1&lt;/span&gt;: Add a new User Control to the Silverlight project&lt;br /&gt;Right-click on the Silverlight project, select "Add", then "New Item".  From the dialog, select "Silverlight User Control" and name it "PersonListControl".  This will create a default PersonListControl.xaml and PersonListControl.cs that look very similar to what we started with for Page.xaml/Page.cs.  This is because Page is also a Silverlight User Control.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2&lt;/span&gt;: Cut the StackPanel xaml from Page.xaml to PersonListControl.xaml&lt;br /&gt;We'll be moving everything from the first Grid column of Page.xaml to the new user control.  Just cut the entire StackPanel (the one that has Grid.Column="0"), and paste it over the Grid (LayoutRoot) in PersonListControl.xaml.  This will leave us with a StackPanel as the root element of the user control.  Note: after pasting it in, you will want to remove the "Grid.Column" attribute.  The app will still run with it there, but it's better to keep the xaml as clean as possible.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3&lt;/span&gt;: Copy the UserControl.Resources Section&lt;br /&gt;The xaml that we moved in the step above makes use of the Converters we created earlier.  This means that our new user control needs to have references to these as well.  The easiest way is just to copy these from the Page.xaml.  Note that we are doing a copy (not a cut) because these are used in the DetailPanel that is staying on Page.xaml.&lt;br /&gt;&lt;br /&gt;Copy the "xmlns:local=" namespace and the entire "UserControl.Resources" sections with all three converters to PersonListControl.xaml.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 4&lt;/span&gt;: Change the Size&lt;br /&gt;Our new UserControl will need to fit in the first column of our main Grid, so we'll want to change the sizes a bit.  Change Width to 240 (to allow for a little bit of padding) and the Height to 300.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 5&lt;/span&gt;: Move the Event Handlers&lt;br /&gt;The xaml that we moved contained 2 Event Handlers: one for the ListBox selection changed event, and one for the Button click event.  Now we'll move the Event Handlers as well.&lt;br /&gt;&lt;br /&gt;From the Page.cs file, cut the "PersonList_SelectionChanged" and "GetPeopleButton_Click" methods and paste them into PersonListControl.cs.  One thing to note: since the PersonList_SelectionChanged event directly references the DetailPanel, this won't compile.  For now, just comment out the 2 lines in this Event Handler. We'll be re-implementing this a little later.&lt;br /&gt;&lt;br /&gt;You should be able to build now, but if you run the application, you will find that we still need to place the new user control onto our main Page.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 6&lt;/span&gt;: Using the User Control&lt;br /&gt;Actually using the new user control on our main Page couldn't be easier.  In the spot in our Page.xaml where we used to have a StackPanel (in the first Grid column), we will now have our control:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SkW6PNA45zI/AAAAAAAAAJU/ozveMsQyHHU/s1600-h/6-AddUserControl.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888502553896754" style="width: 400px; height: 102px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SkW6PNA45zI/AAAAAAAAAJU/ozveMsQyHHU/s400/6-AddUserControl.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Notice that this uses the "local" prefix (the same as our Converters) since everything is in the same namespace.  If we were to split out the User Control into a separate namespace, then we would need to add a new xmlns and give it a different alias to use.&lt;br /&gt;&lt;br /&gt;We can now run the application, and the ListBox will look just like it did before.  If we click the Button, it will fetch the Person list and display it.  The application doesn't work completely, though.  We can't get the data into the DetailPanel.  For that, we will need to expose an Event in our new User Control.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;High Level Event Overview&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before we create the Event, let's take a look at how we'd like it to work.  What we want to do is get the Person that is selected in the ListBox and display it in the DetailPanel.  The problem is that the ListBox and DetailPanel are now in different scopes.  So, we need to get the Person from the ListBox to the DetailPanel somehow.  We'll do this by exposing an Event in the ListBox that has the selected Person as part of the EventArgs.&lt;br /&gt;&lt;br /&gt;We'll need a custom EventArgs class that will hold the selected Person.  Then we'll set up an Event on our new User Control that we can hook in to from our Page.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Custom EventArgs&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We'll create the custom EventArgs class in the PersonListControl.cs file.  You may want to abstract this out into its own file for other projects, but we won't do that here.  We'll descend from RoutedEventArgs (which is a little more specific than EventArgs and is commonly used in Silverlight and WPF).  Our custom EventArgs only needs to have a single Property (SelectedPerson) and a contructor that takes a Person as a parameter.  Here's the completed code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SkW6OxfSZLI/AAAAAAAAAJM/dWKBE1ptCPs/s1600-h/7-EventArgs.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888495165203634" style="width: 400px; height: 163px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SkW6OxfSZLI/AAAAAAAAAJM/dWKBE1ptCPs/s400/7-EventArgs.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Declaring the Event Handler&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next, we need to declare the Event in our PersonListControl class.  We can do this with a single line of code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SkW6O3C0vNI/AAAAAAAAAJE/VA_yF87Aa-M/s1600-h/8-EventHandler.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888496656432338" style="width: 400px; height: 15px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SkW6O3C0vNI/AAAAAAAAAJE/VA_yF87Aa-M/s400/8-EventHandler.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note that there are several ways to make this declaration, including using "delegate" syntax.  The syntax used here is the most compact.  You'll see that we are using our custom EventArgs class as a generic type.  Our Event is called "SelectedPersonChanged".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Invoking the Event Handler&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To invoke the Event Handler, the convention is to create a method called On&lt;span style="font-style: italic;"&gt;EventName --&lt;/span&gt; in our case "OnSelectedPersonChanged".  Take a look at the code below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SkW6HFaRWYI/AAAAAAAAAI8/ZI_YX_ULJIE/s1600-h/9-OnSelectedPersonChanged.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888363073919362" style="width: 400px; height: 105px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SkW6HFaRWYI/AAAAAAAAAI8/ZI_YX_ULJIE/s400/9-OnSelectedPersonChanged.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If the comments look familiar, it's because they came straight from the Microsoft Help file.  They aren't really applicable for this particular application because we're not making descendant classes or doing complex invokation, but it's good to use the "safe" version so that we can get used to it.&lt;br /&gt;&lt;br /&gt;You'll see that we are using our custom EventArgs as a parameter for this method.  And as noted in the comments, we are making a copy of the handler first.  This is because we can only invoke handlers that are actually hooked up to something (i.e. not null).  If the handler is null, then we do not want to do anything (and thus we have the null check).  The reason that we make the copy is that it is possible that the handler is deleted between the time we check for null and the time we invoke the method.  If we make a copy, then we are acting on a snapshot in time, and so eliminate this possibility.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Raising the Event&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now we need to actually raise the event.  We will do this in the "PersonList_SelectionChanged" method (the one that we commented out earlier).  We will get the SelectedItem from the ListBox and cast it to a Person -- just like the old ListBox SelectionChanged handler.  Then we'll use that Person to create the custom EventArgs and pass it to the OnSelectedPersonChanged method.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6HJSOJTI/AAAAAAAAAI0/O-AFub24AZw/s1600-h/10-ListSelectionChanged.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888364113896754" style="width: 400px; height: 74px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6HJSOJTI/AAAAAAAAAI0/O-AFub24AZw/s400/10-ListSelectionChanged.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Notice that it is possible for the Person to be null (as we discussed above).  This is okay.  If there is no SelectedItem, then we will pass the null through the Event and ultimately to the DetailPanel (as we'll see next).  Be sure to build everything to make sure that there are now errors.  If you run, you still won't see any difference.  Yet.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Using the Newly Exposed Event&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now we'll go back to our Page.xaml to hook up the new Event.  You'll notice that if you start typing "Select" in the PersonListControl element, IntelliSense will show the Event.  Like other events, if you type "SelectedPersonChanged=", Visual Studio will let pop up "New Event Handler" (as we saw above).  If you do this, you'll end up with something like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SkW6Gz0G5BI/AAAAAAAAAIs/snt_ECiROMY/s1600-h/11-HookUpEvent.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888358350447634" style="width: 400px; height: 35px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SkW6Gz0G5BI/AAAAAAAAAIs/snt_ECiROMY/s400/11-HookUpEvent.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Finally, we'll navigate to the event handler in the Page.cs file.  Since the custom EventArgs exposes a SelectedPerson object, we just need to assign this to the DataContext of the DetailPanel.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SkW6Gt9B0JI/AAAAAAAAAIk/M9kMTKhfKGY/s1600-h/12-HandleEvent.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888356777250962" style="width: 400px; height: 61px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SkW6Gt9B0JI/AAAAAAAAAIk/M9kMTKhfKGY/s400/12-HandleEvent.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you run the application now, you'll see a fully functioning Person ListBox and DetailPanel.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SkW6GWIYSrI/AAAAAAAAAIc/h-5pO5mW95Y/s1600-h/13-Result.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351888350382410418" style="width: 400px; height: 283px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SkW6GWIYSrI/AAAAAAAAAIc/h-5pO5mW95Y/s400/13-Result.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This will behave the same as above.  If you click the Button again, the DetailPanel is cleared.  This is because the SelectedItem is cleared when the ListBox is loaded.  Because the SelectedItem changed, the Event fires.  And because there is no SelectedItem, the EventArgs contains a null SelectedPerson.  This results in a null for the DataContext for the DetailPanel (which is what we want here).  You may need to rework this if you need different behavior.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;We've taken our application and abstracted out a significant part of it into a separate User Control.  Then we implemented an Event on that User Control that we can use when we add the element to our Page.  If we were to have several different forms that needed this same Person ListBox, we can simply add the custom User Control and get all the same functionality.  We even have an Event to hook into so we know when the selected Person changes.  These are just the basics, of course.  For a production app, we would want to add Error handling and other such things.&lt;br /&gt;&lt;br /&gt;As you can see, Silverlight has several powerful features that allow us to create flexible and well-designed applications.  Since pretty much everything in Silverlight is a User Control, it's possible to nest these elements within each other and come up with some interesting abstractions in our UI.&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;br /&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-8158097648664674880?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/8158097648664674880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/06/more-silverlight-part-2-user-controls.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8158097648664674880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8158097648664674880'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/06/more-silverlight-part-2-user-controls.html' title='More Silverlight Part 2 - User Controls &amp; Events'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_tXOq_FsazuI/SkW6XhiclsI/AAAAAAAAAJ8/8PPxubMHEXc/s72-c/1-StartProject.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7169196981125250412</id><published>2009-06-06T21:46:00.000-07:00</published><updated>2009-06-28T17:47:06.051-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Value Converter'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>More Silverlight Part 1 - Data Templates &amp; Value Converters</title><content type='html'>&lt;p&gt;I've pretty much finished up my Silverlight 2 project at work, so I thought I'd share a few more useful things that I've come across. This time, we'll take a look at Data Templates (which make List Boxes extremely flexible) and Value Converters.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Setting Up the App&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;We're going to start by building a application similar to what we built in the last few posts: a Silverlight 2 application that gets data from a WCF service. Start by following Steps 1 - 3 from &lt;a href="http://jeremybytes.blogspot.com/2009/05/silverlight-2-and-wcf-part-1.html"&gt;this post&lt;/a&gt;. I'll point out where we'll make a couple of changes.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Create a New Silverlight Application&lt;br /&gt;We'll call it "TemplatesConvertersEvents" this time.  Let it create the ASP.NET hosting site as well.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Build a WCF Service&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step 2a:&lt;/strong&gt; The WCF Service Contract&lt;br /&gt;We'll create the same PersonService, but we'll add a new field "BirthDate" to the Person class. See the Service Contract below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SkWku7zKiuI/AAAAAAAAAIU/oeLMHwvjxsY/s1600-h/1-ServiceContract.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864858432932578" style="width: 400px; height: 233px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SkWku7zKiuI/AAAAAAAAAIU/oeLMHwvjxsY/s400/1-ServiceContract.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step 2b:&lt;/strong&gt; The Service Implementation&lt;br /&gt;Again, this will look pretty similar. We'll just add a BirthDate value to each of the Person objects.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkrR5TPfI/AAAAAAAAAIM/C1_HggohO2E/s1600-h/2-ServiceImplementation.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864795644771826" style="width: 400px; height: 270px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkrR5TPfI/AAAAAAAAAIM/C1_HggohO2E/s400/2-ServiceImplementation.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step 2c:&lt;/strong&gt; WCF Service Configuration&lt;br /&gt;Same as last time. Make sure to change the binding from "wsHttpBinding" to "basicHttpBinding".&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Add the WCF Service Reference to the Silverlight Application&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Update the XAML.&lt;br /&gt;This is pretty similar to the previous examples, with just a few differences. Check out the code sample below for Page.xaml. Then we'll walk through it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SkWkrEdvx_I/AAAAAAAAAIE/pKOVoZS8Siw/s1600-h/3-StartingXaml.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864792039540722" style="width: 400px; height: 299px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SkWkrEdvx_I/AAAAAAAAAIE/pKOVoZS8Siw/s400/3-StartingXaml.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Start by changing the Width and Height properties of the page (500 x 300). Then replace the default Grid with a Border. The Border contains a 2 column grid. We'll be concentrating on the first column here (the 2nd column will be used in Part 2). The Grid contains a ListBox.&lt;br /&gt;&lt;br /&gt;Notice that the ListBox looks a little different. We are no longer using the "DisplayMemberPath". Instead, we have an ItemTemplate that contains a DataTemplate. The DataTemplate is simply a container that can hold whatever content you like. For now, we'll just include a TextBlock that is bound to the FirstName field. This will have the same effect as if we were to set the DisplayMemberPath. One thing to be aware of: the DisplayMemberPath and ItemTemplate are mutually exclusive; if you try to include both, you will get an error.&lt;br /&gt;&lt;br /&gt;Finally, we have a Button that looks similar to our previous examples. As a reminder, to add the Click handler, just type "Click=" and Visual Studio will pop up an option for "New Event Handler". This will create a handler based on the control name and put the stub in the code-behind.&lt;br /&gt;&lt;br /&gt;Next we implement the handler. You can right-click on "GetPeopleButton_Click" and choose "Navigate to Event Handler" and it will take you to appropriate spot in Page.cs. The handler implementation should look like this (again similar to what we've seen before):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkq6_9UjI/AAAAAAAAAH8/J6-ptLFO61Q/s1600-h/4-ButtonHandler.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864789498679858" style="width: 400px; height: 111px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkq6_9UjI/AAAAAAAAAH8/J6-ptLFO61Q/s400/4-ButtonHandler.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another reminder: you will need to add the "using" statement for the PersonService. If you type in the code above, you can place the cursor on "PersonServiceClient", then press Ctrl+. to bring up the option to add the "using".&lt;br /&gt;&lt;br /&gt;You should be able to build and run the application now. After you click the button, the results should look like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SkWkqxeLRNI/AAAAAAAAAH0/ECGtGJ1h-NU/s1600-h/5-StartingResult.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864786941068498" style="width: 246px; height: 294px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SkWkqxeLRNI/AAAAAAAAAH0/ECGtGJ1h-NU/s400/5-StartingResult.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Expanding the Data Template&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Now we'll see the power that the ListBox has by expanding the DataTemplate a bit. The DataTemplate can only have a single child element, so if we add multiple items, we'll need to wrap them in some sort of container. We'll use a set of nested StackPanels -- some vertical and some horizontal.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SkWkqnNjBfI/AAAAAAAAAHs/5MUEFfhIi3s/s1600-h/6-MiddleTemplate.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864784186967538" style="width: 400px; height: 214px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SkWkqnNjBfI/AAAAAAAAAHs/5MUEFfhIi3s/s400/6-MiddleTemplate.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is fairly straightforward XAML. Note that we have multiple TextBlocks that are databound and a little bit of formatting. Here's what we get when we run the app now.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SkWkiM-iS2I/AAAAAAAAAHk/RnJu_Pjtmvg/s1600-h/7-MiddleResult.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864639705729890" style="width: 249px; height: 290px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SkWkiM-iS2I/AAAAAAAAAHk/RnJu_Pjtmvg/s400/7-MiddleResult.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Creating a Value Converter&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;One thing I don't like about the output is the format of the BirthDate field. To take care of this, we'll use a value converter. A value converter is simply a class that implements the IValueConverter interface (profound, eh?). The interface consists of 2 methods: Convert and ConvertBack. An incoming value is passed in as a parameter; all you need to do is do the conversion and return the new value.&lt;br /&gt;&lt;br /&gt;Our DateConverter isn't going to be that interesting, but it's a good place to start (then we'll look at something a little more challenging).&lt;br /&gt;&lt;br /&gt;In the Silverlight project, add a new Class. I've called mine "Converters.cs" because I'll use the same file to hold all of my converters. Then we'll rename the class from "Converter" to "DateConverter" and add the IValueConverter interface. IValueConverter is in the System.Windows.Data namespace, so you'll need to add this to the "using" block as well.&lt;br /&gt;&lt;br /&gt;As we've done before, we'll just right-click on "IValueConverter", choose "Implement Interface", then "Implement Interface" again. This will put the "Convert" and "ConvertBack" method stubs into our class. We'll only be doing one-way conversion (read-only data), so we will only implement "Convert".  If you had a TextBox or other editable control, then you would also implement "ConvertBack" which reverses the process.  Here's our code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SkWkhzdrhzI/AAAAAAAAAHc/nsNuU8GgIrc/s1600-h/8-DateConverter.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864632857036594" style="width: 400px; height: 212px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SkWkhzdrhzI/AAAAAAAAAHc/nsNuU8GgIrc/s400/8-DateConverter.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Since the "value" parameter is of type object, we'll need to start off by casting it to the inbound type that we are expecting (DateTime in this case). Our outbound type is simply a string, so we'll call the ToString function with a formatting string that we like. Note that there are additional options (some that are especially useful for Date conversions) by using the "parameter" and "culture" parameters. Take a look at the Microsoft Help file to get more information on those.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Using a Value Converter&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;So, now that we have a DateConverter, how do we use it? First, we'll need to add the namespace to our xaml (see below). Again, VisualStudio is helpful here; if you type "xmlsns:local=", then you will get a list of namespaces that are in the project, including everything that appears in the project References.  We'll select the project namespace "TemplatesConvertersEvents". You can use whatever alias you like for the namespace; "local" is a convention for items contained within your project.&lt;br /&gt;&lt;br /&gt;The next step is to add our DateConverter as a Static Resource.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SkWkhvAJGVI/AAAAAAAAAHU/Ud-6RUx5yRk/s1600-h/9-DateConverterResource.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864631659403602" style="width: 400px; height: 86px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SkWkhvAJGVI/AAAAAAAAAHU/Ud-6RUx5yRk/s400/9-DateConverterResource.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now all that's left is to add the Converter to the Binding declaration in our TextBlock.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SkWkhXHUw-I/AAAAAAAAAHM/AMGndv9akh4/s1600-h/10-UsingDateConverter.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864625247077346" style="width: 400px; height: 69px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SkWkhXHUw-I/AAAAAAAAAHM/AMGndv9akh4/s400/10-UsingDateConverter.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you run the application now, you'll see that we have a nicely formatted mm/dd/yyyy date for the BirthDate field. Let's try something a little more complex.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;An Age Converter&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;In addition to the BirthDate, I'd like to display the age of the Person as well. The problem is that we don't have an Age field. So, instead, we'll use the BirthDate field to calculate the age. We'll just add another class (AgeConverter) to the Converters.cs file.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SkWkhDNnqnI/AAAAAAAAAHE/HNH9L_Ihdp4/s1600-h/11-AgeConverter.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864619904772722" style="width: 400px; height: 251px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SkWkhDNnqnI/AAAAAAAAAHE/HNH9L_Ihdp4/s400/11-AgeConverter.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We won't worry about the specifics of the code too much (I'm sure that I'll get letters with better ways to calculate age). The main point is that we are taking a DateTime (BirthDate) and converting it to an Integer (Age). Well, actually, we're converting it to a string for display purposes, but you get the idea.&lt;br /&gt;&lt;br /&gt;Using the AgeConverter is just the same as the DateConverter. Add a Static Resource (I called mine "myAgeConverter") and then use it in a Binding statement. Notice that we are still Binding to the BirthDate field; by using the AgeConverter, we control what we will actually display.  Here is a portion of our expanded DataTemplate (we appended the Age portions to the section with the BirthDate).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SkWkYwFkN9I/AAAAAAAAAG8/3xHdWeKKGpY/s1600-h/12-UsingAgeConverter.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864477331765202" style="width: 400px; height: 111px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SkWkYwFkN9I/AAAAAAAAAG8/3xHdWeKKGpY/s400/12-UsingAgeConverter.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you run the app now, you'll see both the BirthDate and the Age are included.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;One More Converter&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;As one final step, we'll get a little more creative with our converter. So far, we've more or less just converted a value from one format to another. This time, we'll convert to a completely different type. I want to display ages that are over 30 in a green font and 30 or under in blue. We'll do this by changing the BirthDate to a Brush.&lt;br /&gt;&lt;br /&gt;Once again, create a new class "AgeBrushConverter" in the Converter.cs file. The code looks like the "AgeConverter" code, but instead of returning the age, it uses it to create a SolidColorBrush:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkYh9uueI/AAAAAAAAAG0/Z1DZ60QUzr4/s1600-h/13-AgeBrushConverter.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864473540803042" style="width: 400px; height: 281px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkYh9uueI/AAAAAAAAAG0/Z1DZ60QUzr4/s400/13-AgeBrushConverter.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For the implementation, our final "Resources" section looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkYlPOXDI/AAAAAAAAAGs/nTvSC993tII/s1600-h/14-FinalResources.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864474419485746" style="width: 400px; height: 63px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkYlPOXDI/AAAAAAAAAGs/nTvSC993tII/s400/14-FinalResources.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And our final DataTemplate (notice that we are using the AgeBrushConverter for the Foreground property of the TextBlock):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SkWkYRBgxAI/AAAAAAAAAGk/82bZRY4R4Rg/s1600-h/15-FinalDataTemplate.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864468993262594" style="width: 400px; height: 239px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SkWkYRBgxAI/AAAAAAAAAGk/82bZRY4R4Rg/s400/15-FinalDataTemplate.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And our final result:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkYFcoocI/AAAAAAAAAGc/JM-7i69u6k0/s1600-h/16-FinalResult.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5351864465885798850" style="width: 252px; height: 291px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SkWkYFcoocI/AAAAAAAAAGc/JM-7i69u6k0/s400/16-FinalResult.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Summary&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;We've taken a chance to look at DataTemplates and ValueConverters to add flexibility to how we display our data in ListBoxes. DataTemplates can contain complex layouts (including Grids and Images, if desired). ValueConverters also go beyond simple formatting (like Dates and Currency); they can also be used to show or hide items (think of Binding a value to the "Visible" property) or even to add text formatting to differentiate values (such as using red for negative numbers and black for positive, or possibly graying-out inactive items).&lt;br /&gt;&lt;br /&gt;Hang on to this application. In Part 2, we'll take a look at creating a custom user control that abstracts out part of the functionality and exposes an event that we can use.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7169196981125250412?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7169196981125250412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/06/more-silverlight-part-1-data-templates.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7169196981125250412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7169196981125250412'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/06/more-silverlight-part-1-data-templates.html' title='More Silverlight Part 1 - Data Templates &amp; Value Converters'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_tXOq_FsazuI/SkWku7zKiuI/AAAAAAAAAIU/oeLMHwvjxsY/s72-c/1-ServiceContract.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-5234958707616497495</id><published>2009-05-12T20:34:00.000-07:00</published><updated>2009-06-09T10:29:44.943-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Lambda Expression'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>Silverlight 2, WCF, and Lambda Expressions - Part 2</title><content type='html'>In &lt;a href="http://jeremybytes.blogspot.com/2009/05/silverlight-2-and-wcf-part-1.html"&gt;Part 1&lt;/a&gt;, we set up a Silverlight 2 application that consumes a WCF Service. In Part 2, we'll look at a problem with the implementation and different ways of solving it -- ultimately ending with Lambda Expressions. Hopefully by the time we get done, you'll be comfortable with how lambda expressions work and how to use them to make your code cleaner and easy to understand.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Where We Left Off&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Here's a quick reminder of what we did last time:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We created a WCF Service that is Silverlight 2 compatible.&lt;/li&gt;&lt;li&gt;We added a reference to the service in a Silverlight application.&lt;/li&gt;&lt;li&gt;We created a UI (Button and ListBox) to call the service and show the results.&lt;/li&gt;&lt;li&gt;We called the WCF Service and hooked up the Completed event to an event handler.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The Page.xaml.cs file we finished with is as follows:&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAPgUj42I/AAAAAAAAAE8/ifJ1-t26BYg/s1600-h/StartPageXamlCs.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147343692161890" style="width: 400px; height: 224px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAPgUj42I/AAAAAAAAAE8/ifJ1-t26BYg/s400/StartPageXamlCs.JPG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;And the UI:&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SgpAPqgQwYI/AAAAAAAAAFE/8ow1YPxUdcI/s1600-h/StartPoint.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147346425594242" style="width: 197px; height: 188px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SgpAPqgQwYI/AAAAAAAAAFE/8ow1YPxUdcI/s400/StartPoint.JPG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;A Problem&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;There is a small problem with the UI. After calling the service (by clicking the button), the list gets populated with the names. You can select a name in the list by clicking on it. But if you click the button again, the list refreshes and the selection goes away. We want to update this so that the selected item is maintained when the service is called again.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Solution #1 - Using the Event Handler&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;The SelectedItem of the ListBox gets cleared when the service is called because we are re-binding the data. From the ListBox's point of view, it is getting a new object to bind to. When the old object is un-bound, the selected item goes away and doesn't come back.&lt;/p&gt;&lt;p&gt;We'll solve this by simply saving off the SelectedIndex of the ListBox before we make the service call. Then after the service call returns, we will reassign the SelectedIndex. (This is assuming that the order of our items is not changing, and we're not getting any new items -- you can extend this basic functionality for more complex situations).&lt;/p&gt;Since we need to save off the SelectedIndex in one method (the Button Click event handler) and then use it in a different method (the Service Completed event handler), we'll need to create a class-level variable to hold this information. See the code below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SgpAGtb0dRI/AAAAAAAAAEU/MBG266HVx3Q/s1600-h/EHComplete.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147192593446162" style="width: 400px; height: 217px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SgpAGtb0dRI/AAAAAAAAAEU/MBG266HVx3Q/s400/EHComplete.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You'll see 3 new lines of code to get this to work:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;private int ehListIndex;&lt;br /&gt;The class-level variable&lt;/li&gt;&lt;li&gt;ehListIndex = EHList.SelectedIndex;&lt;br /&gt;Saving the index&lt;/li&gt;&lt;li&gt;EHList.SelectedIndex = ehListIndex;&lt;br /&gt;Re-assigning the index to the list box&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you re-run the application, you will see that if you make a selection in the list box, that selection is maintained when you call the service multiple times.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Solution #2 - Using an Anonymous Delegate&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Now, we'll try this again using an anonymous delegate instead of an explicit event handler. You'll see why this is an advantage in just a bit.&lt;/p&gt;&lt;p&gt;We'll update our XAML by adding another StackPanel to our Grid.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SgpAGXWJsBI/AAAAAAAAAEM/LJPy_M0F95c/s1600-h/ADXaml.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147186664091666" style="width: 400px; height: 132px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SgpAGXWJsBI/AAAAAAAAAEM/LJPy_M0F95c/s400/ADXaml.JPG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You'll notice that this section looks almost identical to the EventHandler UI section. Here's a summary of the differences:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The 2nd column of the Grid is specified in the StackPanel.&lt;/li&gt;&lt;li&gt;The Names of the ListBox and Button start with AD (for anonymous delegate) instead of EH.&lt;/li&gt;&lt;li&gt;The ListBox border is blue (just to make it different).&lt;/li&gt;&lt;li&gt;The button Content is "Anonymous Delegate".&lt;/li&gt;&lt;li&gt;There is a new Click handler for the button (you can look at the hint in Part 1 about letting IntelliSense create the handler for you).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So, what is an anonymous delegate? In our case, it is an in-line definition of an event handler (for the service callback). This is defined by using the "delegate" keyword, then a set of parentheses with the appropriate parameters, then a set of curly braces with the method implementation. The implementation will look just like in our callback when using the EventHandler.&lt;/p&gt;&lt;p&gt;Here's the initial implementation:&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SgpAGZu2pXI/AAAAAAAAAEE/f_t3IAjwx18/s1600-h/ADStart.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147187304572274" style="width: 400px; height: 124px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SgpAGZu2pXI/AAAAAAAAAEE/f_t3IAjwx18/s400/ADStart.jpg" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;What you will notice is that that the first and last lines are the same as our previous button click event. You'll also notice that the parameters for the anonymous delegate ("object" and "GetPeopleCompletedEventArgs") matches the parameters in the explicit event handler we implemented earlier. Finally, the body of the delegate matches the body of the event handler callback.&lt;br /&gt;&lt;br /&gt;I know what you're thinking: big deal. Other than "in-lining" some code, exactly what did we gain here? We're about to find out.&lt;br /&gt;&lt;br /&gt;We still have the same issue we had earlier with the ListBox SelectedIndex. The advantage to using an anonymous delegate is that any variables in the outer method can be accessed in the delegate implementation. This means that instead of using a class-level variable to store the index, we can use a local variable. Check out the completed code below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAGNI5-2I/AAAAAAAAAD8/6ImHRKAt7GU/s1600-h/ADComplete.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147183924181858" style="width: 400px; height: 146px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAGNI5-2I/AAAAAAAAAD8/6ImHRKAt7GU/s400/ADComplete.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You'll see that we now have a local variable named "adListIndex" that is assigned outside of the delegate and then used inside of the delegate. We've just eliminated the need to have a class-level variable.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Solution #3 - Using a Lambda Expression&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Let's take this one step further. Instead of using an anonymous delegate, we'll use a lambda expression. First, update the UI. This XAML is very similar to the anonymous delegate section:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAPkyvIqI/AAAAAAAAAE0/uY1EdzFyruE/s1600-h/LEXaml.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147344892469922" style="width: 400px; height: 132px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAPkyvIqI/AAAAAAAAAE0/uY1EdzFyruE/s400/LEXaml.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The same items are updated as above: grid column, element names, border color, button content, and click event.&lt;br /&gt;&lt;br /&gt;So, now lets take a look at lambda expressions. There are 2 types of lambda expressions: statement lambdas and expression lambdas. Both use the same syntax (consisting of 3 parts):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Parameters&lt;br /&gt;These are normally enclosed by parentheses (although, parentheses can be excluded if there is only a single parameter).&lt;br /&gt;The parameter types may be excluded if the compiler can determine the correct types.&lt;/li&gt;&lt;li&gt;=&gt;&lt;br /&gt;This is known as the "goes to" operator and denotes that this is a lambda.&lt;/li&gt;&lt;li&gt;Statement(s) or Expression(s)&lt;br /&gt;A statement lambda has one or more operations wrapped in curly braces. The statement(s) denotes some type of work to be done.&lt;br /&gt;An expression lambda has one or more expressions (that return true or false) wrapped in curly braces. These are used extensively in LINQ.&lt;br /&gt;If there is only a single statement or expression, then the curly braces can be excluded.&lt;/li&gt;&lt;/ol&gt;We'll be working with an Statement Lambda. The first steps to convert the anonymous delegate to a lambda expression are to remove the "delegate" keyword and place the "=&gt;" operator between the parameters and the method implementation. Take a look at the "LEButton_Click" method below and compare it to the first "ADButton_Click" method above:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAPXPIo0I/AAAAAAAAAEs/50WFdcLD2Kc/s1600-h/LEStart.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147341253485378" style="width: 400px; height: 124px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAPXPIo0I/AAAAAAAAAEs/50WFdcLD2Kc/s400/LEStart.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But, as we noted above, if the compiler can determine the parameter types, then we don't need to include them in our code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SgpAPUCDULI/AAAAAAAAAEk/BBPWdGXobBs/s1600-h/LEMid.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147340393304242" style="width: 400px; height: 123px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SgpAPUCDULI/AAAAAAAAAEk/BBPWdGXobBs/s400/LEMid.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you hover over the "s" and "ea" parameters, you will see that Visual Studio recognizes these as being of type "object" and "GetPeopleCompletedEventArgs" respectively. This means that we still have strongly-typed objects. The same is true of "ea.Result". This is the strongly-typed collection that is returned from our WCF Service.&lt;br /&gt;&lt;br /&gt;As a final step, we can add the SelectedIndex handling code into the mix:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAGlM7l-I/AAAAAAAAAEc/9glZ2wlCUOU/s1600-h/LEComplete.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5335147190383515618" style="width: 400px; height: 150px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAGlM7l-I/AAAAAAAAAEc/9glZ2wlCUOU/s400/LEComplete.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;If you run the application, you will see that all three list boxes behave the same way. All three list boxes will keep the selected index between service calls.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;What We Learned&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;We took a look at 3 different ways to solve a particular UI issue. We see that both the Anonymous Delegate and Lambda Expression solutions have the advantage of being able to use a local-scoped variable (thus, keeping our class-level clutter-free). In addition, we see that the Lambda Expression solution has the advantage of not needing to include the parameter types. This is especially helpful if you have a delegate that has the standard 2 parameter signature ("object" and "SomeKindOfEventArgs"); you don't need to know the particular EventArgs class -- just let Visual Studio figure that out for you.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;My advice: become familar with Lambda Expressions. You will find that when used judiciously, they can help keep your code understandable and easier to maintain.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-5234958707616497495?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/5234958707616497495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/05/silverlight-2-wcf-and-lambda.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5234958707616497495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/5234958707616497495'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/05/silverlight-2-wcf-and-lambda.html' title='Silverlight 2, WCF, and Lambda Expressions - Part 2'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_tXOq_FsazuI/SgpAPgUj42I/AAAAAAAAAE8/ifJ1-t26BYg/s72-c/StartPageXamlCs.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-6906653892090988374</id><published>2009-05-01T19:58:00.000-07:00</published><updated>2009-05-11T10:00:43.553-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Access'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Silverlight 2, WCF, and Lambda Expressions - Part 1</title><content type='html'>This is a 2-part series in using WCF with Silverlight 2. Part 1 is about creating a Silverlight-compatible WCF service and consuming it in a Silverlight application. Part 2 is about lambda expressions, but uses the foundations in Part 1.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 1 - Create a New Silverlight Application&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;First we'll create a new Silverlight application. In Visual Studio, create a New Project, and select the "Silverlight Application" template. I've called mine "SilverlightWithWCF", so that's what you'll see in a couple places throughout the post.&lt;br /&gt;&lt;br /&gt;Visual Studio will prompt you with the following:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVA-_jJrI/AAAAAAAAACU/VziAMqiADI0/s1600-h/SilverlightStartup.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396127785723570" style="width: 400px; height: 355px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVA-_jJrI/AAAAAAAAACU/VziAMqiADI0/s400/SilverlightStartup.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We want to include a new ASP.NET Web Application Project, so we'll leave the defaults as-is. Other options include "ASP.NET Web Site" and possibly "ASP.NET MVC" (if you have the MVC bits installed). In addition to using the ASP.NET application as a test site for the Silverlight application, we will use it to host our WCF service.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 2 - Build the WCF Service&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;We'll add a new WCF Service at this point. Right-click on the Web Application project ("SilverlightWithService.Web" in my case), and choose "Add", then "New Item". Select the WCF Service. We'll name ours "PersonService.svc". See below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SgeVXDoLRLI/AAAAAAAAADE/bipZlj-XPGQ/s1600-h/AddWCFService.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396506986988722" style="width: 400px; height: 240px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SgeVXDoLRLI/AAAAAAAAADE/bipZlj-XPGQ/s400/AddWCFService.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You'll notice that there are 2 options we could choose from: "WCF Service" or "Silverlight-enabled WCF Service". You might wonder why we didn't pick the Silverlight one. The answer is that I wanted to look at the standard WCF Service, so that you will know what to do if you already have an existing WCF Service that you want to hook into. I'll point out the difference below when we look at the Web.config file.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 2a - The WCF Service Contract&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;WCF Service consist of 3 main pieces: the Service Contract, the Service Implementation, and the Service Configuration. First, we'll look at the Service Contract.&lt;br /&gt;&lt;br /&gt;The contract is simply an interface decorated with a few specific attributes. Visual Studio will create an I[ServiceName].cs file that contains the placeholder contract. If you open the IPersonService.cs file, you'll see an interface that is decorated with the [ServiceContract] attribute. Visual Studio also gives you a sample method called "DoWork". You'll notice that this is decorated with the [OperationContract] attribute. You can think of this as being analogous to the [WebMethod] attribute that we used in ASMX Services. The [OperationContract] attribute denotes which methods will be exposed to the outside world.&lt;br /&gt;&lt;br /&gt;We're going to replace the "DoWork" method with a "GetPeople" method. Take a look at the completed code below, and we'll step through it:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVAyJnjMI/AAAAAAAAACk/eu61_a3jqqM/s1600-h/CompletedContract.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396124338293954" style="width: 400px; height: 295px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVAyJnjMI/AAAAAAAAACk/eu61_a3jqqM/s400/CompletedContract.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You'll notice that our method returns a List of Person. Person is a custom class, and so we need to include the definition of the class as well. You'll notice that we have a separate public class called "Person" that is decorated with the [DataContract] attribute. The class consists of 2 public properties (FirstName and LastName) that are each decorated with the [DataMember] attribute. The DataContract and DataMember attributes let the WCF sub-system know that it needs to include this type in the definition of the Service.&lt;br /&gt;&lt;br /&gt;On a side note, the [DataContract] and [DataMember] attributes can be excluded in this particular case. .NET 3.5 SP1 will automatically include the type definition for public classes that have automatic properties and a public default constructor. This was added to facilitate Entity Framework.  I'll leave it as an exercise for the reader to do further research into this.&lt;br /&gt;&lt;br /&gt;The contract only tells what the service will do, not how it does it. For that, we'll need to look at the service implementation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 2b - The WCF Service Implementation&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;The WCF Service implementation is a class that implements the WCF interface. Open up the "PersonService.svc.cs" file (note: you can simply double-click on the "PersonService.svc", and it will open the .cs file).&lt;br /&gt;&lt;br /&gt;You'll see that the class "PersonService" implements "IPersonService" and still has the placeholder "DoWork" method from the stub that Visual Studio created. Delete this method. We'll let Visual Studio add the stubs for the updated interface. Simply right-click on "IPersonService" and select "Implement Interface", then "Implement Interface" again (we won't cover "Implement Interface Explicitly"). This will create a stub for the "GetPeople" method. Here's the implementation:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click to enlarge image)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SgeVBFQ5TVI/AAAAAAAAACs/OPnMHMAI1R8/s1600-h/CompletedService.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396129469091154" style="width: 400px; height: 229px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SgeVBFQ5TVI/AAAAAAAAACs/OPnMHMAI1R8/s400/CompletedService.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This simply creates a List object and populates it with some Person instances. In real life, you'll probably be doing something more complex (such as accessing a database).&lt;br /&gt;&lt;br /&gt;Next comes the configuration.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 2c - WCF Service Configuration&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Open up the Web.config file, and then navigate to the "system.serviceModel" section (at the bottom). The only thing that you'll need to do is update the binding to "basicHttpBinding" (from "wsHttpBinding"). See below:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVBGK2nOI/AAAAAAAAAC0/dpVU8HwJf9k/s1600-h/CompletedWebConfig.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396129712184546" style="width: 400px; height: 230px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVBGK2nOI/AAAAAAAAAC0/dpVU8HwJf9k/s400/CompletedWebConfig.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Remember when I promised to show the difference between "WCF Service" and "Silverlight-enabled WCF Service"? This is it. Silverlight 2 is limited in that it can only use WCF Services that use the "basicHttpBinding". This is the same binding that ASMX services use. (Note: Silverlight 3 will not have this limitation). The "Silverlight-enabled WCF Service" defaults to basicHttpBinding, while "WCF Service" defaults to wsHttpBinding. If you have an existing service, you'll just need to change this value (or add an endpoint that uses this binding).&lt;br /&gt;&lt;br /&gt;Note: This is a very important step. If you try to add a Service Reference in a Silverlight application to a WCF Service that is *not* using basicHttpBinding, then the proxy will not work. Even better, you don't get any helpful error messages, just a rather obscure one. So, make sure you don't skip this step.&lt;br /&gt;&lt;br /&gt;From here, we'll build everything just to make sure that things look good. This completes our updates to the Web Application. Next, we'll move on to the Silverlight application.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 3 - Add the WCF Service Reference to the Silverlight Application&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;We'll start in the Silverlight application by adding a Service Reference to our newly created service. Right-click on the Silverlight Application project ("SilverlightWithService" in our case), and choose "Add Service Reference". If you click the "Discover" button, it will search out the Services that are included in the Solution. We'll use the namespace "PersonService". See below:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/Sgee5v_gAzI/AAAAAAAAADk/qTAAB2gY6Fs/s1600-h/AddServiceReference.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334406998616179506" style="width: 400px; height: 322px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/Sgee5v_gAzI/AAAAAAAAADk/qTAAB2gY6Fs/s400/AddServiceReference.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Before you click "OK", be sure to check out the "Advanced" button. This opens a dialog that lets you choose how collections are returned from WCF Service calls:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;br /&gt;&lt;/span&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVXERyRaI/AAAAAAAAAC8/VCAZmXB1UiY/s1600-h/AddServiceReferenceAdvanced.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396507161511330" style="width: 400px; height: 72px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVXERyRaI/AAAAAAAAAC8/VCAZmXB1UiY/s400/AddServiceReferenceAdvanced.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You'll see that there are 4 options to choose from: Array, Generic List, Collection, and ObservableCollection. The ObservableCollection is preferred in Silverlight for data binding purposes, but you may want to experiment with the other options as well. It doesn't matter the actual collection type that is returned from the service; it will be converted to the type you select here.&lt;br /&gt;&lt;br /&gt;Now that we've added our Service Reference, we'll take a look at the Silverlight UI.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 4 - Update the XAML&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Next, we'll create the UI. Open up the Page.xaml file. We're going to be making a few changes to the default values and adding some controls of our own. The final layout may look a little odd. This is because we will be adding some more elements to this in Part 2.&lt;br /&gt;&lt;br /&gt;Here's the final layout:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/Sgehh_Wo0NI/AAAAAAAAADs/YsjUiV2j5I8/s1600-h/PageXAMLdesign.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334409888957780178" style="width: 400px; height: 139px;" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/Sgehh_Wo0NI/AAAAAAAAADs/YsjUiV2j5I8/s400/PageXAMLdesign.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let's look at the XAML; then we'll go through it step by step:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVXe-ZSRI/AAAAAAAAADM/KHsiVQtf5Kk/s1600-h/PageXAML.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396514327939346" style="width: 400px; height: 293px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVXe-ZSRI/AAAAAAAAADM/KHsiVQtf5Kk/s400/PageXAML.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First, update the Width and Height of the UserControl to 600 and 200 respectively. Then we'll swap out the "Grid" root element for a "Border". Then add a Grid with 3 columns (the other 2 columns will be used in Part 2). Inside the first column is a StackPanel with a ListBox and a Button. The ListBox sets the ItemsSource to "{Binding}". This says that each ListBox item will be bound to each item in the collection. The data binding will use a DataContext that we set in code at runtime.&lt;br /&gt;&lt;br /&gt;Next is the Button named "EHButton" (for Event Handler Button -- Part 2 will have 2 additional Lists and Buttons and these names will make more sense). When adding an event handler in XAML, Visual Studio will help you out a bit. If you type "Click=" and hit Ctrl-Space (or let Intellisense pop up on its own), you will have the option "New Handler" to pick from. This will automatically name the handler based on the control name, and then add the stub to the code. In this case, it will create "EHButton_Click" in the code and hook up event.&lt;br /&gt;&lt;br /&gt;Now that our UI is laid out, let's put the last of the pieces together.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 5 - Call the WCF Service&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Here's another short-cut. If you right-click on "EHButton_Click" (the event handler) in the XAML, one of the options is "Navigate to Event Handler". This will open up the Page.xaml.cs file and put the cursor on the "EHButton_Click" event handler.&lt;br /&gt;&lt;br /&gt;First, add the WCF Service namespace to the "using" section. This will make the code more readable. The namespace is [projectName].[serviceNamespace]. In our case, it is "SilverlightWithService.PersonService".&lt;br /&gt;&lt;br /&gt;Now, we'll go back to the event handler. Start by creating a new proxy object. The proxy is the service name with "Client" appended to the end. In our case it is "PersonServiceClient". Next we'll hook up the callback. Since all Silverlight calls are asynchronous, we have to call the service asynchronously (it's the only choice). Start by hooking up an event handler to the "Completed" event. Visual Studio helps you out with this, too. Type "proxy.GetPeopleCompleted +=", and you'll see Intellisense for creating a new event handler. If you press "Tab" twice, it will create the new handler, and add the implementation. This is a great short-cut. The last step is to call the service using the "Async" method. In this case, just call "proxy.GetPeopleAsync()". See completed button click event handler below:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SgeVXvHH78I/AAAAAAAAADU/kF2rbkNXAC0/s1600-h/ButtonClick.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396518659518402" style="width: 400px; height: 67px;" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SgeVXvHH78I/AAAAAAAAADU/kF2rbkNXAC0/s400/ButtonClick.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The final step is to implement the callback. This is as simple as getting the result of the call (in this case a List of Person) with "e.Result" in the code. Then we assign this to the DataContext of the ListBox in the UI. One thing to note, if you hover over "e.Result", you will see that it is actually of type ObservableCollection of Person. This is due to the selection we made when we added the Service Reference earlier. The completed Page.xaml.cs file is as follows:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVXnV4bmI/AAAAAAAAADc/TA0W8IqAiD4/s1600-h/PageXamlCs.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334396516573933154" style="width: 400px; height: 224px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVXnV4bmI/AAAAAAAAADc/TA0W8IqAiD4/s400/PageXamlCs.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 6 - Build and Test&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Let's build and run. What you should see is that when you click the "Event Handler" button, you will get a list of 5 names in the ListBox. This may take a few seconds for the Service to fire up and run -- remember we're running asynchronously here. Also note that the list only includes the First Name because we did not do a full data template; we just set the DisplayMemeberPath. It's easy enough to enhance yourself, though.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SgemiQI_ufI/AAAAAAAAAD0/XUuBkYBuGaA/s1600-h/FinalResult.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334415391022103026" style="width: 197px; height: 188px;" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SgemiQI_ufI/AAAAAAAAAD0/XUuBkYBuGaA/s400/FinalResult.JPG" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;br /&gt;Conclusion&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;You should have a pretty good idea of how to create a WCF Service and consume it with Silverlight 2. We've created a new WCF Service, ensured that it was Silverlight 2 compatible, created a Silverlight 2 application, added the Service Reference, updated the UI, and finally called the Service and bound the results to the UI. In Part 2, we'll be looking at other ways of handling the asynchronous calls.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-6906653892090988374?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/6906653892090988374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/05/silverlight-2-and-wcf-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/6906653892090988374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/6906653892090988374'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/05/silverlight-2-and-wcf-part-1.html' title='Silverlight 2, WCF, and Lambda Expressions - Part 1'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_tXOq_FsazuI/SgeVA-_jJrI/AAAAAAAAACU/VziAMqiADI0/s72-c/SilverlightStartup.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-8806503989380795871</id><published>2009-04-14T21:41:00.000-07:00</published><updated>2009-05-13T20:36:08.623-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Access'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='Book Review'/><title type='text'>Book Review - Data-Driven Services with Silverlight 2</title><content type='html'>As mentioned in a &lt;a href="http://jeremybytes.blogspot.com/2009/04/getting-started-with-silverlight-2.html"&gt;previous post&lt;/a&gt;, I deal with data-centric applications on a daily basis. &lt;a href="http://www.amazon.com/Data-Driven-Services-Silverlight-John-Papa/dp/0596523092/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1241496476&amp;amp;sr=1-1"&gt;Data-Driven Services with Silverlight 2&lt;/a&gt; by John Papa is an excellent book for folks in the same situation. Here's what I really like about it:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Focused Topic&lt;/li&gt;&lt;li&gt;Concise Code Snippets&lt;/li&gt;&lt;li&gt;Clear and Useful Samples&lt;/li&gt;&lt;li&gt;Full Coverage of Silverlight 2 Data Access&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Let's take a look at each of these.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Focused Topic&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;The book covers only data access concepts in Silverlight 2. It assumes that you have a basic Silverlight background and does not focus on areas such as controls, XAML or layout. This keeps the book brief (around 350 pages) and allows you to focus on the relevant topic: data in Silverlight 2.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Concise Code Snippets&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;Code snippets are used liberally throughout the text, both XAML and C#/VB code. The snippets build on previous samples and so only show the "new" parts. This keeps the code snippets short and relevant. And even though the code shows both C# and VB, neither seems to be too long or distracting. I found myself even forgetting that the "other" language was included at times. (You should be able to figure out which language I'm referring to -- not that there's nothing wrong with it. Both languages are pretty much equivalent, so it's just a matter of preference when it comes to syntax.)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Clear and Useful Samples&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;The samples (downloadable from John Papa's webite) are very clear. When there are multiple examples covering a single topic, they are packaged into a single application. This makes it very easy to navigate the samples both at design-time and run-time.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;(Click image to enlarge)&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SgZfGS0udVI/AAAAAAAAACM/PO4c47tFJV4/s1600-h/PapaSample.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5334055370403771730" style="width: 400px; height: 309px;" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SgZfGS0udVI/AAAAAAAAACM/PO4c47tFJV4/s400/PapaSample.JPG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;A couple things to notice in the screen-shot. First, the menu system on the left. This lists the different samples that are included in the project. This makes it very easy to flip back and forth to make comparisons among the samples. &lt;/p&gt;&lt;p&gt;Second, notice that the sample on the right is pleasant to look at. I know that this isn't really all that important. But, many times sample applications for data access methodologies are merely functional. These actually use a custom control template library to make the samples look less generic. The control templates are out of the way in the samples, so it is still easy to focus on the functionality when reviewing the XAML.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Full Coverage of Silverlight 2 Data Access&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;Finally, since this book is focused simply on data access, it can cover a variety of data sources and methodologies. Chapters 1-4 are overviews of the technologies used in data access in Silverlight. Chapters 5-11 cover specific data sources. Here's a breakdown of the book chapter by chapter:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Getting Started with Silverlight 2&lt;br /&gt;A few Silverlight 2 basics (such as Data Services and the Control Model) and .NET topics (such as LINQ and C# language enhancements) which are needed in later topics such as data binding.&lt;/li&gt;&lt;li&gt;Silverlight Data-Binding Foundation&lt;br /&gt;The data-binding basics including dependency properties, XAML binding markup, and the DataContext.&lt;/li&gt;&lt;li&gt;Modes and Notifications&lt;br /&gt;OneTime, OneWay, and TwoWay binding modes and the INotifyPropertyChangedInterface.&lt;/li&gt;&lt;li&gt;Managing Lists, Templates, and Converters&lt;br /&gt;An overview of working with list-based controls, implementing data templates, and building value converters.&lt;/li&gt;&lt;li&gt;WCF, Web Services, and Cross-Domain Policies&lt;br /&gt;How to build and call ASMX services, and also using WCF services that are compatible with Silverlight 2.&lt;/li&gt;&lt;li&gt;Passing Entities via WCF&lt;br /&gt;How to send entities (simple classes) back and forth using LINQ to SQL and Entity Framework.&lt;/li&gt;&lt;li&gt;Consuming RESTful Services with WebClient and HttpWebRequest&lt;br /&gt;An introduction to REST and using WebClient (simpler) or HttpWebRequest (more complex, but more flexible) to interact with RESTful services.&lt;/li&gt;&lt;li&gt;Consuming Amazon's RESTful Services with Silverlight 2&lt;br /&gt;A specific example interacting with Amazon to search items, create a shopping cart, and add items to that cart.&lt;/li&gt;&lt;li&gt;Creating RESTful Services and Introducing SilverTwit&lt;br /&gt;More REST, including consuming JSON services. The SilverTwit sample uses a series of services to create a Twitter client in Silverlight.&lt;/li&gt;&lt;li&gt;Syndication Feeds and Silverlight 2&lt;br /&gt;How to interact with RSS and Atom feeds.&lt;/li&gt;&lt;li&gt;Silverlight 2 and ADO.NET Data Services&lt;br /&gt;An overview of ADO.NET Data Services and how to interact with them with Silverlight.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Summary&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;If you create data-centric applications and are working with Silverlight 2, you need this book. By the time I got to the end of this book, I was extremely comfortable creating services and consuming them with Silverlight. This is an excellent addition to my collection of reference books, and I am finding myself repeatedly opening up the sample applications to review different data access techniques. I am very glad that I came across this excellent resource.&lt;/p&gt;&lt;p&gt;I read between 8 and 10 technical books per year (generally in the 500 to 900 page range).  I find the majority of them useful, but occasionally one will jump out as being particularly relevant.  That is how I felt with Data-Driven Services with Silverlight 2.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-8806503989380795871?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/8806503989380795871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/04/book-review-data-driven-services-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8806503989380795871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/8806503989380795871'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/04/book-review-data-driven-services-with.html' title='Book Review - Data-Driven Services with Silverlight 2'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_tXOq_FsazuI/SgZfGS0udVI/AAAAAAAAACM/PO4c47tFJV4/s72-c/PapaSample.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2508768091911359947</id><published>2009-04-04T20:40:00.000-07:00</published><updated>2010-04-30T08:44:59.918-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Access'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>Getting Started with Silverlight 2</title><content type='html'>I was planning on doing my next application at work in WPF, but it turned out that Silverlight 2 was a better fit. So, I've been doing some quick and dirty work to get up to speed. The good news is that the UI model with XAML is pretty similar (I'll let others get into the specific differences). The bad news is that everything happens asynchronously. Okay, so that's not really bad news, it's just something to get used to. I'll be covering some of my specific learnings on asynchronous programming a bit later, so stay tuned.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;&lt;strong&gt;Database Programming&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;As I said earlier, I write business applications for a living. And that means database access. Silverlight does not support direct database access (such as ADO.NET or LINQ to SQL), so that means that everything happens through network calls. WCF is the best choice for this (with some limitations).&lt;br /&gt;&lt;br /&gt;It took me a while to get comfortable with this concept. The best introductory resource that I found is actually on the silverlight.net site, including very useful tutorial videos. The most helpful one for me was #58 "&lt;a href="http://silverlight.net/learn/learnvideo.aspx?video=47177"&gt;How to Consume WCF and ASP.NET Web Services in Silverlight&lt;/a&gt;" by Tim Heuer. It's about 23 minutes and definitely worth the time.&lt;br /&gt;&lt;br /&gt;Here's the short version:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a WCF Service using basicHttpBinding (Silverlight 2 only supports this binding).&lt;/li&gt;&lt;li&gt;Generate a proxy class for the service in the Silverlight application using the standard Add Service Reference.&lt;/li&gt;&lt;li&gt;Create an instance of the proxy.&lt;/li&gt;&lt;li&gt;Hook up a call-back by assigning a handler to [methodName]&lt;methodname&gt;Completed. Visual Studio is good at helping create the stubs for you (see the video for a demo).&lt;br /&gt;&lt;/methodname&gt;&lt;/li&gt;&lt;li&gt;Call the &lt;methodname&gt;[methodName]Async() to kick off the call.&lt;/methodname&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size: 130%;"&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;If your applications are data centric, then you will definitely want to check out John Papa's book: &lt;a href="http://www.amazon.com/Data-Driven-Services-Silverlight-John-Papa/dp/0596523092/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1241496476&amp;amp;sr=1-1"&gt;Data-Driven Services with Silverlight 2&lt;/a&gt; -- with an introduction by Tim Heuer. This book is all about data access, whether you are creating your own services or consuming existing services. This is a relatively short book (at about 350 pages -- small for a tech book), but the text and samples (easily available for download) are very good. By the time that I got to the end, I was so comfortable with consuming services with Silverlight and working with the asynchronous calls that I could code them up with my eyes closed. I'm planning on doing a full review of this book in a later post.&lt;br /&gt;&lt;br /&gt;The official Microsoft site has a lot to offer. In addition to the video mentioned above, there are lots more on all different topics. Just check out &lt;a href="http://silverlight.net/Learn/"&gt;http://silverlight.net/Learn/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I mentioned the Matthew MacDonald WPF book in a previous post. The good news is that there is a sibling Silverlight book: &lt;a href="http://www.amazon.com/Pro-Silverlight-C-2008-Windows-Net/dp/1590599497/ref=sr_1_1?ie=UTF8&amp;amp;qid=1241496230&amp;amp;sr=8-1"&gt;Pro Silverlight 2 in C# 2008&lt;/a&gt;. This is a very good overview of Silverlight 2 including XAML basics, layout, controls, animation, styles/templates, service calls, and browser integration. The accompanying samples are also very good and cover all of the included topics.&lt;br /&gt;&lt;br /&gt;I always point to dnrTV for good web-casts. You can check out episode #127: &lt;a href="http://www.dnrtv.com/default.aspx?showNum=127"&gt;Shawn Wildermuth on Silverlight 2 Data&lt;/a&gt;. Lots of interesting tidbits scattered throughout.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;&lt;strong&gt;My Experience So Far...&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Silverlight 2 is an adventure. It's not quite web programming, and it's not quite WinForms programming. It sits squarely between the two. More details coming up...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2508768091911359947?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2508768091911359947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/04/getting-started-with-silverlight-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2508768091911359947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2508768091911359947'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/04/getting-started-with-silverlight-2.html' title='Getting Started with Silverlight 2'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-7829900728591769439</id><published>2009-03-09T14:03:00.001-07:00</published><updated>2009-03-12T06:44:13.290-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='XAML'/><title type='text'>Target Practice - WPF / XAML Sample</title><content type='html'>This time we'll be looking at a few of the points from my last post: &lt;a href="http://jeremybytes.blogspot.com/2009/03/what-i-like-about-wpf.html"&gt;What I Like About WPF&lt;/a&gt;. I set out to create a short demo that uses only XAML (with no code behind) to show the power of some of the features; specifically declarative programming, templates, styles and "lookless" controls. So, let's get to the scenario.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;We'll be creating a very simple shooting gallery-type application. I call it "Target Practice" since it will require some more work to turn it into an actual game. In the final version, we will have a 3 x 3 grid of targets. Each of these is clickable and will result in a "hit" animation. After 3 seconds, the target will reset to its previous state -- all inside the XAML. You can scroll down to the bottom to see the finished product.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 1 - Application Set-up&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;We'll start by creating a new WPF application. I'm using Visual Studio 2008, but everything I'm doing here should work in 2005 as well. Create a new project by selecting File -&gt; New -&gt; Project. From there, choose the "Windows" category under "Visual C#" and select "WPF Application".&lt;br /&gt;&lt;br /&gt;In the new application, you will find a "Window1.xaml" file. That's where we are going to start. Open up the xaml file, and you will see a designer and xaml editor. We'll be focusing on the xaml editor. Here's what the project template creates:&lt;br /&gt;&lt;br /&gt;(Click images to enlarge)&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWvhtJSwbI/AAAAAAAAAAc/Zs-SfTpzL5s/s1600-h/Intro-step.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311344329142485426" style="WIDTH: 400px; HEIGHT: 120px" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWvhtJSwbI/AAAAAAAAAAc/Zs-SfTpzL5s/s400/Intro-step.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We're going to make a few changes. Again, this isn't a tutorial on XAML, we're just focusing on showing some of the power. Resources from the previous post are helpful if you are completely new to XAML. First thing we'll do is change a few properties in the "Window" tag. Set the following properties:&lt;br /&gt;&lt;br /&gt;Title="Target Practice"&lt;br /&gt;Height="370"&lt;br /&gt;Width="350"&lt;br /&gt;&lt;br /&gt;Next, we'll replace the Grid with a set of nested StackPanels. The nested StackPanels will set up our 3 x 3 grid (I could have used the Grid here as well, but the StackPanels are better at letting things "flow"). Inside each nested StackPanel, I have placed 3 buttons. The StackPanel code (that replaces the Grid) looks like this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWvhvZGc8I/AAAAAAAAAAk/UBSuRDSHFZA/s1600-h/Step1-code.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311344329745658818" style="WIDTH: 400px; HEIGHT: 235px" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWvhvZGc8I/AAAAAAAAAAk/UBSuRDSHFZA/s400/Step1-code.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When you run the application, you will get a highly exciting result that looks like this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWvh1ATRAI/AAAAAAAAAAs/qW17KNoTKM4/s1600-h/Step1-screenshot.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311344331252253698" style="WIDTH: 350px; HEIGHT: 370px" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWvh1ATRAI/AAAAAAAAAAs/qW17KNoTKM4/s400/Step1-screenshot.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 2 - Templates &amp;amp; Styles&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;So, we have a grid of buttons; now what? Next, we are going to take advantage of the "lookless" controls. WPF controls do not have any inherent visual styling to them. They simply use a default template that is provided by the framework. We are going to replace that template with our own to create a custom button. And hopefully, by the time we get done, you'll see how much easier this is to do in WPF than it is in other UI technologies.&lt;br /&gt;&lt;br /&gt;We're going to add a local resource to the file. Add a tag "Window.Resources" just above the outer StackPanel. You'll find that Visual Studio IntelliSense is very helpful when hand-editing XAML. There are visual ways of doing this with Expression Blend, but that's another topic. Inside the Resources section, we'll add a ControlTemplate.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SbWwI_3y3II/AAAAAAAAAA0/A6TJFYy6Nk0/s1600-h/Step2-controltemplate.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311345004184263810" style="WIDTH: 400px; HEIGHT: 120px" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SbWwI_3y3II/AAAAAAAAAA0/A6TJFYy6Nk0/s400/Step2-controltemplate.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A few key things to point out. The TargetType is set to Button. This means that we can apply this template to button controls (and only to buttons). Next is x:Key: this gives a name to the template that we can use elsewhere. Next we have a Canvas (basically our drawing surface) and an Ellipse (which is just a DarkRed circle). Note: this is called the "Outer Red Stripe" in the comments because we will be adding more to this later on.&lt;br /&gt;&lt;br /&gt;From here we are going to add a Style. The reason for adding a Style will become apparent as we move along. For now, you can see that we create a new Style, give it some Margins, and then set the Template property to our ControlTemplate:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWwJcpVMgI/AAAAAAAAABE/myQj5VpY2WI/s1600-h/Step2-style.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311345011908227586" style="WIDTH: 400px; HEIGHT: 66px" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWwJcpVMgI/AAAAAAAAABE/myQj5VpY2WI/s400/Step2-style.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Styles work by using Setters. The Setters let you select a property (such as Template) and then assign a value to it. You'll notice the syntax for the Template setter looks like this: Value="{StaticResource targetButton}". The curly braces denote that we aren't setting the value directly; we are binding to another object, in this case a StaticResource. The "targetButton" is the x:Key that we specified on our ControlTemplate above.&lt;br /&gt;&lt;br /&gt;One thing to note on our Style: we would normally use an x:Key here as well, which would give us a named style that we can apply in our UI. Styles have the special behavior that if you exclude the x:Key, then the style will automatically be applied to every control in that scope. In this case, since the TargetType is Button, it will be applied to every button in our Window. Here's what our application looks like now.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_tXOq_FsazuI/SbWwJE8trOI/AAAAAAAAAA8/K-07I77QJ8o/s1600-h/Step2-screenshot.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311345005547072738" style="WIDTH: 350px; HEIGHT: 370px" alt="" src="http://1.bp.blogspot.com/_tXOq_FsazuI/SbWwJE8trOI/AAAAAAAAAA8/K-07I77QJ8o/s400/Step2-screenshot.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One thing to note: the red circles are still buttons. They are clickable (although they don't visually change when you click on them), and they have standard button events (such as Click). Notice that they do not have any content (Button1a, Button1b, etc.). This is because our template does not contain an element for the Content. If you are creating your own buttons, then you will want to look at this and other behaviors (such as having different visuals for up, down, and hover). So far the visuals for our application aren't that great. Step 3 is going to change that.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 3 - Eye Candy&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Now we'll take our boring red circles and make them into glassy 3-D buttons. The best way to learn how to do this is to take a look at some Photoshop tutorials and use the same techniques in Expression Blend. The cool part about using Blend is that when you have what you want, you can simply copy the XAML (or have it included as a resource in your project). I am not a graphic designer, and I will admit to stealing this "top glow" and "bottom glow" sections from a demo by &lt;a href="http://wpfwonderland.wordpress.com/"&gt;Walt Ritscher&lt;/a&gt;. He is also a good resource for WPF styles and templates.&lt;br /&gt;&lt;br /&gt;First, the top glow. This is simply added to our ControlTemplate below the DarkRed Ellipse. All it is is an ellipse with a radial gradient that moves from white to transparent.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWwnEIC3tI/AAAAAAAAABc/4pqo0qaOlyw/s1600-h/Step3-topglow.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311345520722239186" style="WIDTH: 400px; HEIGHT: 177px" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWwnEIC3tI/AAAAAAAAABc/4pqo0qaOlyw/s400/Step3-topglow.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The bottom glow is much the same: just an ellipse with a radial gradient.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWwm5Uxq9I/AAAAAAAAABM/g2NAB2B2CU8/s1600-h/Step3-bottomglow.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311345517822847954" style="WIDTH: 400px; HEIGHT: 137px" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWwm5Uxq9I/AAAAAAAAABM/g2NAB2B2CU8/s400/Step3-bottomglow.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What you see when you run the application is a distinct difference in what we had before:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWwm1ClIoI/AAAAAAAAABU/aUY0EQ6dU2s/s1600-h/Step3-screenshot.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311345516672787074" style="WIDTH: 350px; HEIGHT: 370px" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWwm1ClIoI/AAAAAAAAABU/aUY0EQ6dU2s/s400/Step3-screenshot.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pretty cool, eh?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 4 - Completing the Targets&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;Next, we just need to complete the visual design of our Targets. This is just a set of ellipses, each smaller than the last, alternating Red and White.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWw-eA5xaI/AAAAAAAAABk/j-PEUvATUaw/s1600-h/Step4-otherstripes.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311345922808595874" style="WIDTH: 400px; HEIGHT: 278px" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWw-eA5xaI/AAAAAAAAABk/j-PEUvATUaw/s400/Step4-otherstripes.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A few things to note here. You'll see that we are moving the Canvas.Left and Canvas.Top properties because the Top Left corner is considered the starting point for drawing. We are moving down a bit and to the right to make a smaller circle on top of the previous one.&lt;br /&gt;&lt;br /&gt;Order is important here. The XAML parser processes items in the order that they appear in the file. This means that the "Outer Red Stripe" (our first circle) needs to be specified first, and then as each smaller circle is defined, the XAML parser layers it on top of the last. If we were to reverse the order, then the large circle would simply cover everything underneath it. The same is true for the "glows." We want those as the top layer, so we specify them last in the XAML.&lt;br /&gt;&lt;br /&gt;On a side note: Silverlight has a Canvas.ZIndex property that allows you to explicitly set the order of the layering.  This is not available in the current version of WPF, but we'll see what the future holds when .NET 4.0 comes out later this year.&lt;br /&gt;&lt;br /&gt;When we're done, our targets will look like this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SbWw-n2Zv5I/AAAAAAAAABs/hGBAReuV-GU/s1600-h/Step4-screenshot.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311345925448908690" style="WIDTH: 350px; HEIGHT: 370px" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SbWw-n2Zv5I/AAAAAAAAABs/hGBAReuV-GU/s400/Step4-screenshot.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Step 5 - The Action&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;The last step is to add the behavior. As a reminder, when we click on a Target, we want it to animate to fall over, and then reset after 3 seconds. The animation will work by using a Transform. The first step is to define an empty Transform in our Style (note: we are adding this to the Style, not the ControlTemplate).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWxRiKQFOI/AAAAAAAAAB0/HdXENhV7xeY/s1600-h/Step5-rendertransform.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311346250339063010" style="WIDTH: 400px; HEIGHT: 103px" alt="" src="http://2.bp.blogspot.com/_tXOq_FsazuI/SbWxRiKQFOI/AAAAAAAAAB0/HdXENhV7xeY/s400/Step5-rendertransform.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Next, we will add a Trigger to our Style. A Trigger denotes a change to a style based on some external influence. In our case it will be a response to a Button.Click, but it could be a MouseOver or other event.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWxSDPA9fI/AAAAAAAAACE/Mwv1orv8QOw/s1600-h/step5-trigger.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311346259217413618" style="WIDTH: 400px; HEIGHT: 242px" alt="" src="http://4.bp.blogspot.com/_tXOq_FsazuI/SbWxSDPA9fI/AAAAAAAAACE/Mwv1orv8QOw/s400/step5-trigger.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a big bit of code, so let's walk through it. First, we are setting up a Triggers section in our Style. Next we are setting up a EventTrigger on the "Button.Click" RoutedEvent. Inside the EventTrigger, we have an Action section which will contain our actual animation. The EventTrigger and corresponding animation is why we need to use a Style here (as opposed to using just the ControlTemplate).&lt;br /&gt;&lt;br /&gt;The animation is declared with Storyboards. This is another section where using Expression Blend is helpful. You can define an animation using visual tools, and then copy the XAML back into your application (or use it directly as a Resource).&lt;br /&gt;&lt;br /&gt;The first "DoubleAnimation" on "RenderTansform.ScaleY" means that we will be changing the "Y" scale (meaning the Height) over the duration specified (0.3 seconds) and changing it from 1 (full height) to 0.01 (which ends up looking like a line on the screen). If we were to use this animation by itself, then our button would actually shrink "up" because the origin is at the top left corner. In order to get it to shrink "down", we need to add another transform.&lt;br /&gt;&lt;br /&gt;The second "DoubleAnimation" on "RenderTransform.CenterY" means that we will be moving the origin of our button. This time from 0 (the top) to 110 (which is actually a little bit below the bottom of our 100 unit Canvas -- the Canvas is a special container in that you can actually draw outside of its boundaries).&lt;br /&gt;&lt;br /&gt;Let's take a step back for a moment and talk about animation. What you will notice is that we do not have any timers specified here. To perform this animation in the WinForms world, we would use a timer, and then perform some action on every tick (such as moving an image a few pixels). Animation in XAML is declarative. This means that we tell it what we want to do (move from here to there and take 0.3 seconds to do it) and not how to do it (move 3 pixels each 100 milliseconds). The animation declaration itself is just changing a Property on the element. In this case, we are making changes to the empty RenderTransform that we defined earlier. The "DoubleAnimation" denotes that we are changing a Property that is of type Double (specifically the RenderTransfor.ScaleY and RenderTransform.CenterY).&lt;br /&gt;&lt;br /&gt;These two animations together will result in our Target being "hit" and falling down.&lt;br /&gt;&lt;br /&gt;The next 2 "DoubleAnimations" are basically doing the opposite. Note that these both have a BeginTime of "0:0:3", which means that this section of the animation will start after 3 seconds have elapsed. This will return our Target to the upright position after 3 seconds.&lt;br /&gt;&lt;br /&gt;You'll have to run it yourself to see the final result. Here's a screen shot of things in action:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_tXOq_FsazuI/SbWxSMgL38I/AAAAAAAAAB8/Hb0Uf1StIuM/s1600-h/Step5-screenshot.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5311346261705351106" style="WIDTH: 350px; HEIGHT: 370px" alt="" src="http://3.bp.blogspot.com/_tXOq_FsazuI/SbWxSMgL38I/AAAAAAAAAB8/Hb0Uf1StIuM/s400/Step5-screenshot.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Round Up&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;So, what we've seen here is a pretty impressive application for not having any C# code. In fact, we could have started with a VB project and come up with exactly the same results. We were able to declaratively program the behavior using XAML only -- and all in less than 120 lines. We took advantage of the lookless controls by replacing the default template and style with our own. With a little bit of C# code, we could turn this into a full fledged Shooting Gallery. But I'll leave that to you.&lt;br /&gt;&lt;br /&gt;Happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-7829900728591769439?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/7829900728591769439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/03/wpf-xaml-sample.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7829900728591769439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/7829900728591769439'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/03/wpf-xaml-sample.html' title='Target Practice - WPF / XAML Sample'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_tXOq_FsazuI/SbWvhtJSwbI/AAAAAAAAAAc/Zs-SfTpzL5s/s72-c/Intro-step.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-2133688749970360526</id><published>2009-03-01T15:07:00.000-08:00</published><updated>2009-03-12T06:44:31.218-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>What I Like About WPF</title><content type='html'>Windows Presentation Foundation (WPF) is the future of Rich Client (or Smart Client or Fat Client or whatever term is in fashion) programming in .NET. Microsoft is using WPF for the UI in Visual Studio 2010. If you are like me, then you still haven't had a chance to work with it extensively (due to constraints of my day-job). But, if you are like me, you are also very excited about the technology -- and not just because of the eye candy (although that is an added bonus; albeit a potentially dangerous one).&lt;br /&gt;&lt;br /&gt;Note: this isn't an introduction to WPF. I have some resources listed below if you want more info. So, here's what I like...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Declarative Programming Model&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;You can do quite a bit of the UI work in the XAML itself (XAML stands for eXtensible Application Markup Lanuage -- for more information, look for an intro to XAML). This UI work includes triggers, animations, and data bindings. Sure, you can do the work in your C# (or VB) code, but it's nice to be able to put it into the XAML.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Data Binding&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;I write business applications for a living -- that means pretty much everything requires some sort of data access. There are several WPF data binding features that seem to combine the best of WinForms data binding and ASP.NET WebForms data binding, plus some new features thrown in.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Binding to the container&lt;/strong&gt;&lt;br /&gt;Since you can bind the DataContext (your data source) to a UI container (which is pretty much everything -- see below), every child element can use that DataContext implicitly.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Good Support for value converters&lt;/strong&gt;&lt;br /&gt;IValueConverter is nothing new, but I have seen several WPF demos that use it in the data binding, making things dead simple. For example, you can use a value converter to convert a bank balance (an integer) to a brush (red for negative values, black for positive). In your bindings, you can bind the Brush on a TextBox directly to the bank balance, and the value converter takes care of the rest.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Binding to static resources&lt;/strong&gt;&lt;br /&gt;You can use data binding syntax to connect properties to static resources that are either defined locally to the page or globally to the application. As a programmer, you need to do less internal context switching since the syntax is the same regardless of whether you are binding to a static resource or a dynamic data context.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Binding from one element property to another&lt;/strong&gt;&lt;br /&gt;I'm not sure why I like this so much, but for some reason I do. If you need to display the same data twice on a page (like in a master / detail or selection / detail relationship), you can bind the Content property of one element ot the Content property (or any other property) of another.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Commands&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Coming from the Delphi programming world, I always wondered where the concept of Actions went in C# (after all, Anders Heilsberg was the architect of both languages). Commands allow you to hook up several UI elements to the same command. For example, you can hook up a menu item, tool bar item, and a button to a single Command (such as Save). This lets you enable or disable the Command, and it will affect all connected UI elements. (Also, you have centralized code which is always good.)&lt;br /&gt;&lt;br /&gt;Now let's move on to some more visual features. (I'm skipping the eye-candy at this point to focus on usability.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Most controls are also containers&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;This adds immense flexibility to the UI designer. You have full control over layout of a button that has both an image and text. Anyone who has fought with the layout of an image button in WinForms will greatly appreciate this.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Flexible layout and resolution independence&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;If you pay attention to your layout, you can design an UI that is usable on both a 23" desktop monitor and a 9" netbook. This will seem somewhat familiar to web developers. Plus, if you focus on using vector graphics (as opposed to bitmaps), then you can get good scaling without aliasing (i.e. "jaggies").&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Templates and styles&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;This seems very comfortable to web developers who use CSS. But it is incredibly more powerful. I'll be focusing on this in a future post.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;"Lookless" controls&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;None of the WPF UI controls have a built in rendering. Instead, they have default templates. This means you can replace the default with your own template to make a control appear however you want. Because the base control is "lookless", it means that all of the functionality (such as "Click" on a button) is separated from the rendering; so, you can replace the visual rendering without impacting the underlying functionality.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Lack of a DataGrid&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;This one may sound weird. Most of the WPF forums are littered with developers complaining about the lack of a data grid. There is even a CodePlex project to implement one. But I have found the lack of a DataGrid to be an opportunity.&lt;br /&gt;&lt;br /&gt;In my applications, I generally use data grids because they are easy -- not because they are the best way to present the information to the user. I have started to think about the power of the ListView. By using containers and templates (including data templates), I have full control over how I present the data, and it's dead simple.&lt;br /&gt;&lt;br /&gt;"Dead simple" is the key. Most of the things that I've mentioned are possible to do in WinForms, but you end up jumping through hoops to accomplish them. WPF makes these things "dead simple." If you're curious about alternatives to displaying data (without a Data Grid), then check out some of Billy Hollis' web casts (see below for links).&lt;br /&gt;&lt;br /&gt;So, that's why I am excited about WPF. If you are, too, then you can check out these resources:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://windowsclient.net/"&gt;The Official Microsoft WPF and Windows Forms Site&lt;/a&gt;&lt;br /&gt;This site is loaded with tutorials, samples, downloads, and lots of info.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dnrtv.com/"&gt;dnrTV&lt;/a&gt;&lt;br /&gt;This site has web casts (generally about an hour long) on all sorts of .NET topics. As mentioned above, Billy Hollis has done some excellent episodes:&lt;br /&gt;&lt;a href="http://www.dnrtv.com/default.aspx?showNum=115"&gt;dnrTV - Episode 115&lt;/a&gt; - Billy Hollis: Getting Smart with WPF&lt;br /&gt;&lt;a href="http://www.dnrtv.com/default.aspx?showNum=128"&gt;dnrTV - Episode 128&lt;/a&gt; - Billy Hollis: XAML for Developers Part 1&lt;br /&gt;&lt;a href="http://www.dnrtv.com/default.aspx?showNum=129"&gt;dnrTV - Episode 129&lt;/a&gt; - Billy Hollis: XAML for Developers Part 2&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.apress.com/book/view/1590599551"&gt;Pro WPF in C# 2008: Windows Presentation Foundation with .NET 3.5, Second Edition - Matthew MacDonald&lt;/a&gt;&lt;br /&gt;This is an excellent (large) book. It's around 1000 pages, and has lots of great information and samples. There is also a VB version of this book if that is your language of choice.&lt;br /&gt;&lt;br /&gt;I'll be digging in to specific WPF topics as time goes on, so stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-2133688749970360526?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/2133688749970360526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/03/what-i-like-about-wpf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2133688749970360526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/2133688749970360526'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/03/what-i-like-about-wpf.html' title='What I Like About WPF'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5359546512544809971.post-1611145402378704380</id><published>2009-02-21T23:30:00.000-08:00</published><updated>2009-02-22T19:19:13.141-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>What's this all about?</title><content type='html'>I am not an expert.&lt;br /&gt;&lt;br /&gt;Computer programming is about constant learning.   I like to think that I'm competent in my field (currently doing .NET programming).  But with the depth and breadth of the technologies, it's also very easy to feel lost and inadequate.  Still, I keep moving forward and keep learning new things along the way.  If I ever get to the point when I've come to the end of another project and I haven't come across some new technique or optimization along the way, then it probably means that it's time to move on to another field.&lt;br /&gt;&lt;br /&gt;But I don't see that happening for a while.&lt;br /&gt;&lt;br /&gt;I wrote my first program in 1985 on a knock-off Apple ][.  I was 14 at the time.  So, that puts me squarely between the old-timers who talk about punch cards and big iron, and the newcomers who have never had a computer with a floppy drive.  Over the years, I've used various programming tools and languages, including BASIC, C++, Visual Basic, Java, Delphi and C#.  In addition, I've used various web technologies, such as HTML, JavaScript, PHP, Visual InterDev, ASP, ASP.NET, and even dabbled in assembly (just for the "fun" of it).&lt;br /&gt;&lt;br /&gt;My professional programming career began in 2000.  I was fortunate enough to have been given access to good training, knowledgeable colleagues, and access to the occasional technical conference.  I'm also an avid reader and can usually be found with some 600 page tome in my bag.&lt;br /&gt;&lt;br /&gt;So, what's this all about?  My goal is to help other programmers take a step up.  Together, we will be looking at various topics ranging from general programming techniques (such as common design patterns) to specific technologies (such as WCF and WPF) to application architecture.  The focus will be on those elements that have made me more effective as a programmer.  But I will also include mistakes that I've made along the way.  Many times, basic tenets become clear when you look at the way &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; to do things.&lt;br /&gt;&lt;br /&gt;Be prepared to think.  And above all, keep learning.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5359546512544809971-1611145402378704380?l=jeremybytes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeremybytes.blogspot.com/feeds/1611145402378704380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeremybytes.blogspot.com/2009/02/whats-this-all-about.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1611145402378704380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5359546512544809971/posts/default/1611145402378704380'/><link rel='alternate' type='text/html' href='http://jeremybytes.blogspot.com/2009/02/whats-this-all-about.html' title='What&apos;s this all about?'/><author><name>Jeremy</name><uri>http://www.blogger.com/profile/06749690234470413216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
