<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Paul Sheriff's Blog for the Real World</title><link>http://weblogs.asp.net/psheriff/default.aspx</link><description>This blog is to share my tips and tricks garnered over 25+ years in the IT industry</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PaulSheriffsOuterCircleBlog" /><feedburner:info uri="paulsheriffsoutercircleblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Creating Collections of Entity Objects using Reflection</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/94Nk9FEYPz8/creating-collections-of-entity-objects-using-reflection.aspx</link><pubDate>Wed, 06 Mar 2013 22:43:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9953142</guid><dc:creator>psheriff</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=9953142</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2013/03/06/creating-collections-of-entity-objects-using-reflection.aspx#comments</comments><description>In my last blog posts I have been showing you how to create collection of entity objects using code that is custom for each table and object you create. Well, if you use a little reflection code you can shrink this code quite a bit. Yes, we all know that...(&lt;a href="http://weblogs.asp.net/psheriff/archive/2013/03/06/creating-collections-of-entity-objects-using-reflection.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9953142" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/ADO.NET/default.aspx">ADO.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Reflection/default.aspx">Reflection</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2013/03/06/creating-collections-of-entity-objects-using-reflection.aspx</feedburner:origLink></item><item><title>Join PDSA at DevIntersection Conference - April 8 - 11, 2013</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/ad7VlmwUmbA/join-pdsa-at-devintersection-conference-april-8-11-2013.aspx</link><pubDate>Mon, 04 Mar 2013 17:07:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9943759</guid><dc:creator>psheriff</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=9943759</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2013/03/04/join-pdsa-at-devintersection-conference-april-8-11-2013.aspx#comments</comments><description>Use the Code 'PDSA' when registering and receive $50 off your registration! Top Microsoft Speakers Featured at DevIntersection &amp;amp; SQLIntersection, Including 3 Speakers from PDSA, Inc. Top Microsoft and third-party speakers, including PDSA's Paul Sheriff...(&lt;a href="http://weblogs.asp.net/psheriff/archive/2013/03/04/join-pdsa-at-devintersection-conference-april-8-11-2013.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9943759" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Conference/default.aspx">Conference</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2013/03/04/join-pdsa-at-devintersection-conference-april-8-11-2013.aspx</feedburner:origLink></item><item><title>Creating Collections of Entity Objects using LINQ and Field Method</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/TfN7Uq19cdI/creating-collections-of-entity-objects-using-linq-and-field-method.aspx</link><pubDate>Mon, 25 Feb 2013 17:02:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9912732</guid><dc:creator>psheriff</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=9912732</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2013/02/25/creating-collections-of-entity-objects-using-linq-and-field-method.aspx#comments</comments><description>Let’s now look at another advantage of using a DataTable. A lot of developers today are used to using LINQ. After loading data into a DataTable you can iterate using a foreach statement, or you can use LINQ to create a collection of entity objects. The...(&lt;a href="http://weblogs.asp.net/psheriff/archive/2013/02/25/creating-collections-of-entity-objects-using-linq-and-field-method.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9912732" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Field+Method/default.aspx">Field Method</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2013/02/25/creating-collections-of-entity-objects-using-linq-and-field-method.aspx</feedburner:origLink></item><item><title>Creating Collections of Entity Objects using LINQ</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/ZxSf7pbpJII/creating-collections-of-entity-objects-using-linq.aspx</link><pubDate>Mon, 11 Feb 2013 15:17:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9861777</guid><dc:creator>psheriff</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=9861777</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2013/02/11/creating-collections-of-entity-objects-using-linq.aspx#comments</comments><description>As discussed in my last two blog posts you have a variety of ways to create collections of Entity classes. Using a DataSet or DataTable is a little slower than using a DataReader, but in most cases the difference is in milliseconds so in a real world...(&lt;a href="http://weblogs.asp.net/psheriff/archive/2013/02/11/creating-collections-of-entity-objects-using-linq.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9861777" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/ADO.NET/default.aspx">ADO.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/LINQ/default.aspx">LINQ</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2013/02/11/creating-collections-of-entity-objects-using-linq.aspx</feedburner:origLink></item><item><title>Building Collections of Entity Classes using a DataReader</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/lRvdKUoGZHA/building-collections-of-entity-classes-using-a-datareader.aspx</link><pubDate>Tue, 29 Jan 2013 20:45:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9814212</guid><dc:creator>psheriff</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=9814212</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2013/01/29/building-collections-of-entity-classes-using-a-datareader.aspx#comments</comments><description>As discussed in the last blog post, it is a best practice to build entity classes. In the last post we filled a DataTable with Category data and then iterated over that DataTable to create a collection of Entity classes. In this blog post we will use...(&lt;a href="http://weblogs.asp.net/psheriff/archive/2013/01/29/building-collections-of-entity-classes-using-a-datareader.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9814212" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Entity+Classes/default.aspx">Entity Classes</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2013/01/29/building-collections-of-entity-classes-using-a-datareader.aspx</feedburner:origLink></item><item><title>Building Collections of Entity Classes</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/uxrOTRbw1p4/building-collections-of-entity-classes.aspx</link><pubDate>Tue, 29 Jan 2013 16:55:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9813569</guid><dc:creator>psheriff</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=9813569</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2013/01/29/building-collections-of-entity-classes.aspx#comments</comments><description>What is an Entity Class An Entity class has properties and typically no methods. An entity class is generally used to hold a single row of data from a table. So, if you have a Category table with the fields CategoryId, CategoryName and Description, you...(&lt;a href="http://weblogs.asp.net/psheriff/archive/2013/01/29/building-collections-of-entity-classes.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9813569" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Entity+Classes/default.aspx">Entity Classes</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2013/01/29/building-collections-of-entity-classes.aspx</feedburner:origLink></item><item><title>Creating a XAML Tile Control</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/gXZxGtWSMxQ/creating-a-xaml-tile-control.aspx</link><pubDate>Mon, 22 Oct 2012 17:13:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9176517</guid><dc:creator>psheriff</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=9176517</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/10/22/creating-a-xaml-tile-control.aspx#comments</comments><description>One of the navigation mechanisms used in Windows 8 and Windows Phone is a Tile. A tile is a large rectangle that can have words and pictures that a user can click on. You can build your own version of a Tile in your WPF or Silverlight applications using...(&lt;a href="http://weblogs.asp.net/psheriff/archive/2012/10/22/creating-a-xaml-tile-control.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9176517" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/WPF/default.aspx">WPF</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Tiles/default.aspx">Tiles</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/10/22/creating-a-xaml-tile-control.aspx</feedburner:origLink></item><item><title>A WPF Image/Text Button</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/0s2e_xtagiQ/a-wpf-image-text-button.aspx</link><pubDate>Mon, 01 Oct 2012 16:03:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9030135</guid><dc:creator>psheriff</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=9030135</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/10/01/a-wpf-image-text-button.aspx#comments</comments><description>Some of our customers are asking us to give them a Windows 8 look and feel for their applications. This includes things like buttons, tiles, application bars, and other features. In this blog post I will describe how to create a button that looks similar...(&lt;a href="http://weblogs.asp.net/psheriff/archive/2012/10/01/a-wpf-image-text-button.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9030135" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/WPF/default.aspx">WPF</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/User+Controls/default.aspx">User Controls</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/10/01/a-wpf-image-text-button.aspx</feedburner:origLink></item><item><title>A WPF Image  Button</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/JYSukR6RyFM/a-wpf-image-button.aspx</link><pubDate>Thu, 06 Sep 2012 20:15:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8896811</guid><dc:creator>psheriff</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=8896811</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/09/06/a-wpf-image-button.aspx#comments</comments><description>&lt;p&gt;Instead of a normal button with words, sometimes you want a button that is just graphical. Yes, you can put an Image control in the Content of a normal Button control, but you still have the button outline, and trying to change the style can be rather difficult. Instead I like creating a user control that simulates a button, but just accepts an image. Figure 1 shows an example of three of these custom user controls to represent minimize, maximize and close buttons for a borderless window. Notice the highlighted image button has a gray rectangle around it. You will learn how to highlight using the VisualStateManager in this blog post.&lt;/p&gt;&lt;p&gt;&lt;img style="width: 500px; height: 300px;" title="Figure 1" alt="Figure 1" src="http://www.pdsa.com/ImagesForBlog/WPFImageButton.jpg" width="500" height="300" mce_src="http://www.pdsa.com/ImagesForBlog/WPFImageButton.jpg"&gt;&lt;/p&gt;&lt;p&gt;Figure 1: Creating a custom user control for things like image buttons gives you complete control over the look and feel.&lt;/p&gt;&lt;p&gt;I would suggest you read my previous blog post on creating a custom Button user control as that is a good primer for what I am going to expand upon in this blog post. You can find this blog post at &lt;a href="http://weblogs.asp.net/psheriff/archive/2012/08/10/create-your-own-wpf-button-user-controls.aspx"&gt;http://weblogs.asp.net/psheriff/archive/2012/08/10/create-your-own-wpf-button-user-controls.aspx&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The User Control&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The XAML for this image button user control contains just a few controls, plus a Visual State Manager. The basic outline of the user control is shown below:&lt;/p&gt;&lt;p&gt;&amp;lt;Border Grid.Row="0"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name="borMain"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Style="{StaticResource pdsaButtonImageBorderStyle}"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseEnter="borMain_MouseEnter"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseLeave="borMain_MouseLeave"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseLeftButtonDown="borMain_MouseLeftButtonDown"&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;lt;VisualStateManager.VisualStateGroups&amp;gt;&lt;br&gt;&amp;nbsp; ... MORE XAML HERE ...&lt;br&gt;&amp;nbsp; &amp;lt;/VisualStateManager.VisualStateGroups&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;lt;Image Style="{StaticResource pdsaButtonImageImageStyle}"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Visibility="{Binding Path=Visibility}"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Source="{Binding Path=ImageUri}"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ToolTip="{Binding Path=ToolTip}" /&amp;gt;&lt;br&gt;&amp;lt;/Border&amp;gt;&lt;/p&gt;&lt;p&gt;There is a Border control named borMain and a single Image control in this user control. That is all that is needed to display the buttons shown in Figure 1. The definition for this user control is in a DLL named PDSA.WPF. The Style definitions for both the Border and the Image controls are contained in a resource dictionary names PDSAButtonStyles.xaml. Using a resource dictionary allows you to create a few different resource dictionaries, each with a different theme for the buttons.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The Visual State Manager&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;To display the highlight around the button as your mouse moves over the control, you will need to add a Visual State Manager group. Two different states are needed; MouseEnter and MouseLeave. In the MouseEnter you create a ColorAnimation to modify the BorderBrush color of the Border control. You specify the color to animate as “DarkGray”. You set the duration to less than a second. The TargetName of this storyboard is the name of the Border control “borMain” and since we are specifying a single color, you need to set the TargetProperty to “BorderBrush.Color”. You do not need any storyboard for the MouseLeave state. Leaving this VisualState empty tells the Visual State Manager to put everything back the way it was before the MouseEnter event.&lt;/p&gt;&lt;p&gt;&amp;lt;VisualStateManager.VisualStateGroups&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;VisualStateGroup Name="MouseStates"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;VisualState Name="MouseEnter"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Storyboard&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ColorAnimation &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; To="DarkGray"&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; Duration="0:0:00.1"&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; Storyboard.TargetName="borMain"&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; Storyboard.TargetProperty="BorderBrush.Color" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Storyboard&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/VisualState&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;VisualState Name="MouseLeave" /&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;/VisualStateGroup&amp;gt;&lt;br&gt;&amp;lt;/VisualStateManager.VisualStateGroups&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Writing the Mouse Events&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;To trigger the Visual State Manager to run its storyboard in response to the specified event, you need to respond to the MouseEnter event on the Border control. In the code behind for this event call the GoToElementState() method of the VisualStateManager class exposed by the user control. To this method you will pass in the target element (“borMain”) and the state (“MouseEnter”). The VisualStateManager will then run the storyboard contained within the defined state in the XAML.&lt;/p&gt;&lt;p&gt;private void borMain_MouseEnter(object sender, &lt;br&gt;&amp;nbsp;MouseEventArgs e)&lt;br&gt;{&lt;br&gt;&amp;nbsp; VisualStateManager.GoToElementState(borMain,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "MouseEnter", true);&lt;br&gt;}&lt;/p&gt;&lt;p&gt;You also need to respond to the MouseLeave event. In this event you call the VisualStateManager as well, but specify “MouseLeave” as the state to go to.&lt;/p&gt;&lt;p&gt;private void borMain_MouseLeave(object sender,&lt;br&gt;&amp;nbsp;MouseEventArgs e)&lt;br&gt;{&lt;br&gt;&amp;nbsp; VisualStateManager.GoToElementState(borMain, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "MouseLeave", true);&lt;br&gt;}&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The Resource Dictionary&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Below is the definition of the PDSAButtonStyles.xaml resource dictionary file contained in the PDSA.WPF DLL. This dictionary can be used as the default look and feel for any image button control you add to a window. &lt;/p&gt;&lt;p&gt;&amp;lt;ResourceDictionary&amp;nbsp; ... &amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;!-- ************************* --&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;!-- ** Image Button Styles ** --&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;!-- ************************* --&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;!-- Image/Text Button Border --&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;Style TargetType="Border"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Key="pdsaButtonImageBorderStyle"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Margin"&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; Value="4" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Padding"&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; Value="2" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="BorderBrush"&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; Value="Transparent" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="BorderThickness"&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; Value="1" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="VerticalAlignment"&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; Value="Top" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="HorizontalAlignment"&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; Value="Left" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Background"&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; Value="Transparent" /&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;!-- Image Button --&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;Style TargetType="Image"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Key="pdsaButtonImageImageStyle"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Width"&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; Value="40" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Margin"&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; Value="6" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="VerticalAlignment"&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; Value="Top" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="HorizontalAlignment"&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; Value="Left" /&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;br&gt;&amp;lt;/ResourceDictionary&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Using the Button Control&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Once you make a reference to the PDSA.WPF DLL from your WPF application you will see the “PDSAucButtonImage” control appear in your Toolbox. Drag and drop the button onto a Window or User Control in your application. I have not referenced the PDSAButtonStyles.xaml file within the control itself so you do need to add a reference to this resource dictionary somewhere in your application such as in the App.xaml.&lt;/p&gt;&lt;p&gt;&amp;lt;Application.Resources&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;ResourceDictionary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary.MergedDictionaries&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Source="/PDSA.WPF;component/PDSAButtonStyles.xaml" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ResourceDictionary.MergedDictionaries&amp;gt;&lt;br&gt;&amp;nbsp; &amp;lt;/ResourceDictionary&amp;gt;&lt;br&gt;&amp;lt;/Application.Resources&amp;gt;&lt;/p&gt;&lt;p&gt;This will give your buttons a default look and feel unless you override that dictionary on a specific Window or User Control or on an individual button. After you have given a global style to your application and you drag your image button onto a window, the following will appear in your XAML window.&lt;/p&gt;&lt;p&gt;&amp;lt;my:PDSAucButtonImage ... /&amp;gt;&lt;/p&gt;&lt;p&gt;There will be some other attributes set on the above XAML, but you simply need to set the x:Name, the ToolTip and ImageUri properties. You will also want to respond to the Click event procedure in order to associate an action with clicking on this button. In the sample code you download for this blog post you will find the declaration of the Minimize button to be the following:&lt;/p&gt;&lt;p&gt;&amp;lt;my:PDSAucButtonImage&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Name="btnMinimize"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Click="btnMinimize_Click"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ToolTip="Minimize Application"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ImageUri="/PDSA.WPF;component/Images/Minus.png" /&amp;gt;&lt;/p&gt;&lt;p&gt;The ImageUri property is a dependency property in the PDSAucButtonImage user control. The x:Name and the ToolTip we get for free. You have to create the Click event procedure yourself. This is also created in the PDSAucButtonImage user control as follows:&lt;/p&gt;&lt;p&gt;private void borMain_MouseLeftButtonDown(object sender, &lt;br&gt;&amp;nbsp;MouseButtonEventArgs e)&lt;br&gt;{&lt;br&gt;&amp;nbsp; RaiseClick(e);&lt;br&gt;}&lt;/p&gt;&lt;p&gt;public delegate void ClickEventHandler(object sender,&lt;br&gt;&amp;nbsp; RoutedEventArgs e);&lt;br&gt;public event ClickEventHandler Click;&lt;/p&gt;&lt;p&gt;protected void RaiseClick(RoutedEventArgs e)&lt;br&gt;{&lt;br&gt;&amp;nbsp; if (null != Click)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Click(this, e);&lt;br&gt;}&lt;/p&gt;&lt;p&gt;Since a Border control does not have a Click event you will create one by using the MouseLeftButtonDown on the border to fire an event you create called “Click”.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Creating your own image button control can be done in a variety of ways. In this blog post I showed you how to create a custom user control and simulate a button using a Border and Image control. With just a little bit of code to respond to the MouseLeftButtonDown event on the border you can raise your own Click event. Dependency properties, such as ImageUri, allow you to set attributes on your custom user control. Feel free to expand on this button by adding additional dependency properties, change the resource dictionary, and even the animation to make this button look and act like you want.&lt;/p&gt;&lt;p&gt;NOTE: You can download the sample code for this article by visiting my website at &lt;a href="http://www.pdsa.com/downloads"&gt;http://www.pdsa.com/downloads&lt;/a&gt;. Select “Tips &amp;amp; Tricks”, then select “A WPF Image&amp;nbsp; Button” from the drop down list.&lt;br&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8896811" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/WPF/default.aspx">WPF</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/09/06/a-wpf-image-button.aspx</feedburner:origLink></item><item><title>A Communication System for XAML Applications</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/5wAzReSsDMA/a-communication-system-for-xaml-applications.aspx</link><pubDate>Mon, 27 Aug 2012 21:15:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8872843</guid><dc:creator>psheriff</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=8872843</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/08/27/a-communication-system-for-xaml-applications.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;In any application, you want to keep the coupling between any two or more objects as loose as possible. Coupling happens when one class contains a property that is used in another class, or uses another class in one of its methods. If you have this situation, then this is called strong or tight coupling. One popular design pattern to help with keeping objects loosely coupled is called the Mediator design pattern. The basics of this pattern are very simple; avoid one object directly talking to another object, and instead use another class to mediate between the two. As with most of my blog posts, the purpose is to introduce you to a simple approach to using a message broker, not all of the fine details.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;IPDSAMessageBroker Interface&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;As with most implementations of a design pattern, you typically start with an interface or an abstract base class. In this particular instance, an Interface will work just fine. The interface for our Message Broker class just contains a single method “SendMessage” and one event “MessageReceived”.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public delegate void MessageReceivedEventHandler(&lt;BR&gt;&amp;nbsp;object sender, PDSAMessageBrokerEventArgs e);&lt;/P&gt;
&lt;P mce_keep="true"&gt;public interface IPDSAMessageBroker&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; void SendMessage(PDSAMessageBrokerMessage msg);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; event MessageReceivedEventHandler MessageReceived;&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;PDSAMessageBrokerMessage Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;As you can see in the interface, the SendMessage method requires a type of PDSAMessageBrokerMessage to be passed to it. This class simply has a MessageName which is a ‘string’ type and a MessageBody property which is of the type ‘object’ so you can pass whatever you want in the body. You might pass a string in the body, or a complete Customer object. The MessageName property will help the receiver of the message know what is in the MessageBody property.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class PDSAMessageBrokerMessage&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public PDSAMessageBrokerMessage()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public PDSAMessageBrokerMessage(string name, object body)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageName = name;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBody = body;&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public string MessageName { get; set; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public object MessageBody { get; set; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;PDSAMessageBrokerEventArgs Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;As our message broker class will be raising an event that others can respond to, it is a good idea to create your own event argument class. This class will inherit from the System.EventArgs class and add a couple of additional properties. The properties are the MessageName and Message. The MessageName property is simply a string value. The Message property is a type of a PDSAMessageBrokerMessage class.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class PDSAMessageBrokerEventArgs : EventArgs&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public PDSAMessageBrokerEventArgs()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public PDSAMessageBrokerEventArgs(string name, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDSAMessageBrokerMessage msg)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageName = name;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Message = msg;&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public string MessageName { get; set; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public PDSAMessageBrokerMessage Message { get; set; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;PDSAMessageBroker Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Now that you have an interface class and a class to pass a message through an event, it is time to create your actual PDSAMessageBroker class. This class implements the SendMessage method and will also create the event handler for the delegate created in your Interface.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class PDSAMessageBroker : IPDSAMessageBroker&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public void SendMessage(PDSAMessageBrokerMessage msg)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDSAMessageBrokerEventArgs args;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; args = new PDSAMessageBrokerEventArgs(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; msg.MessageName, msg);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RaiseMessageReceived(args);&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public event MessageReceivedEventHandler MessageReceived;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; protected void RaiseMessageReceived(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDSAMessageBrokerEventArgs e)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (null != MessageReceived)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageReceived(this, e);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;The SendMessage method will take a PDSAMessageBrokerMessage object as an argument. It then creates an instance of a PDSAMessageBrokerEventArgs class, passing to the constructor two items: the MessageName from the PDSAMessageBrokerMessage object and also the object itself. It may seem a little redundant to pass in the message name when that same message name is part of the message, but it does make consuming the event and checking for the message name a little cleaner – as you will see in the next section.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Create a Global Message Broker&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;In your WPF application, create an instance of this message broker class in the App class located in the App.xaml file. Create a public property in the App class and create a new instance of that class in the OnStartUp event procedure as shown in the following code:&lt;/P&gt;
&lt;P mce_keep="true"&gt;public partial class App : Application&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public PDSAMessageBroker MessageBroker { get; set; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; protected override void OnStartup(StartupEventArgs e)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.OnStartup(e);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBroker = new PDSAMessageBroker();&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Sending and Receiving Messages&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Let’s assume you have a user control that you load into a control on your main window and you want to send a message from that user control to the main window. You might have the main window display a message box, or put a string into a status bar as shown in Figure 1.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 623px; HEIGHT: 429px" title="Figure 1: The main window can receive and send messages" alt="Figure 1: The main window can receive and send messages" src="http://www.pdsa.com/ImagesForBlog/WPFMessageBroker1.jpg" width=623 height=429 mce_src="http://www.pdsa.com/ImagesForBlog/WPFMessageBroker1.jpg"&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Figure 1: The main window can receive and send messages&lt;/P&gt;
&lt;P mce_keep="true"&gt;The first thing you do in the main window is to hook up an event procedure to the MessageReceived event of the global message broker. This is done in the constructor of the main window:&lt;/P&gt;
&lt;P mce_keep="true"&gt;public MainWindow()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; InitializeComponent();&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; (Application.Current as App).MessageBroker.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageReceived += new MessageReceivedEventHandler(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBroker_MessageReceived);&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;One piece of code you might not be familiar with is accessing a property defined in the App class of your XAML application. Within the App.Xaml file is a class named App that inherits from the Application object. You access the global instance of this App class by using Application.Current. You cast Application.Current to ‘App’ prior to accessing any of the public properties or methods you defined in the App class. Thus, the code (Application.Current as App).MessageBroker, allows you to get at the MessageBroker property defined in the App class.&lt;/P&gt;
&lt;P mce_keep="true"&gt;In the MessageReceived event procedure in the main window (shown below) you can now check to see if the MessageName property of the PDSAMessageBrokerEventArgs is equal to “StatusBar” and if it is, then display the message body into the status bar text block control.&lt;/P&gt;
&lt;P mce_keep="true"&gt;void MessageBroker_MessageReceived(object sender,&lt;BR&gt;&amp;nbsp;&amp;nbsp; PDSAMessageBrokerEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; switch (e.MessageName)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; case "StatusBar":&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tbStatus.Text = e.Message.MessageBody.ToString();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;In the Page 1 user control’s Loaded event procedure you will send the message “StatusBar” through the global message broker to any listener using the following code:&lt;/P&gt;
&lt;P mce_keep="true"&gt;private void UserControl_Loaded(object sender, &lt;BR&gt;&amp;nbsp;RoutedEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; // Send Status Message&lt;BR&gt;&amp;nbsp; (Application.Current as App).MessageBroker.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendMessage(new PDSAMessageBrokerMessage("StatusBar",&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "This is Page 1"));&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;Since the main window is listening for the message ‘StatusBar’, it will display the value “This is Page 1” in the status bar at the bottom of the main window.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Sending a Message to a User Control&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;The previous example sent a message from the user control to the main window. You can also send messages from the main window to any listener as well. Remember that the global message broker is really just a broadcaster to anyone who has hooked into the MessageReceived event.&lt;/P&gt;
&lt;P mce_keep="true"&gt;In the constructor of the user control named ucPage1 you can hook into the global message broker’s MessageReceived event. You can then listen for any messages that are sent to this control by using a similar switch-case structure like that in the main window.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public ucPage1()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; InitializeComponent();&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; // Hook to the Global Message Broker&lt;BR&gt;&amp;nbsp; (Application.Current as App).MessageBroker.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageReceived += new MessageReceivedEventHandler(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBroker_MessageReceived);&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;void MessageBroker_MessageReceived(object sender, &lt;BR&gt;&amp;nbsp;PDSAMessageBrokerEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; // Look for messages intended for Page 1&lt;BR&gt;&amp;nbsp; switch (e.MessageName)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; case "ForPage1":&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show(e.Message.MessageBody.ToString());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;Once the ucPage1 user control has been loaded into the main window you can then send a message using the following code:&lt;/P&gt;
&lt;P mce_keep="true"&gt;private void btnSendToPage1_Click(object sender, &lt;BR&gt;&amp;nbsp;RoutedEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; PDSAMessageBrokerMessage arg = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new PDSAMessageBrokerMessage();&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; arg.MessageName = "ForPage1";&lt;BR&gt;&amp;nbsp; arg.MessageBody = "Message For Page 1";&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; // Send a message to Page 1&lt;BR&gt;&amp;nbsp; (Application.Current as App).MessageBroker.SendMessage(arg);&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;Since the MessageName matches what is in the ucPage1 MessageReceived event procedure, ucPage1 can do anything in response to that event. It is important to note that when the message gets sent it is sent to all MessageReceived event procedures, not just the one that is looking for a message called “ForPage1”. If the user control ucPage1 is not loaded and this message is broadcast, but no other code is listening for it, then it is simply ignored.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Remove Event Handler&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;In each class where you add an event handler to the MessageReceived event you need to make sure to remove those event handlers when you are done. Failure to do so can cause a strong reference to the class and thus not allow that object to be garbage collected. In each of your user control’s make sure in the Unloaded event to remove the event handler.&lt;/P&gt;
&lt;P mce_keep="true"&gt;private void UserControl_Unloaded(object sender,&lt;BR&gt;&amp;nbsp;RoutedEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if (_MessageBroker != null)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _MessageBroker.MessageReceived -= &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _MessageBroker_MessageReceived;&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Problems with Message Brokering&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;As with most “global” classes or classes that hook up events to other classes, garbage collection is something you need to consider. Just the simple act of hooking up an event procedure to a global event handler creates a reference between your user control and the message broker in the App class. This means that even when your user control is removed from your UI, the class will still be in memory because of the reference to the message broker. This can cause messages to still being handled even though the UI is not being displayed. It is up to you to make sure you remove those event handlers as discussed in the previous section. If you don’t, then the garbage collector cannot release those objects.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Instead of using events to send messages from one object to another you might consider registering your objects with a central message broker. This message broker now becomes a collection class into which you pass an object and what messages that object wishes to receive. You do end up with the same problem however. You have to un-register your objects; otherwise they still stay in memory. To alleviate this problem you can look into using the WeakReference class as a method to store your objects so they can be garbage collected if need be. Discussing Weak References is beyond the scope of this post, but you can look this up on the web.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Summary&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;In this blog post you learned how to create a simple message broker system that will allow you to send messages from one object to another without having to reference objects directly. This does reduce the coupling between objects in your application. You do need to remember to get rid of any event handlers prior to your objects going out of scope or you run the risk of having memory leaks and events being called even though you can no longer access the object that is responding to that event.&lt;/P&gt;
&lt;P mce_keep="true"&gt;NOTE: You can download the sample code for this article by visiting my website at &lt;A href="http://www.pdsa.com/downloads"&gt;http://www.pdsa.com/downloads&lt;/A&gt;. Select “Tips &amp;amp; Tricks”, then select “A Communication System for XAML Applications” from the drop down list.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8872843" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/WPF/default.aspx">WPF</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Silverlight+4/default.aspx">Silverlight 4</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/08/27/a-communication-system-for-xaml-applications.aspx</feedburner:origLink></item><item><title>A WPF Message Box you can Style</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/aWLaoEN4Eag/a-wpf-message-box-you-can-style.aspx</link><pubDate>Mon, 13 Aug 2012 19:39:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8841104</guid><dc:creator>psheriff</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=8841104</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/08/13/a-wpf-message-box-you-can-style.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;You go to great pains to add styles, colors, gradients, and a really cool look and feel to your WPF application only to have that ruined by the standard Windows message box as shown in Figure 1.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 624px; HEIGHT: 312px" title="Figure 1: The normal Windows message box just does not look right on a styled WPF application." alt="Figure 1: The normal Windows message box just does not look right on a styled WPF application." src="http://www.pdsa.com/ImagesForBlog/WPFMessageBox1.jpg" width=624 height=312 mce_src="http://www.pdsa.com/ImagesForBlog/WPFMessageBox1.jpg"&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Figure 1: The normal Windows message box just does not look right on a styled WPF application.&lt;/P&gt;
&lt;P mce_keep="true"&gt;What would be nice is if Microsoft offered a styled message box. But, they don’t. So it is up to us to create a window that we can style and do whatever we want with it. Thus, I can up with a message box that looks like Figure 2 and Figure 3.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 624px; HEIGHT: 312px" title="Figure 2: Creating your own dialog from a Window, a Text Block and a custom button control." alt="Figure 2: Creating your own dialog from a Window, a Text Block and a custom button control." src="http://www.pdsa.com/ImagesForBlog/WPFMessageBox2.jpg" width=624 height=312 mce_src="http://www.pdsa.com/ImagesForBlog/WPFMessageBox2.jpg"&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Figure 2: Creating your own dialog from a Window, a Text Block and a custom button control.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 624px; HEIGHT: 312px" title="Figure 3: You can completely change the theme of your button through the use of resource dictionaries." alt="Figure 3: You can completely change the theme of your button through the use of resource dictionaries." src="http://www.pdsa.com/ImagesForBlog/WPFMessageBox3.jpg" width=624 height=312 mce_src="http://www.pdsa.com/ImagesForBlog/WPFMessageBox3.jpg"&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Figure 3: You can completely change the theme of your button through the use of resource dictionaries.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;The PDSAMessageBoxView XAML&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;The first step in creating a custom message box is to add a new Window to your WPF project. You then need to set some styles to get a border-less window. You set the following attributes on your Window.&lt;/P&gt;
&lt;P mce_keep="true"&gt;WindowStyle="None" &lt;BR&gt;ShowInTaskbar="True" &lt;BR&gt;ResizeMode=”NoResize”&lt;BR&gt;AllowsTransparency="True" &lt;BR&gt;Background="Transparent"&lt;/P&gt;
&lt;P mce_keep="true"&gt;The WindowStyle attribute normally allows you to set a single border, three-D border, or a Tool Window border. Setting this attribute to None will eliminate the border. The ShowInTaskbar attribute is optional, but if you are doing a dialog window you probably want this window to show up in the Task Bar. Since this is a dialog window, you probably do not want to allow the user to resize this window, thus you set the ResizeMode to “NoResize”. The next two attributes, AllowsTransparency and Background work together. You must set AllowsTransparency to True to allow the Background to be set to Transparent. If you do not set these two attributes, then your border will still show up.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The listing that follows shows the complete XAML for the PDSAMessageBoxView.xaml file. This XAML file contains a Border, a Grid, a TextBlock for the message, and a StackPanel control with four PDSAucButton controls (see my previous blog post on how to create these buttons). All of the attributes for the border, the text block and the buttons are controlled via styles in a Resource Dictionary file. Using a resource dictionary allows you to create new resource dictionaries with different colors and other attributes to style the message box in any manner you see fit.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;lt;Window x:Class="PDSA.WPF.PDSAMessageBoxView"&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; xmlns:my="clr-namespace:PDSA.WPF"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WindowStyle="None"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AllowsTransparency="True"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Background="Transparent"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ResizeMode="NoResize"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowInTaskbar="True"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FontFamily="Segoe UI"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WindowStartupLocation="CenterScreen"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Height="300"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Width="420"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseLeftButtonDown="Window_MouseLeftButtonDown"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Deactivated="Window_Deactivated" &amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Window.Resources&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- Set style for PDSA Button --&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Style TargetType="my:PDSAucButton"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Effect"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value="{StaticResource pdsaMessageBoxButtonShadow}" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Width"&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; Value="80" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Window.Resources&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Border Style="{StaticResource pdsaMessageBoxBorder}"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Grid&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Grid.RowDefinitions&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;RowDefinition Height="*" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;RowDefinition Height="Auto" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Grid.RowDefinitions&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TextBlock Name="tbMessage"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Style="{StaticResource pdsaMessageBoxTextBlock}"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Text="Message goes here..."&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TextWrapping="Wrap" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;StackPanel Grid.Row="1"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Style="{StaticResource pdsaMessageBoxStackPanel}"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;my:PDSAucButton Text="Yes"&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; x:Name="btnYes"&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; Click="btnYes_Click" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;my:PDSAucButton Text="No"&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; x:Name="btnNo"&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; Click="btnNo_Click" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;my:PDSAucButton Text="OK"&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; x:Name="btnOk"&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; Click="btnOk_Click" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;my:PDSAucButton Text="Cancel"&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; x:Name="btnCancel"&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; Click="btnCancel_Click" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/StackPanel&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Grid&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Border&amp;gt;&lt;BR&gt;&amp;lt;/Window&amp;gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Styles for PDSAMessageBox Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;As mentioned previously, all of the styles for the PDSAMessageBoxView class are contained within a resource dictionary. There is one resource dictionary in the PDSA.WPF DLL where the PDSAMessageBoxView class is located. However, there is an additional resource dictionary in the main project with a blue theme as shown in Figure 3. The listing below is the complete resource dictionary for the gray message box theme.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;lt;ResourceDictionary ... &amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Background for Message Box --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;LinearGradientBrush x:Key="pdsaMessageBoxBackground"&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; StartPoint="0.5,0"&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; EndPoint="0.5,1"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="DarkSlateGray"&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; Offset="0" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="LightGray"&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; Offset="0.70" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="DarkSlateGray"&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; Offset="1" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/LinearGradientBrush&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Drop Shadow Effect for Message Box --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;DropShadowEffect Color="Black"&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; x:Key="pdsaMessageBoxDropShadow"&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; Opacity=".85"&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; ShadowDepth="16" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Drop Shadow for Message Box Buttons --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;DropShadowEffect x:Key="pdsaMessageBoxButtonShadow"&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; Color="Black"&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; ShadowDepth="8" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Border for Message Box --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Style TargetType="Border"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Key="pdsaMessageBoxBorder"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="CornerRadius"&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; Value="10" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="BorderBrush"&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; Value="Black" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="BorderThickness"&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; Value="3" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Margin"&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; Value="16" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Effect"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value="{StaticResource pdsaMessageBoxDropShadow}" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Background"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value="{StaticResource pdsaMessageBoxBackground}" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Buttons for Message Box --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Style TargetType="Button"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Key="pdsaMessageBoxButton"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Margin"&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; Value="10" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Width"&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; Value="70" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Height"&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; Value="35" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="FontSize"&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; Value="14" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="FontWeight"&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; Value="SemiBold" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Effect"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value="{StaticResource pdsaMessageBoxButtonShadow}" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Text Block for Message Box --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Style TargetType="TextBlock"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Key="pdsaMessageBoxTextBlock"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Foreground"&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; Value="Black" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Margin"&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; Value="20,40,20,10" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="FontSize"&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; Value="28" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="TextWrapping"&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; Value="Wrap" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- StackPanel for Message Box --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Style TargetType="StackPanel"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Key="pdsaMessageBoxStackPanel"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Orientation"&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; Value="Horizontal" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="HorizontalAlignment"&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; Value="Right" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Margin"&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; Value="8" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;BR&gt;&amp;lt;/ResourceDictionary&amp;gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Feel free to modify any of the above styles to make the message box look like however you want.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;The PDSAMessageBox Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Just like .NET has the MessageBox class in order to display the dialog, I have created a PDSAMessageBox class with a Show method as well. I made the Show method with the same parameters as the MessageBox class in order to help you make an easier transition to the PDSAMessageBox class. However, I do not use any of the MessageBoxImage parameters, so you will need to remove any of these, or add an image to this view if you so desire. Below is the PDSAMessageBox class with the static Show methods defined.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class PDSAMessageBox&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public static MessageBoxResult Show(string message)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Show(message, string.Empty, MessageBoxButton.OK);&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public static MessageBoxResult Show(string message, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string caption)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Show(message, caption, MessageBoxButton.OK);&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public static MessageBoxResult Show(string message, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string caption, MessageBoxButton buttons)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBoxResult result = MessageBoxResult.None;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDSAMessageBoxView dialog = new PDSAMessageBoxView();&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dialog.Title = caption;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dialog.tbMessage.Text = message;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dialog.Buttons = buttons;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // If just an OK button, allow the user to just &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // move away from the dialog&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (buttons == MessageBoxButton.OK)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dialog.Show();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dialog.ShowDialog();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = dialog.Result;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;All of the Show methods end up calling just a single Show that takes care of displaying the PDSAMessageBoxView dialog. One thing I did change in my Show method is that if the user pops up a message box with just an “Ok” button, I do allow the user to navigate away from this dialog without pressing the Ok button. To me, it does not make sense to force the user to press a single button on the form. This could have side-effects however, if you have code immediately following the call to the Show method because this is no longer a modal dialog. Again, feel free to modify this code if you do not like this functionality.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Calling the PDSAMessageBox&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Below is an example of calling the PDSAMessageBox. The Show method will return a MessageBoxResult enumeration. There was no need to change the return value from that of the normal MessageBox class. This code can be found in the sample that you download along with this blog post.&lt;/P&gt;
&lt;P mce_keep="true"&gt;private void btnOKOnly_Click(object sender, RoutedEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; PDSAMessageBox.Show("This just displays an OK Button", &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "OK", MessageBoxButton.OK);&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;private void btnYesNo_Click(object sender, RoutedEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; MessageBoxResult result;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; result = PDSAMessageBox.Show("Do you want to Quit?",&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Quit?", MessageBoxButton.YesNo);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; MessageBox.Show("Result is " + result.ToString());&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Summary&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Creating your own dialog box is very easy using just a little bit of XAML, some styles and a class with a few methods. Break up your styles into resource dictionaries in order to have the flexibility to modify the look and feel of your dialogs. Keep your dialog boxes and buttons in a separate DLL in order to make it easy to reuse your controls.&lt;/P&gt;
&lt;P mce_keep="true"&gt;NOTE: You can download the sample code for this article by visiting my website at &lt;A href="http://www.pdsa.com/downloads"&gt;http://www.pdsa.com/downloads&lt;/A&gt;. Select “Tips &amp;amp; Tricks”, then select “A WPF Message Box you can Style” from the drop down list.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8841104" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/WPF/default.aspx">WPF</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/08/13/a-wpf-message-box-you-can-style.aspx</feedburner:origLink></item><item><title>Create your own WPF Button User Controls</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/8epPJg7kSLk/create-your-own-wpf-button-user-controls.aspx</link><pubDate>Fri, 10 Aug 2012 18:54:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8832597</guid><dc:creator>psheriff</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=8832597</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/08/10/create-your-own-wpf-button-user-controls.aspx#comments</comments><description>&lt;P&gt;In Figure 1 you can see examples of the standard WPF Button controls. You can add a drop shadow and you can change the color, but you can’t change much else without creating a whole new control template. For example, you are unable to modify the BorderBrush or the BorderThickness properties of the Button control. Additionally you might want to use some other animation than the default, which again requires you to change the control template.&lt;/P&gt;
&lt;P&gt;Sometimes all you want to do is to just have some simple buttons where you can modify the border brush and the thickness and have different color options via styles. I have found that instead of working with the whole control template thing, just creating a User Control is sometimes much easier.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 520px; HEIGHT: 350px" title="Figure 1: The Normal WPF Buttons can not be styled very well" alt="Figure 1: The Normal WPF Buttons can not be styled very well" src="http://www.pdsa.com/ImagesForBlog/WPFButton.jpg" width=520 height=350 mce_src="http://www.pdsa.com/ImagesForBlog/WPFButton.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Figure 1: The normal WPF Buttons cannot be styled very well.&lt;/P&gt;
&lt;P&gt;There are many ways to create custom buttons and there are advantages and disadvantages to each way. The purpose of this blog post is to present one method that is easily understood by almost any XAML programmer, and hopefully to those new to XAML as well. User controls have been around since the Visual Basic 4.0 days. Most developers understand the value of using user controls. With XAML user controls you can put these controls into a WPF User Control Library or a Silverlight Class Library and reference those DLLs from any WPF or Silverlight application. This gives you great reusability. By using resource dictionaries and appropriate use of styles you can make your user controls very customizable as shown in Figure 1. The 2nd row of buttons you see are the same button user control with just different styles applied.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The User Control&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The XAML for your Button user control is actually very simple. You use a single Border control and a TextBlock control within that Border as shown in Listing 1.&lt;/P&gt;
&lt;P&gt;&amp;lt;Border Name="hoverBorder"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Style="{DynamicResource hoverBorder}"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseDown="hoverBorder_MouseDown"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseUp="hoverBorder_MouseUp"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseEnter="hoverBorder_MouseEnter"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseLeave="hoverBorder_MouseLeave"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MouseLeftButtonUp="hoverBorder_MouseLeftButtonUp"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;TextBlock Text="{Binding Path=Text}"&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; Name="tbText"&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; Style="{DynamicResource hoverTextBlock}" /&amp;gt;&lt;BR&gt;&amp;lt;/Border&amp;gt;&lt;/P&gt;
&lt;P&gt;Listing 1: The XAML for a Button user control is just a Border and TextBlock&lt;/P&gt;
&lt;P&gt;The definition for this user control is in a DLL named PDSA.WPF. Notice that there are Style definitions for both the Border and the TextBlock. We used styles contained in a resource dictionary as opposed to setting up dependency properties for each individual attribute that we might want to set. This allows us to create a few different resource dictionaries, each with a different theme for the buttons. You can see the three different themes we created in Figure 1. The Gray Style button uses a resource dictionary that is contained in the PDSA.WPF DLL. The other two styles are in the main project and can be referenced from your App.xaml or from within the Window/User Control where you need the button.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Changing Colors in Response to Mouse Events&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;When a user moves over a button or presses a button you should give some visual feedback to that user. You can do this with animation using the Visual State Manager or Event Triggers in WPF. To keep things simple for this blog post, I simply respond to the various mouse events and change the Background property to a different color. When the mouse is pressed, I also change the Foreground color of the Text in the TextBlock control. The code for each of the mouse events is shown below.&lt;/P&gt;
&lt;P&gt;private void pdsaButtonBorderStyle_MouseEnter(&lt;BR&gt;&amp;nbsp;object sender, MouseEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; pdsaButtonBorderStyle.Background = &lt;BR&gt;&amp;nbsp;&amp;nbsp; (Brush)this.FindResource("pdsaButtonOverStyle");&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;private void pdsaButtonBorderStyle_MouseLeave(&lt;BR&gt;&amp;nbsp;object sender, MouseEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; pdsaButtonBorderStyle.Background = &lt;BR&gt;&amp;nbsp;&amp;nbsp; (Brush)this.FindResource("pdsaButtonNormalStyle");&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;private void pdsaButtonBorderStyle_MouseDown(&lt;BR&gt;&amp;nbsp;object sender, MouseButtonEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; // Save old Foreground Brush&lt;BR&gt;&amp;nbsp; _TextBrush = tbText.Foreground;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; pdsaButtonBorderStyle.Background = &lt;BR&gt;&amp;nbsp;&amp;nbsp; (Brush)this.FindResource("pdsaButtonPressedStyle");&lt;BR&gt;&amp;nbsp; tbText.Foreground = &lt;BR&gt;&amp;nbsp;&amp;nbsp; (SolidColorBrush)this.FindResource(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "pdsaButtonTextBlockStylePressed");&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;private void pdsaButtonBorderStyle_MouseUp(&lt;BR&gt;&amp;nbsp;object sender, MouseButtonEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; RestoreNormal();&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;private void RestoreNormal()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; pdsaButtonBorderStyle.Background = &lt;BR&gt;&amp;nbsp;&amp;nbsp; (Brush)this.FindResource("pdsaButtonNormalStyle");&lt;/P&gt;
&lt;P&gt;&amp;nbsp; tbText.Foreground = _TextBrush;&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Notice that in the code above that you use the FindResource() method instead of accessing the this.Resources[] collection. That is because you want to be able to set the resource dictionary at any level, not just on this user control. FindResource() will search upward through your UI tree looking for a resource that match the names you see that start with “pdsa”.&lt;/P&gt;
&lt;P&gt;You will need a Click event that you can raise when the user clicks on the button. Here is the definition for that Click event.&lt;/P&gt;
&lt;P&gt;private void pdsaButtonBorderStyle_MouseLeftButtonUp(&lt;BR&gt;&amp;nbsp;object sender, MouseButtonEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; RaiseClick(e);&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;public delegate void ClickEventHandler(object sender, &lt;BR&gt;&amp;nbsp;RoutedEventArgs e);&lt;/P&gt;
&lt;P&gt;public event ClickEventHandler Click;&lt;/P&gt;
&lt;P&gt;protected void RaiseClick(RoutedEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if (null != Click)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Click(this, e);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; RestoreNormal();&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The Default Resource Dictionary&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Below is the definition of the resource dictionary file contained in the PDSA.WPF DLL. This dictionary can be used as the default look and feel for any button control you add to a window. I have included two additional resource dictionaries in the main project as examples of how you can change the resources to give your buttons a different look. You need to keep the x:Key names the same, but you can change any of the attributes of color or thickness that you want. You can even change from Gradient colors to a SolidColorBrush as you can see I did when you look at the different resource dictionaries.&lt;/P&gt;
&lt;P&gt;&amp;lt;ResourceDictionary xmlns="&lt;A href="http://schemas.microsoft.com/"&gt;http://schemas.microsoft.com/&lt;/A&gt;&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; winfx/2006/xaml/presentation"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:x="&lt;A href="http://schemas.microsoft.com/winfx/2006/xaml"&gt;http://schemas.microsoft.com/winfx/2006/xaml&lt;/A&gt;"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Hover TextBlock Style --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Style TargetType="TextBlock"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Key="pdsaButtonTextBlockStyle"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Foreground"&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; Value="GhostWhite" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Margin"&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; Value="10" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="FontSize"&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; Value="14" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Hover Brush for Pressed Hover Button Text Block --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;SolidColorBrush x:Key="pdsaButtonTextBlockStylePressed"&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; Color="Black" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Hover Border Thickness --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Thickness x:Key="pdsaButtonBorderStyleThickness"&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; Bottom="0"&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; Left="0"&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; Right="0"&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; Top="0" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Hover Border Brush --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;SolidColorBrush x:Key="pdsaButtonBorderBrushStyle"&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; Color="Black" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Style for when hovering over button --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;RadialGradientBrush x:Key="pdsaButtonOverStyle"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="#FF5F5F5F"&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; Offset="0" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="#FFADADAD"&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; Offset="1" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/RadialGradientBrush&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Style for when button is pressed --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;LinearGradientBrush EndPoint="1,0.5"&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; StartPoint="0,0.5"&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; x:Key="pdsaButtonPressedStyle"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="#FF5F5F5F"&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; Offset="0" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="#FFADADAD"&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; Offset="1" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/LinearGradientBrush&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Style for normal button --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;LinearGradientBrush EndPoint="0.5,1"&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; StartPoint="0.5,0"&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; x:Key="pdsaButtonNormalStyle"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="#FF5F5F5F"&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; Offset="0" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;GradientStop Color="#FFADADAD"&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; Offset="1" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/LinearGradientBrush&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Overall Style for Hover Button --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Style TargetType="Border"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Key="pdsaButtonBorderStyle"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Margin"&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; Value="6" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="CornerRadius"&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; Value="5" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="Background"&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; Value="{StaticResource pdsaButtonNormalStyle}" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="BorderBrush"&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; Value="{StaticResource &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; pdsaButtonBorderBrushStyle}" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Setter Property="BorderThickness"&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; Value="{StaticResource &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; pdsaButtonBorderStyleThickness}" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Style&amp;gt;&lt;BR&gt;&amp;lt;/ResourceDictionary&amp;gt;&lt;/P&gt;
&lt;P&gt;You can look at the other two Resource Dictionary files when you download the sample.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Using the Button Control&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Once you make a reference to the PDSA.WPF DLL from your WPF application you will see the “PDSAucButton” control appear in your Toolbox. Drag and drop the button onto a Window or User Control in your application. I have not referenced the PDSAButtonStyles.xaml file within the control itself so you do need to add a reference to this resource dictionary somewhere in your application such as in the App.xaml.&lt;/P&gt;
&lt;P&gt;&amp;lt;Application.Resources&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;ResourceDictionary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary.MergedDictionaries&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Source="/PDSA.WPF;component/PDSAButtonStyles.xaml" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ResourceDictionary.MergedDictionaries&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/ResourceDictionary&amp;gt;&lt;BR&gt;&amp;lt;/Application.Resources&amp;gt;&lt;/P&gt;
&lt;P&gt;This will give your buttons a default look and feel unless you override that dictionary on a specific Window/User Control or on an individual button. The “Gray Style” button shown in Figure 1 is what the default button looks like after setting the above code in your App.xaml and then dragging a button onto a Window.&lt;/P&gt;
&lt;P&gt;If you wish to give a specific style to just a single button you can override the default by using the code below:&lt;/P&gt;
&lt;P&gt;&amp;lt;my:PDSAucButton HorizontalAlignment="Left"&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; Margin="6"&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; Text="Flat Blue Style"&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; x:Name="btn2"&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; Click="btn2_Click"&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; VerticalAlignment="Top"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;my:PDSAucButton.Resources&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary Source="FlatBlueButtonStyles.xaml" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/my:PDSAucButton.Resources&amp;gt;&lt;BR&gt;&amp;lt;/my:PDSAucButton&amp;gt;&lt;/P&gt;
&lt;P&gt;If you want to override a series of buttons within one specific StackPanel, or within a specific Window or User Control, you simply set the Resources section for that control as shown below:&lt;/P&gt;
&lt;P&gt;&amp;lt;StackPanel Orientation="Horizontal"&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; VerticalAlignment="Top"&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Set Styles for All Buttons. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; This overrides the App.xaml styles --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;StackPanel.Resources&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary Source="FlatBlueButtonStyles.xaml" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/StackPanel.Resources&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;my:PDSAucButton HorizontalAlignment="Left"&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; Margin="6"&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; Text="Blue Style"&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; x:Name="btn11"&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; Effect="{StaticResource mainDropShadow}"&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; VerticalAlignment="Top" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;!-- Can assign a custom set of styles --&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;my:PDSAucButton HorizontalAlignment="Left"&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; Margin="6"&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; Text="Flat Blue Style"&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; x:Name="btn12"&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; VerticalAlignment="Top" /&amp;gt;&lt;BR&gt;&amp;lt;/StackPanel&amp;gt;&lt;/P&gt;
&lt;P&gt;In the above sample, all buttons within this StackPanel control are styled using the resource dictionary FlatBlueButtonStyles.xaml.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Summary&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Creating your own button control can be done in a variety of ways. You can create a new Button control template, apply styles to change just a few things about a Button, create your own Custom control that inherits from Button, or build a User Control as in this blog post. Which method you choose depends a little on how comfortable you are with each method, and how much control you want over the final details of your new Button. The approach outlined in this blog post is simple and easy to understand and almost anyone can use this technique right away. Feel free to add your own animation to this control or maybe add dependency properties to control the BorderBrush, BorderThickness or any other properties you want.&lt;/P&gt;
&lt;P&gt;NOTE: You can download the sample code for this article by visiting my website at &lt;A href="http://www.pdsa.com/downloads"&gt;http://www.pdsa.com/downloads&lt;/A&gt;. Select “Tips &amp;amp; Tricks”, then select “Create your own WPF Buttons” from the drop down list.&lt;BR&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8832597" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/WPF/default.aspx">WPF</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/08/10/create-your-own-wpf-button-user-controls.aspx</feedburner:origLink></item><item><title>XML Activator</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/HYd94QNZcKc/xml-activator.aspx</link><pubDate>Wed, 01 Aug 2012 13:58:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8806615</guid><dc:creator>psheriff</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=8806615</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/08/01/xml-activator.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;All too often I see people using switch/Select Case statements when using a Factory pattern. The problem with this is if you wish to add the ability to instantiate a new class in your Factory, you need to add a new “case” statement, re-compile the code and redeploy that DLL back out to your client machines, or your server(s). Another way to implement a Factory pattern is to use Reflection and Interfaces to dynamically create an instance of a class. This blog post will show you how to use an XML file, an Interface and the Assembly class to dynamically load a list of assemblies and classes to load into an application at runtime.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;An XML File of Assembly/Class Names&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;You will need a data store to place a list of assembly names and class names that you wish to dynamically create. You could use a database table, but I am going to use an XML file that contains the Assembly Name to load and a Class Name to instantiate from that assembly. Any additional information you wish to add, feel free. In the XML listing below you can see a VendorId, VendorName as well as the AssemblyName and ClassName elements.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;lt;Vendors&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Vendor&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;VendorId&amp;gt;1&amp;lt;/VendorId&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;VendorName&amp;gt;Microsoft&amp;lt;/VendorName&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;AssemblyName&amp;gt;Vendor.Microsoft&amp;lt;/AssemblyName&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ClassName&amp;gt;Vendor.Microsoft&amp;lt;/ClassName&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Vendor&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Vendor&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;VendorId&amp;gt;2&amp;lt;/VendorId&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;VendorName&amp;gt;Apple&amp;lt;/VendorName&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;AssemblyName&amp;gt;Vendor.Apple&amp;lt;/AssemblyName&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ClassName&amp;gt;Vendor.Apple&amp;lt;/ClassName&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Vendor&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Vendor&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;VendorId&amp;gt;3&amp;lt;/VendorId&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;VendorName&amp;gt;Google&amp;lt;/VendorName&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;AssemblyName&amp;gt;Vendor.Google&amp;lt;/AssemblyName&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ClassName&amp;gt;Vendor.Google&amp;lt;/ClassName&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/Vendor&amp;gt;&lt;BR&gt;&amp;lt;/Vendors&amp;gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Load the XML File into a Collection Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;When you have an XML file like that shown above, you will typically create a class with properties that match each element in the XML file. Below is a VendorClass that has properties for each element.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class VendorClass&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public int VendorId { get; set; }&lt;BR&gt;&amp;nbsp; public string VendorName { get; set; }&lt;BR&gt;&amp;nbsp; public string AssemblyName { get; set; }&lt;BR&gt;&amp;nbsp; public string ClassName { get; set; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;Next you create a collection class using the Generic List&amp;lt;VendorClass&amp;gt; class. In this class there is a LoadVendors() method. This method uses the XElement class to load the Vendors.xml file into memory. LINQ to XML is used to iterate over the XML elements and create a collection of VendorClass objects. This resulting collection of objects is added to the List using the AddRange() method.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class VendorClasses : List&amp;lt;VendorClass&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public VendorClasses LoadVendors()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Load XML file into memory&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var xElem = XElement.Load(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetCurrentDirectory() + &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConfigurationManager.AppSettings["VendorFile"]);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Read Vendors using LINQ to XML&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var vendors = from vend in xElem.Descendants("Vendor")&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select new VendorClass&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VendorId =&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Convert.ToInt32(vend.Element("VendorId").Value),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VendorName = vend.Element("VendorName").Value,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AssemblyName = vend.Element("AssemblyName").Value,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ClassName = vend.Element("ClassName").Value&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Add vendors read in to the List of Vendor classes&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.AddRange(vendors.ToList());&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;To load an XML file you need to find the location on disk. There is a GetCurrentDirectory() method in this class. This method gets the current directory and removes any \bin\Debug from the end of the path if present. This allows you to get the current path whether you are running in Visual Studio or not.&lt;/P&gt;
&lt;P mce_keep="true"&gt;private string GetCurrentDirectory()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; string path = null;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp; path = AppDomain.CurrentDomain.BaseDirectory;&lt;BR&gt;&amp;nbsp; if (path.IndexOf("&lt;A href="file://bin/"&gt;\\bin&lt;/A&gt;") &amp;gt; 0)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; path = path.Substring(0, path.LastIndexOf("&lt;A href="file://bin/"&gt;\\bin&lt;/A&gt;"));&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; if(!path.EndsWith(@"\"))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; path += @"\";&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; return path;&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Create a Vendor Object Dynamically&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Now that you have the list of assembly and class names loaded into a collection you can now create an instance of a specific class. In order to do this you must have an Interface or a base class. I have created an Interface called IVendor. This interface will need to be implemented by each Vendor class that you will be dynamically loading. This interface is located in a separate assembly from all other classes and from the main application. This assembly will need to be referenced by the main application as well as from each assembly where your Vendor classes are located.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public interface IVendor&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int VendorId { get; set; }&lt;BR&gt;&amp;nbsp; string VendorName { get; set; }&lt;BR&gt;&amp;nbsp; string GetVendorInfo();&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;Below is an example of a vendor class named “Apple” that implements the IVendor interface. The GetVendorInfo() method will simply return a string just so we can verify that the class did get created correctly.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class Apple : IVendor&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public int VendorId { get; set; }&lt;BR&gt;&amp;nbsp; public string VendorName { get; set; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public string GetVendorInfo()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return "Apple Corporation";&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;Below is another example of a vendor class named “Microsoft” that also implements the IVendor interface.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class Microsoft : IVendor&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public int VendorId { get; set; }&lt;BR&gt;&amp;nbsp; public string VendorName { get; set; }&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; public string GetVendorInfo()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return "Microsoft Corporation";&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;Each of the above classes are located in separate assemblies as you can see by the AssemblyName element in the XML file. These DLLs do NOT need to be referenced from your project, and in fact, should not be. The Create() method shown below uses the Assembly.LoadFile() method to load the assembly from the current directory. That means that the assembly where each Vendor class is located must be in the current directory for this sample. After the DLL has been loaded, you use the CreateInstance() method on the loaded assembly to load the specific class name. Finally you take the VendorId and the VendorName and place it into the Vendor object’s appropriate properties. This newly created Vendor object is returned from this method.&lt;/P&gt;
&lt;P mce_keep="true"&gt;public class VendorClass&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; // Properties here…&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp; public IVendor Create()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assembly assm;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IVendor vendor = null;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Load Assembly File&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; assm = Assembly.LoadFile(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AppDomain.CurrentDomain.BaseDirectory + &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AssemblyName + ".dll");&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create new instance of Class&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vendor = (IVendor)assm.CreateInstance(ClassName);&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set properties in the Provider class from the XML file &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vendor.VendorId = VendorId;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vendor.VendorName = VendorName;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return vendor;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;The Sample to Test Activation&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;To test activating each of these vendor classes I have created a WPF application (Figure 1). The Load Vendors button will call the LoadVendors() method to build the collection of VendorClass objects from the XML file.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 525px; HEIGHT: 350px" title="Figure 1: A sample to test our activation" alt="Figure 1: A sample to test our activation" src="http://www.pdsa.com/imagesforblog/XmlActivator.jpg" width=525 height=350 mce_src="http://www.pdsa.com/imagesforblog/XmlActivator.jpg"&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Figure 1: A sample to test our activation&lt;/P&gt;
&lt;P mce_keep="true"&gt;Below is the code in the btnLoad_Click event procedure that loads the collection of VendorClass objects.&lt;/P&gt;
&lt;P mce_keep="true"&gt;private void btnLoad_Click(object sender, RoutedEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; VendorClasses classes = new VendorClasses();&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; // Load all vendors in the XML file&lt;BR&gt;&amp;nbsp; classes.LoadVendors();&lt;BR&gt;&amp;nbsp; lstVendors.DataContext = classes;&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;Once the VendorClass collection is in the List Box you can click on the list box to fire the SelectionChanged event procedure. In this event procedure you will cast the SelectedItem property of the list box into a VendorClass object. You can then call the Create() method to instantiate the Vendor object by loading the assembly and creating an instance of the Vendor object. After the Vendor object has been created you can call the GetVendorInfo() method to verify that the assembly has been loaded and an instance of the class has been created.&lt;/P&gt;
&lt;P mce_keep="true"&gt;private void lstVendors_SelectionChanged(object sender,&lt;BR&gt;&amp;nbsp; SelectionChangedEventArgs e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; VendorClass vendor;&lt;BR&gt;&amp;nbsp; IVendor vend;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; // Get the currently selected vendor&lt;BR&gt;&amp;nbsp; vendor = (VendorClass)lstVendors.SelectedItem;&lt;BR&gt;&amp;nbsp; // Create an instance of a Vendor class&lt;BR&gt;&amp;nbsp; vend = vendor.Create();&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp; tbVendorName.Text = vend.GetVendorInfo();&lt;BR&gt;}&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Summary&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;In this blog post you learned how to use LINQ to XML to load a collection of classes that contain information about other classes that you will eventually load. You saw how to use the Assembly class to load an assembly from disk and instantiate a class from a string value. An Interface is used to ensure that each class to be instantiated has the same set of methods and properties. Using this technique can eliminate a switch/Select case statement and allow you to dynamically add classes to any application.&lt;/P&gt;
&lt;P mce_keep="true"&gt;NOTE: You can download the sample code for this article by visiting my website at &lt;A href="http://www.pdsa.com/downloads"&gt;http://www.pdsa.com/downloads&lt;/A&gt;. Select “Tips &amp;amp; Tricks”, then select “XML Activator” from the drop down list.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8806615" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/XML/default.aspx">XML</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Reflection/default.aspx">Reflection</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/08/01/xml-activator.aspx</feedburner:origLink></item><item><title>WPF Tree View with Multiple Levels</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/gM9r_jeKn24/wpf-tree-view-with-multiple-levels.aspx</link><pubDate>Mon, 23 Jul 2012 17:52:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8776227</guid><dc:creator>psheriff</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=8776227</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/07/23/wpf-tree-view-with-multiple-levels.aspx#comments</comments><description>&lt;P&gt;Earlier this year I blogged on how to use the WPF Tree View to view multiple levels. Since then I have had many requests to do the same in WPF. Luckily, the code is almost identical. Here is a blog post on using the WPF Tree View that has multiple levels.&lt;/P&gt;
&lt;P&gt;There are many examples of the WPF Tree View that you will find on the web, however, most of them only show you how to go to two levels. What if you have more than two levels? This is where understanding exactly how the Hierarchical Data Templates works is vital. In this blog post, I am going to break down how these templates work so you can really understand what is going on underneath the hood. To start, let’s look at the typical two-level WPF Tree View that has been hard coded with the values shown below:&lt;/P&gt;
&lt;P&gt;&amp;lt;TreeView&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;TreeViewItem Header="Managers"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TextBlock Text="Michael" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TextBlock Text="Paul" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/TreeViewItem&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;TreeViewItem Header="Supervisors"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TextBlock Text="John" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TextBlock Text="Tim" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TextBlock Text="David" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/TreeViewItem&amp;gt;&lt;BR&gt;&amp;lt;/TreeView&amp;gt;&lt;/P&gt;
&lt;P&gt;Figure 1 shows you how this tree view looks when you run the WPF application.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 525px; HEIGHT: 350px" title="Figure 1: A hard-coded, two level Tree View." alt="Figure 1: A hard-coded, two level Tree View." src="http://www.pdsa.com/ImagesForBlog/WPFTree-1.jpg" width=525 height=350 mce_src="http://www.pdsa.com/ImagesForBlog/WPFTree-1.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Figure 1: A hard-coded, two level Tree View.&lt;/P&gt;
&lt;P&gt;Next, let’s create three classes to mimic the hard-coded Tree View shown above. First, you need an Employee class and an EmployeeType class. The Employee class simply has one property called Name. The constructor is created to accept a “name” argument that you can use to set the Name property when you create an Employee object.&lt;/P&gt;
&lt;P&gt;public class Employee&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public Employee(string name)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name = name;&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; public string Name { get; set; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Create an EmployeeType class that has one property called EmpType and contains a generic List&amp;lt;&amp;gt; collection of Employee objects. The property that holds the collection is called Employees.&lt;/P&gt;
&lt;P&gt;public class EmployeeType&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public EmployeeType(string empType)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EmpType = empType;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Employees = new List&amp;lt;Employee&amp;gt;();&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; public string EmpType { get; set; }&lt;BR&gt;&amp;nbsp; public List&amp;lt;Employee&amp;gt; Employees { get; set; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Finally we have a collection class called EmployeeTypes created using the generic List&amp;lt;&amp;gt; class. It is in the constructor for this class where you will build the collection of EmployeeTypes and fill it with Employee objects:&lt;/P&gt;
&lt;P&gt;public class EmployeeTypes : List&amp;lt;EmployeeType&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public EmployeeTypes()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EmployeeType type;&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; type = new EmployeeType("Manager");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(new Employee("Michael"));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(new Employee("Paul"));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Add(type);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type = new EmployeeType("Project Managers");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(new Employee("Tim"));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(new Employee("John"));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(new Employee("David"));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Add(type);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;You now have a data hierarchy in memory (Figure 2) which is what the Tree View control expects to receive as its data source.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 355px; HEIGHT: 194px" title="Figure 2: A hierachial data structure of Employee Types containing a collection of Employee objects." alt="Figure 2: A hierachial data structure of Employee Types containing a collection of Employee objects." src="http://www.pdsa.com/ImagesForBlog/WPFTree-2.jpg" width=355 height=194 mce_src="http://www.pdsa.com/ImagesForBlog/WPFTree-2.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Figure 2: A hierachial data structure of Employee Types containing a collection of Employee objects.&lt;/P&gt;
&lt;P&gt;To connect up this hierarchy of data to your Tree View you create an instance of the EmployeeTypes class in XAML as shown in line 13 of Figure 3. The key assigned to this object is “empTypes”. This key is used as the source of data to the entire Tree View by setting the ItemsSource property as shown in Figure 3, Callout #1.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 626px; HEIGHT: 309px" title="Figure 3: You need to start from the bottom up when laying out your templates for a Tree View." alt="Figure 3: You need to start from the bottom up when laying out your templates for a Tree View." src="http://www.pdsa.com/ImagesForBlog/WPFTree-3.jpg" width=626 height=309 mce_src="http://www.pdsa.com/ImagesForBlog/WPFTree-3.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Figure 3: You need to start from the bottom up when laying out your templates for a Tree View.&lt;/P&gt;
&lt;P&gt;The ItemsSource property of the Tree View control is used as the data source in the Hierarchical Data Template with the key of employeeTypeTemplate. In this case there is only one Hierarchical Data Template, so any data you wish to display within that template comes from the collection of Employee Types. The TextBlock control in line 20 uses the EmpType property of the EmployeeType class. You specify the name of the Hierarchical Data Template to use in the ItemTemplate property of the Tree View (Callout #2).&lt;/P&gt;
&lt;P&gt;For the second (and last) level of the Tree View control you use a normal &amp;lt;DataTemplate&amp;gt; with the name of employeeTemplate (line 14). The Hierarchical Data Template in lines 17-21 sets its ItemTemplate property to the key name of employeeTemplate (Line 19 connects to Line 14). The source of the data for the &amp;lt;DataTemplate&amp;gt; needs to be a property of the EmployeeTypes collection used in the Hierarchical Data Template. In this case that is the Employees property. In the Employees property there is a “Name” property of the Employee class that is used to display the employee name in the second level of the Tree View (Line 15).&lt;/P&gt;
&lt;P&gt;What is important here is that your lowest level in your Tree View is expressed in a &amp;lt;DataTemplate&amp;gt; and should be listed first in your Resources section. The next level up in your Tree View should be a &amp;lt;HierarchicalDataTemplate&amp;gt; which has its ItemTemplate property set to the key name of the &amp;lt;DataTemplate&amp;gt; and the ItemsSource property set to the data you wish to display in the &amp;lt;DataTemplate&amp;gt;. The Tree View control should have its ItemsSource property set to the data you wish to display in the &amp;lt;HierarchicalDataTemplate&amp;gt; and its ItemTemplate property set to the key name of the &amp;lt;HierarchicalDataTemplate&amp;gt; object. It is in this way that you get the Tree View to display all levels of your hierarchical data structure.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Three Levels in a Tree View&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Now let’s expand upon this concept and use three levels in our Tree View (Figure 4). This Tree View shows that you now have EmployeeTypes at the top of the tree, followed by a small set of employees that themselves manage employees. This means that the EmployeeType class has a collection of Employee objects. Each Employee class has a collection of Employee objects as well.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 525px; HEIGHT: 350px" title="Figure 4: When using 3 levels in your TreeView you will have 2 Hierarchical Data Templates and 1 Data Template." alt="Figure 4: When using 3 levels in your TreeView you will have 2 Hierarchical Data Templates and 1 Data Template." src="http://www.pdsa.com/ImagesForBlog/WPFTree-4.jpg" width=525 height=350 mce_src="http://www.pdsa.com/ImagesForBlog/WPFTree-4.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Figure 4: When using 3 levels in your TreeView you will have 2 Hierarchical Data Templates and 1 Data Template.&lt;/P&gt;
&lt;P&gt;The EmployeeType class has not changed at all from our previous example. However, the Employee class now has one additional property as shown below:&lt;/P&gt;
&lt;P&gt;public class Employee&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public Employee(string name)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name = name;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ManagedEmployees = new List&amp;lt;Employee&amp;gt;();&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; public string Name { get; set; }&lt;BR&gt;&amp;nbsp; public List&amp;lt;Employee&amp;gt; ManagedEmployees { get; set; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;The next thing that changes in our code is the EmployeeTypes class. The constructor now needs additional code to create a list of managed employees. Below is the new code.&lt;/P&gt;
&lt;P&gt;public class EmployeeTypes : List&amp;lt;EmployeeType&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public EmployeeTypes()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EmployeeType type;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Employee emp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Employee managed;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type = new EmployeeType("Manager");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; emp = new Employee("Michael");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; managed = new Employee("John");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; emp.ManagedEmployees.Add(managed);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; managed = new Employee("Tim");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; emp.ManagedEmployees.Add(managed);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(emp);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; emp = new Employee("Paul");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; managed = new Employee("Michael");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; emp.ManagedEmployees.Add(managed);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; managed = new Employee("Cindy");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; emp.ManagedEmployees.Add(managed);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(emp);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Add(type);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type = new EmployeeType("Project Managers");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(new Employee("Tim"));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(new Employee("John"));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; type.Employees.Add(new Employee("David"));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Add(type);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Now that you have all of the data built in your classes, you are now ready to hook up this three-level structure to your Tree View. Figure 5 shows the complete XAML needed to hook up your three-level Tree View. You can see in the XAML that there are now two Hierarchical Data Templates and one Data Template. Again you list the Data Template first since that is the lowest level in your Tree View. The next Hierarchical Data Template listed is the next level up from the lowest level, and finally you have a Hierarchical Data Template for the first level in your tree. You need to work your way from the bottom up when creating your Tree View hierarchy. XAML is processed from the top down, so if you attempt to reference a XAML key name that is below where you are referencing it from, you will get a runtime error.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 626px; HEIGHT: 319px" title="Figure 5: For three levels in a Tree View you will need two Hierarchical Data Templates and one Data Template." alt="Figure 5: For three levels in a Tree View you will need two Hierarchical Data Templates and one Data Template." src="http://www.pdsa.com/ImagesForBlog/WPFTree-5.jpg" width=626 height=319 mce_src="http://www.pdsa.com/ImagesForBlog/WPFTree-5.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Figure 5: For three levels in a Tree View you will need two Hierarchical Data Templates and one Data Template.&lt;/P&gt;
&lt;P&gt;Each Hierarchical Data Template uses the previous template as its ItemTemplate. The ItemsSource of each Hierarchical Data Template is used to feed the data to the previous template. This is probably the most confusing part about working with the Tree View control. You are expecting the content of the current Hierarchical Data Template to use the properties set in the ItemsSource property of that template. But you need to look to the template lower down in the XAML to see the source of the data as shown in Figure 6.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 626px; HEIGHT: 321px" title="Figure 6: The properties you use within the Content of a template come from the ItemsSource of the next template in the resources section." alt="Figure 6: The properties you use within the Content of a template come from the ItemsSource of the next template in the resources section." src="http://www.pdsa.com/ImagesForBlog/WPFTree-6.jpg" width=626 height=321 mce_src="http://www.pdsa.com/ImagesForBlog/WPFTree-6.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Figure 6: The properties you use within the Content of a template come from the ItemsSource of the next template in the resources section.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Summary&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Understanding how to put together your hierarchy in a Tree View is simple once you understand that you need to work from the bottom up. Start with the bottom node in your Tree View and determine what that will look like and where the data will come from. You then build the next Hierarchical Data Template to feed the data to the previous template you created. You keep doing this for each level in your Tree View until you get to the last level. The data for that last Hierarchical Data Template comes from the ItemsSource in the Tree View itself.&lt;/P&gt;
&lt;P&gt;NOTE: You can download the sample code for this article by visiting my website at &lt;A href="http://www.pdsa.com/downloads"&gt;http://www.pdsa.com/downloads&lt;/A&gt;. Select “Tips &amp;amp; Tricks”, then select “WPF TreeView with Multiple Levels” from the drop down list.&lt;BR&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8776227" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/WPF/default.aspx">WPF</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Tree+View/default.aspx">Tree View</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/07/23/wpf-tree-view-with-multiple-levels.aspx</feedburner:origLink></item><item><title>Read XML Files using LINQ to XML and Extension Methods</title><link>http://feedproxy.google.com/~r/PaulSheriffsOuterCircleBlog/~3/XvIzqjqQmE4/read-xml-files-using-linq-to-xml-and-extension-methods.aspx</link><pubDate>Sun, 08 Jul 2012 02:46:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8708460</guid><dc:creator>psheriff</dc:creator><slash:comments>7</slash:comments><wfw:commentRss>http://weblogs.asp.net/psheriff/rsscomments.aspx?PostID=8708460</wfw:commentRss><comments>http://weblogs.asp.net/psheriff/archive/2012/07/07/read-xml-files-using-linq-to-xml-and-extension-methods.aspx#comments</comments><description>&lt;P&gt;In previous blog posts I have discussed how to use XML files to store data in your applications. I showed you how to read those XML files from your project and get XML from a WCF service. One of the problems with reading XML files is when elements or attributes are missing. If you try to read that missing data, then a null value is returned. This can cause a problem if you are trying to load that data into an object and a null is read. This blog post will show you how to create extension methods to detect null values and return valid values to load into your object.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The XML Data&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;An XML data file called Product.xml is located in the \Xml folder of the Silverlight sample project for this blog post. This XML file contains several rows of product data that will be used in each of the samples for this post. Each row has 4 attributes; namely ProductId, ProductName, IntroductionDate and Price.&lt;/P&gt;
&lt;P&gt;&amp;lt;Products&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Product ProductId="1"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductName="Haystack Code Generator for .NET"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IntroductionDate="07/01/2010"&amp;nbsp; Price="799" /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;Product ProductId="2"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductName="ASP.Net Jumpstart Samples"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IntroductionDate="05/24/2005"&amp;nbsp; Price="0" /&amp;gt;&lt;BR&gt;&amp;nbsp; ...&lt;BR&gt;&amp;nbsp; ...&lt;BR&gt;&amp;lt;/Products&amp;gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The Product Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Just as you create an Entity class to map each column in a table to a property in a class, you should do the same for an XML file too. In this case you will create a Product class with properties for each of the attributes in each element of product data. The following code listing shows the Product class.&lt;/P&gt;
&lt;P&gt;public class Product : CommonBase&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public const string XmlFile = @"Xml/Product.xml";&lt;/P&gt;
&lt;P&gt;&amp;nbsp; private string _ProductName;&lt;BR&gt;&amp;nbsp; private int _ProductId;&lt;BR&gt;&amp;nbsp; private DateTime _IntroductionDate;&lt;BR&gt;&amp;nbsp; private decimal _Price;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; public string ProductName&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _ProductName; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_ProductName != value) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ProductName = value;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RaisePropertyChanged("ProductName");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; public int ProductId&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _ProductId; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_ProductId != value) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ProductId = value;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RaisePropertyChanged("ProductId");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; public DateTime IntroductionDate&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _IntroductionDate; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_IntroductionDate != value) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _IntroductionDate = value;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RaisePropertyChanged("IntroductionDate");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; public decimal Price&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _Price; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_Price != value) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _Price = value;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RaisePropertyChanged("Price");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;NOTE&lt;/STRONG&gt;: The CommonBase class that the Product class inherits from simply implements the INotifyPropertyChanged event in order to inform your XAML UI of any property changes. You can see this class in the sample you download for this blog post.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Reading Data&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;When using LINQ to XML you call the Load method of the XElement class to load the XML file. Once the XML file has been loaded, you write a LINQ query to iterate over the “Product” Descendants in the XML file. The “select” portion of the LINQ query creates a new Product object for each row in the XML file. You retrieve each attribute by passing each attribute name to the Attribute() method and retrieving the data from the “Value” property. The Value property will return a null if there is no data, or will return the string value of the attribute. The Convert class is used to convert the value retrieved into the appropriate data type required by the Product class.&lt;/P&gt;
&lt;P&gt;private void LoadProducts()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; XElement xElem = null;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; try&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xElem = XElement.Load(Product.XmlFile);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // The following will NOT work if you have missing attributes&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var products = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from elem in xElem.Descendants("Product")&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; orderby elem.Attribute("ProductName").Value&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select new Product&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; ProductId = Convert.ToInt32(&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; elem.Attribute("ProductId").Value),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductName = Convert.ToString(&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; elem.Attribute("ProductName").Value),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IntroductionDate = Convert.ToDateTime(&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; elem.Attribute("IntroductionDate").Value),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Price = Convert.ToDecimal(elem.Attribute("Price").Value)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lstData.DataContext = products;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; catch (Exception ex)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show(ex.Message);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;This is where the problem comes in. If you have any missing attributes in any of the rows in the XML file, or if the data in the ProductId or IntroductionDate is not of the appropriate type, then this code will fail! The reason? There is no built-in check to ensure that the correct type of data is contained in the XML file. This is where extension methods can come in real handy.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Using Extension Methods&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Instead of using the Convert class to perform type conversions as you just saw, create a set of extension methods attached to the XAttribute class. These extension methods will perform null-checking and ensure that a valid value is passed back instead of an exception being thrown if there is invalid data in your XML file.&lt;/P&gt;
&lt;P&gt;private void LoadProducts()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var xElem = XElement.Load(Product.XmlFile);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; var products = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from elem in xElem.Descendants("Product")&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; orderby elem.Attribute("ProductName").Value&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select new Product&lt;BR&gt;&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; ProductId = elem.Attribute("ProductId").GetAsInteger(),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductName = elem.Attribute("ProductName").GetAsString(),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IntroductionDate = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; elem.Attribute("IntroductionDate").GetAsDateTime(),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Price = elem.Attribute("Price").GetAsDecimal()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/P&gt;
&lt;P&gt;&amp;nbsp; lstData.DataContext = products;&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Writing Extension Methods&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To create an extension method you will create a class with any name you like. In the code listing below is a class named XmlExtensionMethods. This listing just shows a couple of the available methods such as GetAsString and GetAsInteger. These methods are just like any other method you would write except when you pass in the parameter you prefix the type with the keyword “this”. This lets the compiler know that it should add this method to the class specified in the parameter.&lt;/P&gt;
&lt;P&gt;public static class XmlExtensionMethods&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; public static string GetAsString(this XAttribute attr)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string ret = string.Empty;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (attr != null &amp;amp;&amp;amp; !string.IsNullOrEmpty(attr.Value))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = attr.Value;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ret;&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; public static int GetAsInteger(this XAttribute attr)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int ret = 0;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int value = 0;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (attr != null &amp;amp;&amp;amp; !string.IsNullOrEmpty(attr.Value))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(int.TryParse(attr.Value, out value))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret = value;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ret;&lt;BR&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; ...&lt;BR&gt;&amp;nbsp; ...&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Each of the methods in the XmlExtensionMethods class should inspect the XAttribute to ensure it is not null and that the value in the attribute is not null. If the value is null, then a default value will be returned such as an empty string or a 0 for a numeric value.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Summary&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Extension methods are a great way to simplify your code and provide protection to ensure problems do not occur when reading data. You will probably want to create more extension methods to handle XElement objects as well for when you use element-based XML. Feel free to extend these extension methods to accept a parameter which would be the default value if a null value is detected, or any other parameters you wish.&lt;/P&gt;
&lt;P&gt;NOTE: You can download the complete sample code at my website. &lt;A href="http://www.pdsa.com/downloads"&gt;http://www.pdsa.com/downloads&lt;/A&gt;. Choose “Tips &amp;amp; Tricks”, then "Read XML Files using LINQ to XML and Extension Methods" from the drop-down.&lt;/P&gt;
&lt;P&gt;Good Luck with your Coding,&lt;BR&gt;Paul D. Sheriff&lt;BR&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8708460" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/psheriff/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Extension+Methods/default.aspx">Extension Methods</category><category domain="http://weblogs.asp.net/psheriff/archive/tags/Silverlight+4/default.aspx">Silverlight 4</category><feedburner:origLink>http://weblogs.asp.net/psheriff/archive/2012/07/07/read-xml-files-using-linq-to-xml-and-extension-methods.aspx</feedburner:origLink></item></channel></rss>
