<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>David Kline : Tips and Tricks</title><link>http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx</link><description>Tags: Tips and Tricks</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Presentation tip: Showing code</title><link>http://blogs.msdn.com/davidklinems/archive/2007/12/22/presentation-tip-showing-code.aspx</link><pubDate>Sat, 22 Dec 2007 21:41:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6837539</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/6837539.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=6837539</wfw:commentRss><description>&lt;p&gt;Since MEDC 2005, I have been tapped to present sessions many times.&amp;#160; Over the past three years, I have learned a lot and have grown as a presenter.   &lt;br /&gt;    &lt;br /&gt;When I was first getting started, I attended my first speaker training course.&amp;#160; Speaker training is a one-on-one class where you meet with your coach and he/she observes your presentation technique.&amp;#160; I found the experience extremely valuable and make a point to re-take training every year.    &lt;br /&gt;    &lt;br /&gt;One of the most valuable pieces of advice I was given is in how to best configure Visual Studio for code readability in a presentation hall.&amp;#160; This advice applies to all audience and room sizes: from 16 person conference rooms to lecture halls that seat 400 or more.     &lt;br /&gt;    &lt;br /&gt;Whenever I am preparing for a presentation (or am helping a new presenter prepare), I set Visual Studio's Font and Color settings as follows:     &lt;br /&gt;    &lt;br /&gt;Font: Lucida Console     &lt;br /&gt;Font size: 16-24 (depending on room size and projector resolution)     &lt;br /&gt;    &lt;br /&gt;Text color: Black     &lt;br /&gt;Background color: White     &lt;br /&gt;    &lt;br /&gt;Highlighted text color: Black     &lt;br /&gt;Highlighted text background color: Yellow     &lt;br /&gt;    &lt;br /&gt;It is amazing the difference these settings can make in code readability for your audience.     &lt;br /&gt;    &lt;br /&gt;One note on code layout.&amp;#160; When using large fonts (20) and small resolutions (1024x768), it is very important to format your code to avoid scrolling as much as possible.&amp;#160; Placing each argument on its own line is perhaps the best advise I can give here.&amp;#160; This way, the amount of side-to-side scrolling is minimized (there will still be some when enum / variable names are long).&amp;#160; The example below shows my typical demo code formatting (it is very similar to what I use on this site).     &lt;br /&gt;    &lt;br /&gt;&lt;code&gt;public DemoMethod(String arg1,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Int32 arg2,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Boolean arg3)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // local variables       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; try       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; String result = DemoHelperClass.AStaticMethodWithManyArgs(&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; arg1,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; arg2,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; arg3,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var1,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var2,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var3);       &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // additional code       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; catch(Exception e)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // handler code       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;}&lt;/code&gt;     &lt;br /&gt;    &lt;br /&gt;Ad you can see, the method the demo is calling has a pretty long name.&amp;#160; For this reason, all of the arguments are on their own lines.&amp;#160; Depending on the resolution of the screen, you may wish to further limit the horizontal scrolling by reformatting as below.     &lt;br /&gt;    &lt;br /&gt;&lt;code&gt;String result =&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DemoHelperClass.AStaticMethodWithManyArgs(       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; arg1,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; arg2,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; arg3,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var1,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var2,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var3);       &lt;br /&gt;&lt;/code&gt;    &lt;br /&gt;It may look a bit odd when you are developing the demo, however it will be much easier to read for the audience.&amp;#160; And it has a nice side-effect: it's also better for reviewing printed copies of the code.     &lt;br /&gt;    &lt;br /&gt;Take care and Happy Holidays!     &lt;br /&gt;-- DK     &lt;br /&gt;    &lt;br /&gt;&lt;font size="1"&gt;Disclaimer(s):      &lt;br /&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6837539" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category></item><item><title>Quick Tip: Add files to Visual Studio projects the easy way</title><link>http://blogs.msdn.com/davidklinems/archive/2007/12/18/quick-tip-add-files-to-visual-studio-projects-the-easy-way.aspx</link><pubDate>Wed, 19 Dec 2007 01:58:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6800215</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/6800215.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=6800215</wfw:commentRss><description>&lt;p&gt;Here's another in my series of &amp;quot;why didn't I know this feature was there&amp;quot;.    &lt;br /&gt;    &lt;br /&gt;While I was doing a technical review last week, I learned about a much easier way to add files to my Visual Studio projects.     &lt;br /&gt;    &lt;br /&gt;In the solution explorer&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Select a project &lt;/li&gt;    &lt;li&gt;Click the &amp;quot;Show all files&amp;quot; button &lt;/li&gt;    &lt;li&gt;Right-click on the desired file (will be shown with an empty document icon) &lt;/li&gt;    &lt;li&gt;Click the &amp;quot;Include in project&amp;quot; menu item &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This is so much easier than my usual technique (Add | Existing Item...).    &lt;br /&gt;    &lt;br /&gt;Take care!     &lt;br /&gt;-- DK     &lt;br /&gt;    &lt;br /&gt;&lt;font size="1"&gt;[Edit: fix spelling]      &lt;br /&gt;      &lt;br /&gt;Disclaimer(s):       &lt;br /&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6800215" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>Quick Tip: Debugging Smart Device Unit Tests</title><link>http://blogs.msdn.com/davidklinems/archive/2007/11/12/quick-tip-debugging-smart-device-unit-tests.aspx</link><pubDate>Mon, 12 Nov 2007 21:54:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6147256</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/6147256.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=6147256</wfw:commentRss><description>&lt;p&gt;While browsing &lt;a href="http://msdn2.microsoft.com"&gt;MSDN&lt;/a&gt; today, I came upon a handy article that I wanted to share.&amp;#160;&amp;#160; Titled &lt;a href="http://msdn2.microsoft.com/en-us/library/bb513875(VS.90).aspx"&gt;'How to: Debug while Running a Smart Device Unit Test&lt;/a&gt;', it provides step by step instructions on debugging your test projects.     &lt;br /&gt;    &lt;br /&gt;There is one additional step I would like to add to those listed in the article.     &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;table bordercolor="#800080" cellspacing="0" cellpadding="2" width="60%" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="398"&gt;&lt;strong&gt;WARNING&lt;/strong&gt;: Using Remote Registry Editor incorrectly can cause serious problems that may require you to hard reset your device. Microsoft cannot guarantee that problems resulting from the incorrect use of Remote Registry Editor can be solved. Use Remote Registry Editor at your own risk.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;   &lt;br /&gt;7. Disable support for attaching to managed processes     &lt;br /&gt;To do this, use the Visual Studio Remote Registry Editor:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;a. Navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework      &lt;br /&gt;b. Set the value of Managed Debugger\AttachEnabled to 0       &lt;br /&gt;-or-       &lt;br /&gt;Delete the Managed Debugger node&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Take care!    &lt;br /&gt;-- DK     &lt;br /&gt;    &lt;br /&gt;&lt;font face="Arial" size="1"&gt;Disclaimer(s):      &lt;br /&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.       &lt;br /&gt;The information contained within this post is in relation to beta software.&amp;#160; Any and all details are subject to change.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6147256" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>Quick Tip: Getting the Collection of Checked ListView Items</title><link>http://blogs.msdn.com/davidklinems/archive/2007/06/18/quick-tip-getting-the-collection-of-checked-listview-items.aspx</link><pubDate>Mon, 18 Jun 2007 21:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3387821</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/3387821.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=3387821</wfw:commentRss><description>&lt;P&gt;Have you ever created a ListView control and wanted to get the collection of items that the user has checked?&amp;nbsp; While I was working on my demo for MEDC, that was one of the things that I needed to be able to do.&amp;nbsp; If I were writing my application for the .NET Framework, I would get the collection of items via the ListView.CheckedItems property.&amp;nbsp; When I looked up ListView in the MSDN documentation, I found that the CheckedItems property is not supported on the &lt;A href="http://blogs.msdn.com/netcfteam" mce_href="http://blogs.msdn.com/netcfteam"&gt;.NET Compact Framework&lt;/A&gt;.&amp;nbsp; As a result, I was going to need to create the collection myself.&amp;nbsp; Or was I?&lt;BR&gt;&lt;BR&gt;Since the application that I was writing was a demonstration of the cool new features of .NET Compact Framework version 3.5, I decided to try my hand a using Language Integrated Query, specifically LINQ to Objects.&amp;nbsp; The resulting code was small, worked well and was quite easy to read.&amp;nbsp; Let's take a look at what I wrote.&lt;BR&gt;&lt;CODE&gt;&lt;BR&gt;public static List&amp;lt;ListViewItem&amp;gt; GetCheckedListViewItems(ListView lv)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;ListViewItem&amp;gt; checkedItems = (from ListViewItem lvi in lv.Items&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;where (true == lvi.Checked)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select lvi).ToList();&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return checkedItems;&lt;BR&gt;}&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;The method above is based on my Lunch Launcher demo application, as shown during the What's New in .NET Compact Framework version 3.5 session that I delivered at MEDC 2007 last month.&amp;nbsp;&amp;nbsp; How does it work?&amp;nbsp; First, we specify that we are interested in the ListViewItem objects contained within the ListView.Items property.&lt;BR&gt;&lt;CODE&gt;&lt;BR&gt;from ListViewItem lvi in lv.Items&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;Next, we define the condition under which we are interested in the item, in our case when the item has been checked by the user.&lt;BR&gt;&lt;CODE&gt;&lt;BR&gt;where (true == lvi.Checked)&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;Then we select the item.&lt;BR&gt;&lt;CODE&gt;&lt;BR&gt;select lvi&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;Lastly, we call the ToList method to have the selected items returned to us as a List&amp;lt;ListViewItem&amp;gt;.&lt;BR&gt;&lt;BR&gt;Pretty neat and much nicer to read than a foreach loop.&amp;nbsp; If you have installed the &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=1343d537-a62f-4a6e-9727-7791bf4cc2bd&amp;amp;DisplayLang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=1343d537-a62f-4a6e-9727-7791bf4cc2bd&amp;amp;DisplayLang=en"&gt;beta of .NET Compact Framework version 3.5&lt;/A&gt;, give LINQ a try and see how it can make your applications easier to write.&lt;BR&gt;&lt;BR&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT face=Arial size=1&gt;[Edit: fix formatting]&lt;BR&gt;&lt;BR&gt;Disclaimers:&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3387821" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/GUI/default.aspx">GUI</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>Quick Tip: Using XPath to find nodes by attribute value</title><link>http://blogs.msdn.com/davidklinems/archive/2007/03/13/quick-tip-using-xpath-to-find-nodes-by-attribute-value.aspx</link><pubDate>Tue, 13 Mar 2007 21:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1874604</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/1874604.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=1874604</wfw:commentRss><description>&lt;P&gt;There are some things that I can just remember: phone numbers, locker combinations, and the like.&amp;nbsp; There are others that I have to lookup again and again and again.&amp;nbsp; XPath query syntax is one of the latter items.&amp;nbsp; Today, I'd like to talk a little about XPath queries.&lt;BR&gt;&lt;BR&gt;The following XML contains a collection of "Friend" nodes.&amp;nbsp; Each node has attributes for name and birth date.&amp;nbsp; To keep this post to a reasonable length, I am going to limit the XML to 5 nodes.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;&amp;lt;MyFriends&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Friend name="Sam" birthMonth="July"&amp;nbsp;birthDay="16" birthYear="1974" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Friend name="Pam" birthMonth="April"&amp;nbsp;birthDay="7" birthYear="1967" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Friend name="George" birthMonth="February"&amp;nbsp;birthDay="2" birthYear="1981" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Friend name="John" birthMonth="April"&amp;nbsp;birthDay="11" birthYear="1972" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Friend name="Martha" birthMonth="August"&amp;nbsp;birthDay="3" birthYear="1974" /&amp;gt;&lt;BR&gt;&amp;lt;/MyFriends&amp;gt;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;After loading this XML into an XmlDocument, I can use XPath to query for the nodes of interest.&lt;BR&gt;&lt;BR&gt;Since April is coming soon, I would like to get a list of my friends who has a birthday that month.&amp;nbsp; To do so, I query for Friend nodes where the value of the birthMonth attribute is "April".&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;// load the xml file into an XmlDocument&lt;BR&gt;XmlDocument doc = new XmlDocument();&lt;BR&gt;doc.Load("myfriends.xml");&lt;BR&gt;XmlElement rootNode = doc.DocumentElement;&lt;BR&gt;&lt;BR&gt;// select the friends who have a birthday in April&lt;BR&gt;String query = "Friend[@birthMonth='April']";&lt;BR&gt;XmlNodeList friends = rootNode.SelectNodes(query);&lt;BR&gt;&lt;BR&gt;foreach(XmlElement friend in friends)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO: display a reminder to buy a birthday card&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;When the above snippet is run, two friends are returned: Pam and John.&amp;nbsp; The application can retrieve the desired information from the node and display an appropriate reminder.&lt;BR&gt;&lt;BR&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;Edit: Fix grammar&lt;BR&gt;&lt;BR&gt;Disclaimer(s):&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1874604" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/XML/default.aspx">XML</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>No ParameterizedThreadStart?  No problem.</title><link>http://blogs.msdn.com/davidklinems/archive/2007/01/26/no-parameterizedthreadstart-no-problem.aspx</link><pubDate>Fri, 26 Jan 2007 23:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1537936</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/1537936.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=1537936</wfw:commentRss><description>The .NET Compact Framework is a subset of the .NET Framework.&amp;nbsp; As such, there are features and functionality that exist in the .NET Framework that do not in the .NET Compact Framework.&amp;nbsp; One such feature is ParameterizedThreadStart.&lt;BR&gt;&lt;BR&gt;If your ThreadStart delegate needs data provided by the caller you can create a wrapper object for the method.&amp;nbsp; To get the data to the delegate, you pass the it as arguments to your wrapper object's constructor.&amp;nbsp; The delegate then accesses the data as member variables when performing its work.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;//--------------------------------------------------------------------- &lt;BR&gt;//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY &lt;BR&gt;//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE &lt;BR&gt;//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A &lt;BR&gt;//PARTICULAR PURPOSE. &lt;BR&gt;//---------------------------------------------------------------------&lt;BR&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Wrapper object for worker ThreadStart delegate&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;class ThreadStartDelegateWrapper&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Number of worker iterations&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Int32 m_Iterations;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Constructor&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="iterations&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Number of worker iterations&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/param&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ThreadStartDelegateWrapper(Int32 iterations)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_Iterations = iterations;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Worker thread delegate&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Worker()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(Int32 i = 0; i &amp;lt; this.m_Iterations; i++)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do some work&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;} // end of ThreadStartDelegateWrapper class&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;By creating an instance of the above class, you can pass your desired iterations to the Worker method.&amp;nbsp; &lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;// create the wrapper object, passing in the desired number of iterations&lt;BR&gt;ThreadStartDelegateWrapper wrapper = new ThreadStartDelegateWrapper(15);&lt;BR&gt;&lt;BR&gt;// create and start the thread&lt;BR&gt;ThreadStart ts = new ThreadStart(wrapper.Worker);&lt;BR&gt;Thread t = new Thread(ts);&lt;BR&gt;t.Start();&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;For clarity, the above example was shown on multiple lines.&amp;nbsp; I have often written the above on a single line.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;new Thread(new ThreadStart(new ThreadStartDelegateWrapper(15).Worker)).Start();&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;Disclaimer(s):&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1537936" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category></item><item><title>Quick Tip: Identifing the interfaces that an object implements</title><link>http://blogs.msdn.com/davidklinems/archive/2006/12/05/quick-tip-identifing-the-interfaces-that-an-object-implements.aspx</link><pubDate>Tue, 05 Dec 2006 22:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1212958</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/1212958.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=1212958</wfw:commentRss><description>Have you ever wondered what type an object is?&amp;nbsp; How about what interfaces the object implements?&amp;nbsp; Using the .NET Framework and .NET Compact Framework, this information is very easy to determine.&lt;BR&gt;&lt;BR&gt;The first thing we need to know about an object is it's type.&amp;nbsp; Every object, including Object, has a method called GetType().&amp;nbsp; For a given Object (obj), I get the Type (objType).&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;Type objType = obj.GetType();&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;GetType naturally returns a Type object.&amp;nbsp; The Type object is, to me, one of the most useful objects in .NET.&amp;nbsp; From the Type object, you can determine if the object is public, is a generic type, is abstract, and more.&amp;nbsp; You can also get the name of the type.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;String objTypeName = objType.ToString();&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;When I called the above lines in a simple test application, the value of objTypeName was "System.Collections.Generic.List`1[System.String]", which tells me that obj is a List&amp;lt;String&amp;gt;.&lt;BR&gt;&lt;BR&gt;Once we have the type of our object, we can get the list of interfaces implemented by the object (List&amp;lt;String&amp;gt;).&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;Type[] objInterfaces = objType.GetInterfaces();&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;To continue my example, by iterating over objInterfaces I see that List&amp;lt;String&amp;gt; implements:&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;System.Collections.Generic.IList`1[System.String]&lt;BR&gt;System.Collections.Generic.ICollection`1[System.String]&lt;BR&gt;System.Collections.Generic.IEnumerable`1[System.String]&lt;BR&gt;System.Collections.IList&lt;BR&gt;System.Collections.ICollection&lt;BR&gt;System.Collections.IEnumerable&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Knowing the interfaces implemented by a type can be useful in a variety of applications; from diagnostic tools to applications supporting plugins and more.&amp;nbsp; &lt;BR&gt;&lt;BR&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;Disclaimer(s):&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1212958" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>Quick Tip - Sharing code between multiple projects in Visual Studio 2005</title><link>http://blogs.msdn.com/davidklinems/archive/2006/11/29/quick-tip-sharing-code-between-multiple-projects-in-visual-studio-2005.aspx</link><pubDate>Thu, 30 Nov 2006 04:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1175010</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/1175010.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=1175010</wfw:commentRss><description>I have long been an advocate for putting common code into an assembly that is shared by applications needing the functionality.&amp;nbsp; That said, there are times where the separate assembly approach is not appropriate.&amp;nbsp; For those situations, today's tip may help make code sharing easier.&lt;BR&gt;&lt;BR&gt;I have a project (called TestApp) that targets the .NET Compact Framework version 2.&amp;nbsp; In the TestApp project, there is a file called Helper.cs which implements a class containing static methods that I use throughout the TestApp project.&lt;BR&gt;&lt;BR&gt;While working on TestApp, I decide that a .NET Framework (for desktop PCs) version would be nice to have.&amp;nbsp; Since I already have Helper.cs written, I would like to use the existing version.&amp;nbsp; I had previously chosen to not use an assembly for these helpers, so I&amp;nbsp;add the existing file to my new project.&amp;nbsp; &lt;BR&gt;&lt;BR&gt;I would prefer to not create a duplicate of this file as maintaining changes between the two copies can be time consuming and error prone.&amp;nbsp; Fortunately, Visual Studio 2005 has a great feature to allow for file sharing between projects -- you can add an existing file as a link.&amp;nbsp; Here's how: 
&lt;OL&gt;
&lt;LI&gt;In the project where you wish to add the file, right click the project name in the &lt;STRONG&gt;Solution Explorer&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Select &lt;STRONG&gt;Add&lt;/STRONG&gt; and then &lt;STRONG&gt;Existing Item...&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;In the &lt;STRONG&gt;Add Existing Item&lt;/STRONG&gt; dialog, navigate to the desired file&lt;/LI&gt;
&lt;LI&gt;Click the downward pointing arrow next to the &lt;STRONG&gt;Add&lt;/STRONG&gt; button and select &lt;STRONG&gt;Add As Link&lt;/STRONG&gt;.&lt;BR&gt;Once added to a project, linked files are easy to identify by the small arrow in the lower-left corner of the file icon in the Solution Explorer.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;My new project now has a reference to the original Helper.cs and any changes I make to it, from either project, are reflected in both projects.&lt;/P&gt;
&lt;TABLE class="" borderColor=#800080 cellSpacing=0 cellPadding=2 width="50%" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;B&gt;Note:&lt;/B&gt; It is important to remember that if you are sharing a file between different versions of the .NET Framework, you need to verify that any changes made are compatible with all projects using the file.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;Enjoy!&lt;BR&gt;-- DK&lt;FONT size=1&gt;&lt;BR&gt;&lt;BR&gt;Disclaimer(s):&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1175010" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>Quick Tip: Specifying a field's name when using the XmlSerializer</title><link>http://blogs.msdn.com/davidklinems/archive/2006/11/08/quick-tip-specifying-a-field-s-name-when-using-the-xmlserializer.aspx</link><pubDate>Wed, 08 Nov 2006 23:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1039693</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/1039693.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=1039693</wfw:commentRss><description>Last month, I wrote about how to &lt;A href="http://blogs.msdn.com/davidklinems/archive/2006/10/02/Quick-Tip_3A00_-Serializing-an-Object-Field-as-an-XML-Attribute.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2006/10/02/Quick-Tip_3A00_-Serializing-an-Object-Field-as-an-XML-Attribute.aspx"&gt;instruct the XmlSerializer to create an XML attribute for fields in an object&lt;/A&gt;.&amp;nbsp; Today, I'd like to talk about how to specify the name used to represent a field in the resulting XML.&lt;BR&gt;&lt;BR&gt;By default, when an object is serialized, fields are serialized into nodes with names that match the name of the field.&amp;nbsp; When an instance of the example TestData object(below) is serialized&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;public class TestData&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Int32 TestID;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String Description;&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;the TestID and Description fields become&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;&amp;lt;TestID&amp;gt;0&amp;lt;/TestID&amp;gt;&lt;BR&gt;&amp;lt;Description&amp;gt;Sample test description.&amp;lt;/Description&amp;gt;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;At times, it may be desirable to change the default naming behavior.&amp;nbsp; To change the name, we decorate the TestID field with an XmlElement attribute.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;[XmlElement(ElementName="ID")]&lt;BR&gt;public Int32 TestID;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;After serialization, the XML contains&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;&amp;lt;ID&amp;gt;0&amp;lt;/ID&amp;gt;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;This same technique also works with the XmlAttribute attribute.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;[XmlAttribute(AttributeName="ID")]&lt;BR&gt;public Int32 TestID;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Creates an attribute called ID (highlighted in &lt;FONT color=#800080&gt;purple&lt;/FONT&gt;) in the TestData node.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;&amp;lt;TestData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" &lt;FONT color=#800080&gt;ID="0"&lt;/FONT&gt;&amp;gt;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Enjoy!,&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;Disclaimers:&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1039693" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/XML/default.aspx">XML</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>'const' vs 'static readonly'</title><link>http://blogs.msdn.com/davidklinems/archive/2006/10/27/const-vs-static-readonly.aspx</link><pubDate>Fri, 27 Oct 2006 23:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:883856</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/883856.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=883856</wfw:commentRss><description>I'm a big fan of reusing code whenever and wherever possible.&amp;nbsp; A long time ago, I wrote an assembly that provided common methods and data to some applications I was writing.&amp;nbsp; When I first wrote the assembly, I exposedthe common data as public fields decorated with the &lt;CODE&gt;const&lt;/CODE&gt; keyword, as shown in the example below.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;public class HelperData&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public const Int32 Iterations = 5;&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;When I used the field, in my application, I saw the expected results, and checked in my code.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;The value of HelperData.Iterations is 5&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Later, I needed to update my application (increase the number of iterations), so remembering that I had put the iteration count in my helper assembly, I changed the code and deployed the new dll.&amp;nbsp; When I ran my application, the iteration count did not change, it was still using the old value (5).&amp;nbsp; Scratching my head, I tried building and deploying my dll again with the exact same result.&lt;BR&gt;&lt;BR&gt;When I looked at my application's &lt;A href="http://blogs.msdn.com/davidklinems/archive/2006/09/27/774433.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2006/09/27/774433.aspx"&gt;IL&lt;/A&gt;, I found my problem.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;ldstr "The value of HelperData.Iterations is "&lt;BR&gt;ldc.i4.5&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;When my application was built, the literal value (5) of the HelperData.Iterations field was compiled into the executable (&lt;CODE&gt;ldc.i4.5&lt;/CODE&gt;).&amp;nbsp; My application used the original value because it was never actually referencing the field in the helper assembly.&amp;nbsp; This made sense once I thought about it.&amp;nbsp; Because I had defined my field as a constant, the compiler optimized away the assembly reference.&lt;BR&gt;&lt;BR&gt;To fix the problem (I really did want the assembly reference), I changed my helper class to expose Iterations as a &lt;CODE&gt;static readonly&lt;/CODE&gt; field.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;public class HelperData&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static readonly Int32 Iterations = 5;&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;After rebuilding the application referencing the updated assembly, I see my expected output.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;The value of HelperData.Iterations is 5&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;When I change the value of Iterations (to 43), rebuild and update just the helper assembly, my application reflects the update.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;The value of HelperData.Iterations is 43&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Examining the IL shows why.&amp;nbsp; &lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;ldstr "The value of HelperData.Iterations is "&lt;BR&gt;ldsfld int32 [Helper]Helper.HelperData::Iterations&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Instead of compiling in the literal value, as was done above, we now see that the IL instructions are loading the field value from the helper assembly (&lt;CODE&gt;ldsfld int32 [Helper]Helper.HelperData::Iterations&lt;/CODE&gt;).&lt;BR&gt;&lt;BR&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;Disclaimers:&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=883856" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category></item><item><title>Is it a field or a property?</title><link>http://blogs.msdn.com/davidklinems/archive/2006/10/13/is-it-a-field-or-a-property.aspx</link><pubDate>Fri, 13 Oct 2006 23:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:823206</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/823206.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=823206</wfw:commentRss><description>I very much value &lt;A class="" href="http://blogs.msdn.com/davidklinems/archive/2006/01/24/517073.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2006/01/24/517073.aspx"&gt;code reviews&lt;/A&gt;, as long time readers can attest.&amp;nbsp; During these reviews, I have often found myself wondering whether a given line references a field or a property.&amp;nbsp; When reading isolated portions of code, properties can be easily mistaken for fields.&amp;nbsp; &lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;Player player = new Player("Someone");&lt;BR&gt;String name = player.Name;&lt;BR&gt;player.Age = 22;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;By looking at only the two lines above, is it possible to tell, conclusively, whether or not Name and Age are properties or fields on the Player object?&amp;nbsp; I assert that it is not.&amp;nbsp; Let's take a closer look at fields and properties.&lt;BR&gt;&lt;BR&gt;A field is a variable exposed by the object.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;public class Player&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String Name; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Int32 Age;&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Properties are methods (a getter and/or a setter).&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;public class Player&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private String m_Name;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String Name&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get{ return this.m_Name; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Int32 m_Age;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Int32 Age&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get{ return this.m_Age; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; set&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if( 18 &amp;gt;= value )&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentException("Player must be at least 18 years old.");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_Age = value; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Each of the above examples would allow for code that looks like the original client snippet.&lt;BR&gt;&lt;BR&gt;I typically use properties, in part, because they provide my client code with the same easy to use syntax for setting and retrieving values from a class that I get from fields with the added benefit of data validation when setting the value.&lt;BR&gt;&lt;BR&gt;Take care,&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;[Edit: fix error in example]&lt;BR&gt;[Edit: add "m_" to private class members]&lt;BR&gt;&lt;BR&gt;Disclaimers:&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=823206" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category></item><item><title>Separating Application Logic and Data Presentation layers</title><link>http://blogs.msdn.com/davidklinems/archive/2006/10/05/Separating-Application-Logic-and-Data-Presentation-layers.aspx</link><pubDate>Fri, 06 Oct 2006 00:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:794721</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/794721.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=794721</wfw:commentRss><description>I'm a big advocate of separating an application's logic from it's user interface.&amp;nbsp; By keeping the logic separate from the data presentation layer (UI), it becomes easy to swap out either component with minimal impact on the other.&amp;nbsp; In addition to ease of replacing components, keeping the user interface separate from the application logic avoids blocking the UI during expensive operations.&lt;BR&gt;&lt;BR&gt;Today, I'm going to revisit the .NET Compact Framework WebCrawler sample from Visual Studio 2005 and show how it uses event handlers to allow the application logic (Crawler class) to communicate with the user interface.&amp;nbsp; The source code for the WebCrawler sample can be downloaded from &lt;A href="http://msdn2.microsoft.com/en-us/library/t7w4afa2.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/t7w4afa2.aspx"&gt;here&lt;/A&gt;.&lt;BR&gt;&lt;BR&gt;&lt;B&gt;Simple Status Notification - EventHandler&lt;BR&gt;&lt;/B&gt;For simple notifications requiring no data, such as the CrawlFinishedEvent in the WebCrawler sample, an event handler is defined in the application logic class.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;public event EventHandler CrawlFinishedEvent;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;When the application logic wishes to inform clients that the event has occurred, it checks to see if there are any registered event handlers and, if so, sends the notification.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;if (null != CrawlFinishedEvent)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CrawlFinishedEvent(this, EventArgs.Empty);&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;The UI class (MainForm in the WebCrawler) registers for the event.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;this.crawler.CrawlFinishedEvent += new EventHandler(HandleCrawlFinishedEvent);&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;The form implements a method to handle the event.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Process CrawlFinished events&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;private void HandleCrawlFinishedEvent(object sender, EventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // update the user interface as appropriate&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;&lt;B&gt;Sending Data In The Notification - Creating a Custom EventHandler&lt;BR&gt;&lt;/B&gt;If the notification requires some data data, such as the CurrentPageEvent&amp;nbsp; in the WebCrawler sample, a custom event handler delegate will need to be defined.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;public delegate void CurrentPageEventHandler(object sender, CurrentPageEventArgs e);&lt;BR&gt;public event CurrentPageEventHandler CurrentPageEvent;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Notice the CurrentPageEventArgs argument -- this is where the custom data is placed.&amp;nbsp; In the WebCrawler sample, the CurerntPageEventArgs is defined as&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Class providing the current page address to the CurrentPageEvent handler&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;public class CurrentPageEventArgs : EventArgs&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string pageAddressValue;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// The address of the current page(ex: &lt;A href="http://www.microsoft.com/" mce_href="http://www.microsoft.com"&gt;http://www.microsoft.com&lt;/A&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string PageAddress&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.pageAddressValue;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Constructor&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="page"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// The address of the current page&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/param&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public CurrentPageEventArgs(string page)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.pageAddressValue = page;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;As with the above simple status notification example, when the application logic wishes to inform clients that the event occurred, it checks registrations and sends the notification, passing the data in the event arguments.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;if (CurrentPageEvent != null)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CurrentPageEvent(this,&amp;nbsp; new CurrentPageEventArgs(str));&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Registering for the custom event is similar to the above simple notification example.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;this.crawler.CurrentPageEvent += new Crawler.CurrentPageEventHandler(HandleCurrentPageEvent);&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;The implementation of the event handler method needs to match the custom event handler delegate.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Process CurrentPage events&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;private void HandleCurrentPageEvent(object sender, CurrentPageEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // update the user interface as appropriate&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;By building and running the WebCrawler sample under the Visual Studio 2005 debugger, you can watch the event notifications and how the sample handles &lt;A href="http://blogs.msdn.com/davidklinems/archive/2005/03/21/400102.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2005/03/21/400102.aspx"&gt;updating user interface elements in a multi-threaded application&lt;/A&gt;.&lt;BR&gt;&lt;BR&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;Disclaimer(s):&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=794721" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/GUI/default.aspx">GUI</category></item><item><title>Quick Tip: Serializing an Object Field as an XML Attribute</title><link>http://blogs.msdn.com/davidklinems/archive/2006/10/02/Quick-Tip_3A00_-Serializing-an-Object-Field-as-an-XML-Attribute.aspx</link><pubDate>Tue, 03 Oct 2006 00:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:782023</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/782023.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=782023</wfw:commentRss><description>The addition of the XML Serializer is one of the reasons I really love version 2 of the .NET Compact Framework.&amp;nbsp; I use the XML Serializer in very nearly every application I write; to save application state, data files, etc.&amp;nbsp; By default, the XML Serializer will create a child node for every field in a type.&amp;nbsp; For example, the following object&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;public class TestData&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Int32 TestID;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String Description;&lt;BR&gt;}&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;becomes&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;&amp;lt;TestData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Description&amp;gt;Sample test description.&amp;lt;/Description&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;TestID&amp;gt;0&amp;lt;/TestID&amp;gt;&lt;BR&gt;&amp;lt;/TestData&amp;gt;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;There are times that you may wish to serialize one or more fields as attributes on the object's node (ex: reduce the size of the XML).&amp;nbsp; By decorating the TestID field with an &lt;A href="http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlattributeattribute.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlattributeattribute.aspx"&gt;XmlAttribute&lt;/A&gt; attribute, the TestID field&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;[XmlAttribute()]&lt;BR&gt;public Int32 TestID;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;now becomes an attribute (highlighted in &lt;FONT color=#800080&gt;purple&lt;/FONT&gt;) on the TestData node.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;&amp;lt;TestData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" &lt;FONT color=#800080&gt;TestID="0"&lt;/FONT&gt;&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Description&amp;gt;Sample test description.&amp;lt;/Description&amp;gt;&lt;BR&gt;&amp;lt;/TestData&amp;gt;&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;Disclaimers:&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=782023" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/XML/default.aspx">XML</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>Quick tip: Filtering input to a TextBox control</title><link>http://blogs.msdn.com/davidklinems/archive/2006/09/25/771140.aspx</link><pubDate>Mon, 25 Sep 2006 23:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:771140</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/771140.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=771140</wfw:commentRss><description>Sometimes, it's the little things that take the longest to work out, so I thought I'd start a "Quick tips" series.&amp;nbsp;&amp;nbsp;Quick tips are intended to be short and solve a very specific issue.&lt;BR&gt;&lt;BR&gt;I was talking with &lt;A href="https://blogs.msdn.com:443/markprenticems"&gt;Mark Prentice&lt;/A&gt; today and we were looking at filtering a TextBox control so that it only accepted numeric characters.&amp;nbsp; As it works out, this is a very easy thing to do with the .NET Compact Framework.&lt;BR&gt;&lt;BR&gt;To filter input that is entered into a TextBox, we need to implement a KeyPress event handler.&amp;nbsp; When you encounter a character you wish to exclude, set the value of &lt;A href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.keypresseventargs.handled.aspx"&gt;KeyPressEventArgs.Handled&lt;/A&gt; to true.&amp;nbsp; To determine which characters to handle, the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemcharclasstopic.asp"&gt;Char&lt;/A&gt; type has several handy static methods that help determine&amp;nbsp;what type&amp;nbsp;of character was entered into a TextBox.&amp;nbsp; Since Mark and I were interested in limiting the input to only numeric characters, I will use &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemcharclasstopic.asp"&gt;Char.IsDigit&lt;/A&gt; in my example.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;private void textBox1_KeyPress(object sender, KeyPressEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // only allow numeric characters&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; all other KeyPress events are cancelled&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Handled = !Char.IsDigit(e.KeyCode);&lt;BR&gt;}&lt;/CODE&gt; 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;[Edit: fix sentence]&lt;BR&gt;&lt;BR&gt;Disclaimer(s): This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face="Courier New"&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=771140" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Quick+Tips/default.aspx">Quick Tips</category></item><item><title>Command Line Debugging Revisited - Part 5: The X Command</title><link>http://blogs.msdn.com/davidklinems/archive/2006/09/13/752632.aspx</link><pubDate>Wed, 13 Sep 2006 22:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:752632</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/752632.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=752632</wfw:commentRss><description>In the previous installment, I talked about &lt;A href="http://blogs.msdn.com/davidklinems/archive/2006/08/25/724718.aspx"&gt;attaching to running processes using MDbg&lt;/A&gt;.&amp;nbsp; As part of that discussion, I used the &lt;CODE&gt;X&lt;/CODE&gt; command.&amp;nbsp; Today, I'd like to spend a little time on &lt;CODE&gt;X&lt;/CODE&gt;.&amp;nbsp; The &lt;CODE&gt;X command&lt;/CODE&gt; is one of those great features of MDbg that I think is worth the price of admission by itself.&lt;BR&gt;&lt;BR&gt;From MDbg's online help:&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;mdbg&amp;gt; ? x&lt;BR&gt;abbrev: x&lt;BR&gt;Usage: x [-c numSymbols] [module[!pattern]]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Displays functions matching [pattern] for a module. If numSymbols is&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; provided, the output is limited to the given number. If !regex is not&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; provided, all functions are displayed. If module is not provided either,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; all loaded modules are displayed. Symbols (~#) may be used to set&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; breakpoints using the "break" command.&lt;BR&gt;Example: x mscorlib!*String*&lt;BR&gt;See Also:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;I won't be going into all of the features of &lt;CODE&gt;X&lt;/CODE&gt; here, rather I will demonstrate the ways that I most often use the command.&lt;BR&gt;&lt;BR&gt;I'll use the Visual Studio 2005 WebCrawler sample application to show some of the cool features of &lt;CODE&gt;X&lt;/CODE&gt; in action.&amp;nbsp; Once connected to the debuggee (via &lt;CODE&gt;&lt;A href="http://blogs.msdn.com/davidklinems/archive/2006/07/13/665023.aspx"&gt;Run&lt;/A&gt;&lt;/CODE&gt; or &lt;CODE&gt;&lt;A href="http://blogs.msdn.com/davidklinems/archive/2006/08/25/724718.aspx"&gt;Attach&lt;/A&gt;&lt;/CODE&gt;), we are ready to go.&lt;BR&gt;&lt;BR&gt;When debugging using command line tools, one of the most challenging tasks is getting the fully qualified names of functions correct when setting breakpoints.&amp;nbsp; Namespaces can get long (as you will see in my examples) and the casing of names must be 100% accurate.&amp;nbsp; &lt;CODE&gt;X&lt;/CODE&gt; makes this much much easier, as we will see.&lt;BR&gt;&lt;BR&gt;&lt;B&gt;Getting the list of loaded modules&lt;BR&gt;&lt;/B&gt;In it's simplest form, &lt;CODE&gt;X&lt;/CODE&gt; will display the modules loaded in your application.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;[p#:0, t#:0] mdbg&amp;gt; x&lt;BR&gt;Please specify module.&lt;BR&gt;Loaded Modules:&lt;BR&gt;:0 mscorlib.dll#0 (no symbols loaded)&lt;BR&gt;:1 webcrawler.exe#0&lt;BR&gt;:2 System.Windows.Forms.dll#0 (no symbols loaded)&lt;BR&gt;:3 System.dll#0 (no symbols loaded)&lt;BR&gt;:4 System.Drawing.dll#0 (no symbols loaded)&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;If you are a user of the Modules window in the Visual Studio 2005 debugger, as I am, this usage will be very familiar and handy.&amp;nbsp; The one useful thing missing from this display is the path from where the symbols were loaded, which the Visual Studio 2005 Modules window provides.
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Setting a breakpoint on a function&lt;BR&gt;&lt;/B&gt;My favorite way to use &lt;CODE&gt;X&lt;/CODE&gt; is to help me set breakpoints on functions.&amp;nbsp; As I mentioned earlier, entering fully qualified names exactly right can be challenging, especially when they get long.&amp;nbsp; &lt;CODE&gt;X&lt;/CODE&gt; really helps here by allowing us to search for functions by name fragments.&amp;nbsp; In the example below, I am looking for anything (methods, classes, etc) with "Crawl" as part of the name.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;[p#:0, t#:0] mdbg&amp;gt; x webcrawler.exe!*Crawl*&lt;BR&gt;~0. Microsoft.Samples.NetCF.Crawler.add_CurrentPageEvent(value)&lt;BR&gt;~1. Microsoft.Samples.NetCF.Crawler.remove_CurrentPageEvent(value)&lt;BR&gt;~2. Microsoft.Samples.NetCF.Crawler.add_PageFoundEvent(value)&lt;BR&gt;~3. Microsoft.Samples.NetCF.Crawler.remove_PageFoundEvent(value)&lt;BR&gt;~4. Microsoft.Samples.NetCF.Crawler.add_CrawlFinishedEvent(value)&lt;BR&gt;~5. Microsoft.Samples.NetCF.Crawler.remove_CrawlFinishedEvent(value)&lt;BR&gt;~6. Microsoft.Samples.NetCF.Crawler..ctor(startingPage,noProxy)&lt;BR&gt;~7. Microsoft.Samples.NetCF.Crawler.Start()&lt;BR&gt;~8. Microsoft.Samples.NetCF.Crawler.Stop()&lt;BR&gt;~9. Microsoft.Samples.NetCF.Crawler.PageIsHtml(pageAddress,status)&lt;BR&gt;~10. Microsoft.Samples.NetCF.Crawler.GetPageData(pageUri,pageData)&lt;BR&gt;~11. Microsoft.Samples.NetCF.Crawler.GetPageLinks(pageUri,pageBody,tag,attribute,links)&lt;BR&gt;~12. Microsoft.Samples.NetCF.Crawler.Crawl()&lt;BR&gt;~13. Microsoft.Samples.NetCF.Crawler.CurrentPageEventHandler..ctor(object,method)&lt;BR&gt;~14. Microsoft.Samples.NetCF.Crawler.CurrentPageEventHandler.Invoke(sender,e)&lt;BR&gt;~15. Microsoft.Samples.NetCF.Crawler.CurrentPageEventHandler.BeginInvoke(sender,e,callback,object)&lt;BR&gt;~16. Microsoft.Samples.NetCF.Crawler.CurrentPageEventHandler.EndInvoke(result)&lt;BR&gt;~17. Microsoft.Samples.NetCF.MainForm.HandleCrawlFinishedEvent(sender,e)&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;When we search by a part of the name, we get a numbered list of symbols that match our fragment.&amp;nbsp; If the list contains our desired function, we can set a breakpoint very easily by specifying the index of the function within the list.&amp;nbsp; The results above returned all methods from the Crawler class as well as the event handler for the CrawlFinishedEvent within the MainForm class.&amp;nbsp; I am interested in debugging the event handler, so I'll set a breakpoint there.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;[p#:0, t#:0] mdbg&amp;gt; b ~17&lt;BR&gt;Breakpoint #1 bound (:1!Microsoft.Samples.NetCF.MainForm::HandleCrawlFinishedEvent(+0))&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;This is much more convenient than retyping the name (&lt;CODE&gt;Microsoft.Samples.NetCF.MainForm.HandleCrawlFinishedEvent&lt;/CODE&gt;), or using the Mark - Copy - Paste feature of the Windows Command Prompt.&amp;nbsp; It is important to be sure to use the tilde (~) when specifying the list index.&amp;nbsp; Forgetting to do so will attempt to set a breakpoint by line number within the current source file as shown in the example below.&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;[p#:0, t#:0] mdbg&amp;gt; b 17&lt;BR&gt;Breakpoint #2 bound (line 17 in MainForm.cs)&lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;Enjoy!&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT size=1&gt;Disclaimer(s): This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=752632" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Tips+and+Tricks/default.aspx">Tips and Tricks</category></item></channel></rss>