<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Deborah's Developer MindScape : Binding, C#</title><link>http://msmvps.com/blogs/deborahk/archive/tags/Binding/C_2300_/default.aspx</link><description>Tags: Binding, C#</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Binding to a ComboBox using a DataTable and Linq</title><link>http://msmvps.com/blogs/deborahk/archive/2010/02/27/binding-to-a-combobox-using-a-datatable-and-linq.aspx</link><pubDate>Sun, 28 Feb 2010 01:47:24 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1760130</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1760130</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2010/02/27/binding-to-a-combobox-using-a-datatable-and-linq.aspx#comments</comments><description>&lt;p&gt;If you retrieve data into a DataTable, it is easy to bind it to a ComboBox. And before Linq, you would filter the DataTable using a DataView. But with Linq, you have some easy to use features for filtering the contents of your ComboBox.&lt;/p&gt;  &lt;p&gt;First, here is the basic code for binding a ComboBox to a DataTable.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;private DataTable dt = Customers.Retrieve(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;ComboBox1.DataSource = dt;      &lt;br /&gt;ComboBox1.DisplayMember = &amp;quot;FullName&amp;quot;;       &lt;br /&gt;ComboBox1.ValueMember = &amp;quot;CustomerId&amp;quot;;&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private dt As DataTable = Customers.Retrieve&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;ComboBox1.DataSource = dt      &lt;br /&gt;ComboBox1.DisplayMember = &amp;quot;FullName&amp;quot;       &lt;br /&gt;ComboBox1.ValueMember = &amp;quot;CustomerId&amp;quot;&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;The Retrieve method on the Customers class retrieves a DataTable of customers. If you want to try this code, you can build a DataTable in code following the &lt;a href="http://msmvps.com/blogs/deborahk/archive/2010/02/27/build-a-datatable-in-code.aspx"&gt;techniques covered here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;You can then set the DataSource to the DataTable, set the DisplayMember to the name of the field to display in the ComboBox, and set the ValueMember to the name of the field to use as the field value. This is most often the unique key.&lt;/p&gt;  &lt;p&gt;The result looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/3618.image_5F00_61D850DF.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/6740.image_5F00_thumb_5F00_20C9D17B.png" width="415" height="242" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;With Linq you can add filtering criteria. So let&amp;#39;s add a second ComboBox that lists only the customers with a last name that starts with &amp;quot;B&amp;quot;.&lt;/p&gt;  &lt;p&gt;NOTE: Be sure to set a reference to System.Data.DataSetExtensions.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;var query = dt.AsEnumerable().Where(c=&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c.Field&amp;lt;String&amp;gt;(&amp;quot;LastName&amp;quot;).StartsWith(&amp;quot;B&amp;quot;));       &lt;br /&gt;      &lt;br /&gt;ComboBox2.DataSource = query.AsDataView();       &lt;br /&gt;ComboBox2.DisplayMember = &amp;quot;FullName&amp;quot;;       &lt;br /&gt;ComboBox2.ValueMember = &amp;quot;CustomerId&amp;quot;;&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim query = dt.AsEnumerable.Where(Function(c) _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c.Field(Of String)(&amp;quot;LastName&amp;quot;).StartsWith(&amp;quot;B&amp;quot;))       &lt;br /&gt;      &lt;br /&gt;ComboBox2.DataSource = query.AsDataView       &lt;br /&gt;ComboBox2.DisplayMember = &amp;quot;FullName&amp;quot;       &lt;br /&gt;ComboBox2.ValueMember = &amp;quot;CustomerId&amp;quot;&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;This code uses a Lambda expression to filter the DataTable to only those rows where the LastName starts with &amp;quot;B&amp;quot;.&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;AsEnumerable&lt;/strong&gt; extension method is necessary to allow Linq/Lambda expressions to work with a DataTable. Any field in the DataTable is accessed using c.Field&amp;lt;T&amp;gt; Or c.Field(Of T) where T is the type of the field. In this example, the field is a string.&lt;/p&gt;  &lt;p&gt;The second ComboBox is then bound to the query using the &lt;strong&gt;AsDataView&lt;/strong&gt; extension method. This allows the binding to bind the result as a DataView.&lt;/p&gt;  &lt;p&gt;The result looks like this.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/1663.image_5F00_4AC9CFA3.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/6763.image_5F00_thumb_5F00_660228A4.png" width="347" height="221" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;But wait, there is more. Because of the way that binding works. adding rows to the DataTable will add rows to the first ComboBox that is bound to the DataTable. AND if the new row starts with the letter &amp;quot;B&amp;quot;, it will add it to the second ComboBox as well.&lt;/p&gt;  &lt;p&gt;In this example, code in the Add button does this:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;private void Button1_Click(object sender, EventArgs e)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dt.Rows.Add(5, &amp;quot;Bond&amp;quot;, &amp;quot;James&amp;quot;, &amp;quot;Bond, James&amp;quot;, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, 3);       &lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private Sub Button1_Click2(ByVal sender As System.Object, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal e As System.EventArgs) Handles Button1.Click       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dt.Rows.Add(5, &amp;quot;Bond&amp;quot;, &amp;quot;James&amp;quot;, &amp;quot;Bond, James&amp;quot;, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, 3)       &lt;br /&gt;End Sub&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Click the button and the result is as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/4300.image_5F00_1E409FBD.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/5873.image_5F00_thumb_5F00_2F44CDA0.png" width="244" height="163" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;No refreshing or re-executing binding code required. It just works!!&lt;/p&gt;  &lt;p&gt;Use this technique any time you want to bind a ComboBox to a filtered set of data from a DataTable.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1760130" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Lambda/default.aspx">Lambda</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/DataTable/default.aspx">DataTable</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category></item><item><title>Populating a DataGridView from Xml Data</title><link>http://msmvps.com/blogs/deborahk/archive/2009/10/20/populating-a-datagridview-from-xml-data.aspx</link><pubDate>Wed, 21 Oct 2009 04:49:09 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1733866</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1733866</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/10/20/populating-a-datagridview-from-xml-data.aspx#comments</comments><description>&lt;p&gt;If you are using XML in a WinForms application you may find the need to display the XML data in a DataGridView. &lt;/p&gt;  &lt;p&gt;Let&amp;#39;s take this XML:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;lt;states&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;state name=&amp;quot;California&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;abbreviation&amp;gt;CA&amp;lt;/abbreviation&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;year&amp;gt;1850&amp;lt;/year&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;governor&amp;gt;Schwarzenegger&amp;lt;/governor&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/state&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;state name=&amp;quot;Wisconsin&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;abbreviation&amp;gt;WI&amp;lt;/abbreviation&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;year&amp;gt;1848&amp;lt;/year&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;governor&amp;gt;Doyle&amp;lt;/governor&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/state&amp;gt;       &lt;br /&gt;&amp;lt;/states&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Displaying XML in a DataGridView sounds easy, but if you just set the DataGridView DataSource to the XML data, you will get something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/6013.image_5F00_044D9E51.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/0552.image_5F00_thumb_5F00_62EDF8B4.png" width="469" height="184" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Notice how it has lots of yuck in it: attribute details, node properties, and so on for every node in the XML. So how do you get something more like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/5758.image_5F00_3ADB4995.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/5736.image_5F00_thumb_5F00_64DB47BD.png" width="463" height="203" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The trick is to use anonymous types.&lt;/p&gt;  &lt;p&gt;The code is provided here in VB and C# and then described in detail below.&lt;/p&gt;  &lt;p&gt;NOTE: Be sure to set a reference to &lt;strong&gt;System.Core&lt;/strong&gt; and &lt;strong&gt;System.Xml.Linq&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;XElement statesXml = XElement.Parse(&amp;quot;&amp;lt;states&amp;gt;&amp;quot; +      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;state name=&amp;#39;California&amp;#39;&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;abbreviation&amp;gt;CA&amp;lt;/abbreviation&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;year&amp;gt;1850&amp;lt;/year&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;governor&amp;gt;Schwarzenegger&amp;lt;/governor&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;/state&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;state name=&amp;#39;Wisconsin&amp;#39;&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;abbreviation&amp;gt;WI&amp;lt;/abbreviation&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;year&amp;gt;1848&amp;lt;/year&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;governor&amp;gt;Doyle&amp;lt;/governor&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;&amp;lt;/state&amp;gt;&amp;quot; +       &lt;br /&gt;&amp;#160;&amp;#160; &amp;quot;&amp;lt;/states&amp;gt;&amp;quot;); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;var query = from st in statesXml.Descendants(&amp;quot;state&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select new       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Name = st.Attribute(&amp;quot;name&amp;quot;).Value,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Abbrev = st.Element(&amp;quot;abbreviation&amp;quot;).Value,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Year = st.Element(&amp;quot;year&amp;quot;).Value,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Governor = st.Element(&amp;quot;governor&amp;quot;).Value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };       &lt;br /&gt;DataGridView1.DataSource = query.ToList();&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim statesXml As XElement = _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;states&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;state name=&amp;quot;California&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;abbreviation&amp;gt;CA&amp;lt;/abbreviation&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;year&amp;gt;1850&amp;lt;/year&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;governor&amp;gt;Schwarzenegger&amp;lt;/governor&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/state&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;state name=&amp;quot;Wisconsin&amp;quot;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;abbreviation&amp;gt;WI&amp;lt;/abbreviation&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;year&amp;gt;1848&amp;lt;/year&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;governor&amp;gt;Doyle&amp;lt;/governor&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/state&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/states&amp;gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim query = From st In statesXml...&amp;lt;state&amp;gt; _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select New With { _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Name = st.@name, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Abbrev = st.&amp;lt;abbreviation&amp;gt;.Value, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Year = st.&amp;lt;year&amp;gt;.Value, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Governor = st.&amp;lt;governor&amp;gt;.Value}       &lt;br /&gt;DataGridView1.DataSource = query.ToList&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;The first part of this code builds the XML. The C# code uses the XElement.Parse function to build the XML; VB uses XML literals. This part of the code is not necessary if you are reading the XML from another source, such as a file.&lt;/p&gt;  &lt;p&gt;The second part of the code leverages Linq to XML to process the set of state XML elements. For each element, it uses the Select New syntax to create an anonymous type. The syntax defines an unnamed (anonymous) type with properties Name, Abbrev, Year, and Governor.&lt;/p&gt;  &lt;p&gt;[To view an overview of anonymous types, &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/08/19/anonymous-types-an-introduction.aspx"&gt;start here&lt;/a&gt;.]&lt;/p&gt;  &lt;p&gt;The last line converts the results of the query to a generic list and assigns it to the DataSource property of the DataGridView. Visual Studio uses the anonymous type property names as the text for the column titles and populates the rows with each state element.&lt;/p&gt;  &lt;p&gt;Use this technique any time you have XML that you want to display in a DataGridView.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1733866" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Xml/default.aspx">Xml</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/WinForms/default.aspx">WinForms</category></item><item><title>Binding Control Properties to Business Object Properties</title><link>http://msmvps.com/blogs/deborahk/archive/2009/09/16/binding-control-properties-to-business-object-properties.aspx</link><pubDate>Wed, 16 Sep 2009 23:32:40 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1723916</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1723916</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/09/16/binding-control-properties-to-business-object-properties.aspx#comments</comments><description>&lt;p&gt;As stated &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/09/08/understanding-object-binding.aspx"&gt;here&lt;/a&gt;, you use object binding in a WinForms application by following these steps:&lt;/p&gt;  &lt;p&gt;1. Build the business objects for your application.&lt;/p&gt;  &lt;p&gt;2. Define a business object data source in the Windows Application    &lt;br /&gt;project containing your user interface.&lt;/p&gt;  &lt;p&gt;3. Bind properties of the controls on the form to business object    &lt;br /&gt;properties.&lt;/p&gt;  &lt;p&gt;The first two steps were detailed &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/09/08/using-object-binding.aspx" target="_blank"&gt;here&lt;/a&gt;. This post covers the third step.&lt;/p&gt;  &lt;p&gt;NOTE: You will not be able to follow along with the information in this post unless you perform steps 1 and 2 first from &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/09/08/using-object-binding.aspx" target="_blank"&gt;my prior post&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Binding to Existing Controls&lt;/h2&gt;  &lt;p&gt;Once you have at least one data source set up in your Data Sources window, you can bind it to your user interface. The technique you use to set up the binding is slightly different, depending on whether you are working with existing controls or creating new controls. This section describes the former, and the next section details the latter.&lt;/p&gt;  &lt;p&gt;The process of binding existing controls on a form to a data source is   &lt;br /&gt;referred to as &lt;em&gt;connect-the-dots binding&lt;/em&gt;. It is as easy as connecting point    &lt;br /&gt;A to point B.&lt;/p&gt;  &lt;p&gt;To bind an existing control to a business object property displayed in   &lt;br /&gt;the Data Sources window:&lt;/p&gt;  &lt;p&gt;1. &lt;strong&gt;Open the form&lt;/strong&gt; you want to bind in the Forms Designer.&lt;/p&gt;  &lt;p&gt;2. &lt;strong&gt;Open the Data Sources window&lt;/strong&gt;. Position the Data Sources window so that you can easily see its contents and the Forms Designer at the same time.&lt;/p&gt;  &lt;p&gt;3. &lt;strong&gt;Drag the desired property from the Data Sources window&lt;/strong&gt;, and    &lt;br /&gt;&lt;strong&gt;drop it on the appropriate control&lt;/strong&gt; on the form to bind them.&lt;/p&gt;  &lt;p&gt;Repeat this process for every control on the form that needs to be   &lt;br /&gt;bound to the business object.&lt;/p&gt;  &lt;p&gt;The first time you drop a property from an object data source to a form, Visual Studio adds a BindingSource component to the form’s component tray and names it based on the name of your business object class. This component manages the binding between the form controls and the   &lt;br /&gt;business object properties.&lt;/p&gt;  &lt;p&gt;The default property of the control that you used as your drop target is bound to the BindingSource component for the property that was dragged from the Data Sources window. You can see this by using the Properties window to examine the control’s DataBindings property.&lt;/p&gt;  &lt;p&gt;For example, add a TextBox to an empty form. Then drag the LastName property from the Customer object data source in the Data Sources window and drop it on the TextBox control. This binds the Text property of the TextBox control to the LastName property of the Customer class by way of the CustomerBindingSource. The result is shown below.   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/1184.image_5F00_66F5E35D.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/6886.image_5F00_thumb_5F00_4D243DDF.png" width="491" height="396" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As shown in the Properties window, the Text property of the TextBox control is now bound to the LastName property by way of the CustomerBindingSource.&lt;/p&gt;  &lt;p&gt;The binding information for the BindingSource component and for each bound control is retained in the form’s partial class. When you perform the binding, Visual Studio sets the appropriate control properties. &lt;/p&gt;  &lt;p&gt;The code Visual Studio adds to the partial class for the BindingSource   &lt;br /&gt;component is as follows&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;this.customerBindingSource.DataSource =      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;typeof(SampleBoCSharp.Customer);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Me.CustomerBindingSource.DataSource = GetType(SampleBoVB.Customer)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This defines that the CustomerBindingSource is associated with the Customer class in the associated project.&lt;/p&gt;  &lt;p&gt;Visual Studio adds code to the partial class for each bound control as   &lt;br /&gt;follows&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;this.textBox1.DataBindings.Add(     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new System.Windows.Forms.Binding(&amp;quot;Text&amp;quot;,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.customerBindingSource, &amp;quot;LastName&amp;quot;, true));&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:     &lt;br /&gt;&lt;/strong&gt;    &lt;br /&gt;&lt;font color="#65402e" face="Consolas"&gt;Me.TextBox1.DataBindings.Add( _     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; New System.Windows.Forms.Binding(&amp;quot;Text&amp;quot;, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Me.CustomerBindingSource, &amp;quot;LastName&amp;quot;, True))&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This code adds a binding entry for the TextBox control. The binding entry defines that the Text property of the TextBox is bound to the LastName property in the CustomerBindingSource. The last parameter defines that formatting is enabled to allow formatting of the value.&lt;/p&gt;  &lt;p&gt;NOTE: Although you do not normally need to look at this generated code, there is one case where you may need to know about it. If you use the renaming feature, you will see that the Rename renames only direct references to the property or method, not any occurrences in quoted strings. So if you use   &lt;br /&gt;the rename feature and rename LastName to CustomerLastName, your binding no longer works, because it is still using LastName. You must locate any partial class code that references the property as a quoted string and manually change its name.&lt;/p&gt;  &lt;p&gt;Before you can successfully run the application, you need to write some code. So far, you have defined that the BindingSource component binds to a business object. And you have defined which properties of the business object are to appear in which control of the form. However, you did not define which business object it binds to.&lt;/p&gt;  &lt;p&gt;To define which instance of the business object to bind to, assign the DataSource property of the BindingSource component to a business object instance as follows:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e"&gt;&lt;font face="Consolas"&gt;Customer cust = new Customer()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {LastName = &amp;quot;Baggins&amp;quot;,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName = &amp;quot;Bilbo&amp;quot;};&lt;/font&gt;      &lt;br /&gt;&lt;font face="Consolas"&gt;this.customerBindingSource.DataSource = cust;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;strong&gt;In VB:&lt;/strong&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim cust= New Customer With&amp;#160; _     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {.LastName = &amp;quot;Baggins&amp;quot;, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .FirstName = &amp;quot;Bilbo&amp;quot;}&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;     &lt;br /&gt;Me.CustomerBindingSource.DataSource = cust&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This example binds the controls in the user interface to a new instance of the Product class. Place this binding code in the form. The specific location in the form depends on when you want the binding to occur. If you want the binding to occur when the form is loaded, add this code to the form’s Load event.&lt;/p&gt;  &lt;p&gt;By setting that instance as the DataSource for the CustomerBindingSource, the runtime uses the properties associated with that instance to populate any controls on the form bound to the CustomerBindingSource. So by writing only two lines of code, when you run your application, your form appears populated with appropriate data.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/0511.image_5F00_49A83DA6.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/2570.image_5F00_thumb_5F00_1D8DD166.png" width="288" height="186" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;If the user changes a value in a control on the form, the runtime assigns the revised value to the associated property.&lt;/p&gt;  &lt;p&gt;NOTE: The business object property is assigned to the value from the control when the user leaves the control. By default, if the user modifies a value and then closes the form before leaving the control, the bound property is not changed. However, if you call the &lt;strong&gt;Validate&lt;/strong&gt; method, the current control’s value is assigned to its associated property even if the user does not leave the control.&lt;/p&gt;  &lt;h2&gt;Binding to New Controls&lt;/h2&gt;  &lt;p&gt;Now for the really fun part. In addition to binding to existing controls you can use the features of the Data Sources window to add new controls to a form. Or you can use it to automatically create controls for all of the business object properties.&lt;/p&gt;  &lt;h2&gt;Adding New Controls Using the Data Sources Window&lt;/h2&gt;  &lt;p&gt;If you want to add a new control to a form, you can add the control from the Forms Designer toolbox, add the associated Label control, and then bind the new control using the techniques from the preceding section.&lt;/p&gt;  &lt;p&gt;But the Data Sources window provides a shortcut for this process. If you drag a property from the Data Sources window and drop it on the Forms Designer, Visual Studio creates the control, binds it, and creates the associated Label control. All you need to do is drag and drop!&lt;/p&gt;  &lt;p&gt;To add a new control to a form:&lt;/p&gt;  &lt;p&gt;1. &lt;strong&gt;Open the form&lt;/strong&gt; in the Forms Designer.&lt;/p&gt;  &lt;p&gt;2. &lt;strong&gt;Open the Data Sources window&lt;/strong&gt;. Position the Data Sources window so that you can easily see its contents and the Forms Designer at the same time. &lt;/p&gt;  &lt;p&gt;If a Forms Designer window is active, the Data Sources window changes so that each object data source and each property under the object data source displays an icon to the left of the name. This icon indicates the type of control that Visual Studio creates if you drag the item to the Forms Designer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/4743.image_5F00_50EB8DFB.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/1106.image_5F00_thumb_5F00_27E37FB0.png" width="330" height="334" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;3. &lt;strong&gt;Drag a property from the Data Sources window&lt;/strong&gt;, and &lt;strong&gt;drop it on the     &lt;br /&gt;Forms Designer&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Visual Studio automatically creates the control associated with the dropped property and binds it. It even gives the control a valid name using the property name and the control type, such as FirstNameTextBox—no lame TextBox1 name. In addition, Visual Studio creates an appropriate Label control. Visual Studio is smart about generating the text for the Label control. It breaks the property name into separate words based on either alphabetic casing or underscores.&lt;/p&gt;  &lt;p&gt;For example, if you drag the FirstName property from the Data Sources window and drop it in the CustomerWin form, Visual Studio creates a TextBox control for the First Name and an appropriate Label control.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/5314.image_5F00_229498FF.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/2260.image_5F00_thumb_5F00_3B92F9F5.png" width="474" height="382" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;But what if you don’t want the property to render as a TextBox control? You can change the type of control that is rendered using the Data Sources window.&lt;/p&gt;  &lt;p&gt;To change the default control type associated with a property:&lt;/p&gt;  &lt;p&gt;1. Ensure that a Forms Designer is active.&lt;/p&gt;  &lt;p&gt;2. Open the Data Sources window.&lt;/p&gt;  &lt;p&gt;3. Click a property in the Data Sources window. The property item changes to a drop-down control list.&lt;/p&gt;  &lt;p&gt;4. Drop down the control list and select the desired control type as shown in the prior screen shot of the Data Sources Window. &lt;/p&gt;  &lt;p&gt;Select Customize from the list to select a control type that is not on the list. You can select just about any type of control, including third-party and   &lt;br /&gt;custom controls.&lt;/p&gt;  &lt;p&gt;NOTE: Before a third-party control can be added as a control type in the Data Sources window, it must first be added to the Forms Designer toolbox.&lt;/p&gt;  &lt;p&gt;When you drag the control from the Data Sources window to the Forms Designer, Visual Studio renders the type of control you selected as the default control type for the property. The property retains its default control type in the Data Sources window.&lt;/p&gt;  &lt;h2&gt;Creating a Form from the Data Sources Window&lt;/h2&gt;  &lt;p&gt;But wait—there’s more! You can use the Data Sources window to create all the controls for a business object and bind them.&lt;/p&gt;  &lt;p&gt;To create a new bound form:&lt;/p&gt;  &lt;p&gt;1. &lt;strong&gt;Add a new Windows Form&lt;/strong&gt; to your project.&lt;/p&gt;  &lt;p&gt;2. &lt;strong&gt;Open the Data Sources window&lt;/strong&gt;. Position the Data Sources window so that you can easily see its contents and the Forms Designer window at the same time.&lt;/p&gt;  &lt;p&gt;3. In the Data Sources window, click the object data source you want   &lt;br /&gt;to bind to this form. The item changes to a drop-down control list.&lt;/p&gt;  &lt;p&gt;4. Use the drop-down control list to define how Visual Studio renders controls on the form for this object data source.&lt;/p&gt;  &lt;p&gt;The class object data source can be rendered as Details, DataGridView, or None, or you can select Customize from the control list to select a control type that is not on the list.&lt;/p&gt;  &lt;p&gt;For a data entry form, set the control type for the object data source to &lt;strong&gt;Details&lt;/strong&gt;. Visual Studio renders individual controls for each property in the object data source, along with associated Label controls. Select &lt;strong&gt;DataGridView&lt;/strong&gt; to render the properties in the object data source as columns in a grid.&lt;/p&gt;  &lt;p&gt;5. Drag the object data source node from the Data Sources window and drop it on the form.&lt;/p&gt;  &lt;p&gt;NOTE: If you plan to use Panel or other container controls on the form, place the Panel controls or other containers on the form first, and then drag the object data source node and drop it on the desired container.&lt;/p&gt;  &lt;p&gt;Bang! Visual Studio automatically creates the controls as you specified and binds them. If you selected Details rendering, Visual Studio creates a control based on the default control type for each object data source property in the Data Sources window. It sets each control’s Name property based on the name of the associated business object property and control type. Visual Studio also defines an appropriate Label control for each control it creates. If you selected DataGridView rendering, Visual Studio defines a grid with appropriate columns and column header text.&lt;/p&gt;  &lt;p&gt;For example, if you set up the Customer object data source to render as Details and then drag the Customer node from the Data Sources window and drop it on a form, Visual Studio creates a TextBox control for every property, binds it, names it, and creates a Label control, as shown below.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/8358.image_5F00_38ECCEF5.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/2086.image_5F00_thumb_5F00_76108A7A.png" width="495" height="399" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Notice that this process created two components in the form’s component tray. The &lt;strong&gt;BindingSource&lt;/strong&gt; is the component that manages the binding. The &lt;strong&gt;BindingNavigator&lt;/strong&gt; added VCR-style controls to the top of the form. This type of user interface is not recommended for most business applications. (How often does a user want to sequentially navigate through every customer, for example?) You can delete the BindingNavigator component, and Visual Studio automatically deletes the VCR-style controls.&lt;/p&gt;  &lt;p&gt;The labels created for the controls are generated based on the property names. Visual Studio is smart enough to add spaces between words based on underscores or alphabetic casing. This provides a great starting point for your user interface.&lt;/p&gt;  &lt;p&gt;The controls are added in alphabetical order, which may not be the most logical order or placement for your users. You can move and size the controls as desired. After you have the controls in their desired order, use the Tab Order view to reset the tab order.&lt;/p&gt;  &lt;p&gt;All you need then are those two lines of code in the form’s Load event to   &lt;br /&gt;define the instance of the business object that is bound to the controls:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e"&gt;&lt;font face="Consolas"&gt;Customer cust = new Customer()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {LastName = &amp;quot;Baggins&amp;quot;,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName = &amp;quot;Bilbo&amp;quot;};&lt;/font&gt;      &lt;br /&gt;&lt;font face="Consolas"&gt;this.customerBindingSource.DataSource = cust;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;strong&gt;In VB:&lt;/strong&gt;   &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim cust= New Customer With&amp;#160; _     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {.LastName = &amp;quot;Baggins&amp;quot;, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .FirstName = &amp;quot;Bilbo&amp;quot;}&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;     &lt;br /&gt;Me.CustomerBindingSource.DataSource = cust&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;When you run the application, the runtime automatically populates the    &lt;br /&gt;controls on the form.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/0523.image_5F00_6C4B2302.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/2654.image_5F00_thumb_5F00_3570CEBC.png" width="360" height="232" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The Data Sources window allows you to create all the controls on a form and bind them to a business object with one drag-and-drop operation and two lines of code. It has the flexibility to allow you to define the type of control to render for each property in the object data source.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Using these techniques can make quick work of building and maintaining     &lt;br /&gt;your user interface.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;(Based on an except from &amp;quot;Doing Objects in Visual Basic 2005&amp;quot;.)&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1723916" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/WinForms/default.aspx">WinForms</category></item><item><title>Using Object Binding</title><link>http://msmvps.com/blogs/deborahk/archive/2009/09/08/using-object-binding.aspx</link><pubDate>Tue, 08 Sep 2009 22:23:54 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1721678</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1721678</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/09/08/using-object-binding.aspx#comments</comments><description>&lt;p&gt;As stated &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/09/08/understanding-object-binding.aspx" target="_blank"&gt;here&lt;/a&gt;, you use object binding in a WinForms application by following these steps:&lt;/p&gt;  &lt;p&gt;1. Build the business objects for your application.&lt;/p&gt;  &lt;p&gt;2. Define a business object data source in the Windows Application    &lt;br /&gt;project containing your user interface.&lt;/p&gt;  &lt;p&gt;3. Bind properties of the controls on the form to business object    &lt;br /&gt;properties.&lt;/p&gt;  &lt;h2&gt;Building the Business Objects&lt;/h2&gt;  &lt;p&gt;The idea with object binding is to bind your business objects to your user interface controls. So the first step is to create the business objects. This example builds a Customer class.&lt;/p&gt;  &lt;p&gt;NOTE: Add a Class Library project to your solution and create the Customer class in the Class Library project. You could add the Customer class to your WinForms project, but it is not recommended.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public class Customer      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public int CustomerId { get; set; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public string LastName { get; set; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public string FirstName { get; set; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public string EmailAddress { get; set; }       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The above code takes advantage of automatically implemented properties. VB does not yet have this feature, but it is expected with VB 10.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Class Customer&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Private _CustomerId As Integer      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property CustomerId() As Integer       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _CustomerId       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As Integer)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _CustomerId = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Private _FirstName As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property FirstName() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _FirstName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _FirstName = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Private _LastName As String&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property LastName() As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _LastName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _LastName = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Private _EmailAddress As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property EmailAddress () As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _EmailAddress       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _EmailAddress = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property       &lt;br /&gt;End Class&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Configuring a Data Source&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In Visual Studio, a &lt;strong&gt;data source&lt;/strong&gt; defines the source of data, such as a business object or a database. To use a data source to bind your user interface, you need to configure the data source for the project containing your user interface, such as your Windows Application project.&lt;/p&gt;  &lt;p&gt;For object binding, each data source represents a single business object class. This means that you configure a data source for each business object class that you want to bind. Luckily, this process is quick and easy.&lt;/p&gt;  &lt;p&gt;When you use object binding, the data source is referred to as an &lt;strong&gt;object data source&lt;/strong&gt;. This is technically accurate because at runtime, the binding binds to a specific business object. However, this can look a little confusing at design-time because each data source represents a single business object class. The Data Sources window displays each object data source with the class name and lists the public properties of the class. You then bind each property of the class to a control on the form.&lt;/p&gt;  &lt;p&gt;To set up an object data source for your user interface:&lt;/p&gt;  &lt;p&gt;1. Build your business object Class Library project.    &lt;br /&gt;Only compiled business object classes are recognized by the Data     &lt;br /&gt;Source Configuration Wizard and the Data Sources window.&lt;/p&gt;  &lt;p&gt;2. Select the Windows Application project in Solution Explorer.    &lt;br /&gt;NOTE: Always ensure that the Windows Application project is selected in     &lt;br /&gt;Solution Explorer before you work with the Data Sources window.&lt;/p&gt;  &lt;p&gt;3. Select Data | Show Data Sources from the main menu bar.    &lt;br /&gt;The Data Sources window is displayed.&lt;/p&gt;  &lt;p&gt;4. Click the Add New Data Source link in the Data Sources window, &lt;strong&gt;or &lt;/strong&gt;click the Add New Data Source button on the Data Sources window toolbar, &lt;strong&gt;or &lt;/strong&gt;select Data | Add New Data Source from the main menu bar.     &lt;br /&gt;    &lt;br /&gt;NOTE: The Add New Data Source link only appears when the Data Sources     &lt;br /&gt;window is empty.&lt;/p&gt;  &lt;p&gt;This launches the Data Source Configuration Wizard. The first page, shown below, allows you to select the source of the data.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/2577.image_5F00_229EF995.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/0820.image_5F00_thumb_5F00_49036D91.png" width="395" height="310" /&gt;&lt;/a&gt;     &lt;br /&gt;    &lt;br /&gt;5. Select Object for object binding, and click Next.&lt;/p&gt;  &lt;p&gt;The second page of the Data Source Configuration Wizard, shown below, provides the list of classes for your selection.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/3731.image_5F00_43B486E0.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/1104.image_5F00_thumb_5F00_659FE964.png" width="390" height="306" /&gt;&lt;/a&gt; &lt;/p&gt; The tree view only lists the classes in the Windows Application   &lt;br /&gt;project and classes in any component referenced by the Windows   &lt;br /&gt;Application project. If you already have a reference to your business object Class Library component, the component appears in the Data Source   &lt;br /&gt;Configuration Wizard. Otherwise, you can add a reference using the Add Reference button.   &lt;p&gt;6. Use the tree view to navigate to the class you wish to use for object binding.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/3225.image_5F00_232FD7DF.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/6378.image_5F00_thumb_5F00_00DAD317.png" width="386" height="303" /&gt;&lt;/a&gt;     &lt;br /&gt;    &lt;br /&gt;7. Select the desired class, and click Finish.     &lt;br /&gt;The object data source for the selected class is added to the Data     &lt;br /&gt;Sources window, as shown below.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/4214.image_5F00_5B70DFA8.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/3644.image_5F00_thumb_5F00_7D5C422C.png" width="239" height="270" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;NOTE: The Data Sources window lists only public class properties.&lt;/p&gt;  &lt;p&gt;Use the Data Source Configuration Wizard to define a data source for every business object class you plan to use for binding.&lt;/p&gt;  &lt;p&gt;If you are curious about where the Data Sources window stores its information, it is in a set of XML files. Select the Windows Application project in Solution Explorer, and click the Show All Files button on the Solution Explorer toolbar. All the system files for the project are then accessible from Solution Explorer. Open the Properties node (My Project node in VB) under the Windows Application project, and open the DataSources node to see the XML files for the data sources in the Data Sources window.&lt;/p&gt;  &lt;p&gt;Creating data sources is quick and easy. Add a data source to the Windows Application project for any business object class that you want to use for binding to your user interface.&lt;/p&gt;  &lt;h2&gt;Bind the User Interface Controls&lt;/h2&gt;  &lt;p&gt;There are many ways to bind the resulting object data source to your user interface. These are covered in a &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/09/16/binding-control-properties-to-business-object-properties.aspx" target="_blank"&gt;later post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;(Based on an except from &amp;quot;Doing Objects in Visual Basic 2005&amp;quot;.)&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1721678" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/WinForms/default.aspx">WinForms</category></item><item><title>Understanding Object Binding</title><link>http://msmvps.com/blogs/deborahk/archive/2009/09/08/understanding-object-binding.aspx</link><pubDate>Tue, 08 Sep 2009 19:26:34 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1721653</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1721653</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/09/08/understanding-object-binding.aspx#comments</comments><description>&lt;p&gt;Before going through the details of how to use object binding, it is important to understand exactly what it is—and what it is not. Object binding is binding your business object properties to user interface elements. Object binding is not database binding in the strict sense of the term. It does not directly collect or bind any data from your database.&lt;/p&gt;  &lt;p&gt;When you are using business object classes &lt;em&gt;without&lt;/em&gt; object binding, the flow of data from the database to your user interface and back again requires these steps:&lt;/p&gt;  &lt;p&gt;1. The &lt;strong&gt;business object calls the data access component&lt;/strong&gt; to get the data from the database and sets the business object properties using that data.&lt;/p&gt;  &lt;p&gt;For example, the Product class calls the data access component, which uses a query or stored procedure to fill a DataTable from the Product table. The data access component returns the DataTable to the Product class, which assigns each field from the table to a property of the object. To illustrate, the line of code required to get the ProductName field from the DataTable and set the    &lt;br /&gt;ProductName property is as follows:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;myProduct.ProductName = dt.Rows[0][&amp;quot;ProductName&amp;quot;];&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;myProduct.ProductName = dt.Rows(0).Item(&amp;quot;ProductName&amp;quot;)&lt;/font&gt;     &lt;br /&gt;    &lt;br /&gt;2. The &lt;strong&gt;user interface component accesses the business object&lt;/strong&gt; properties to fill the values of the controls on the form.&lt;/p&gt;  &lt;p&gt;For example, each control on the ProductWin form is assigned to the value of the appropriate Product business object property. To illustrate, the line of code required to set the Text property of the Name TextBox control to the ProductName property of the Product business object is as follows:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;NameTextBox.Text = myProduct.ProductName&lt;/font&gt;;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;NameTextBox.Text = myProduct.ProductName&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;3. After the user makes any changes, the user interface component assigns the current &lt;strong&gt;values in the controls back to the business object&lt;/strong&gt; properties.&lt;/p&gt;  &lt;p&gt;For example, the value in each control on the ProductWin form is assigned back to its associated Product business object property. To illustrate, the line of code required to set the ProductName property to the current value in the Name TextBox control is as follows:&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;myProduct.ProductName = NameTextBox.Text&lt;/font&gt;;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;myProduct.ProductName = NameTextBox.Text&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;4. The &lt;strong&gt;business object component updates the DataTable&lt;/strong&gt; using the property values and passes it back to the data access component, which updates the database with the changed data. &lt;/p&gt;  &lt;p&gt;For example, the value of each Product business object property is assigned to the associated field in the DataTable, and the result is passed to the data access component, which updates the Product table. To illustrate, the line of code required to set the ProductName field in the DataTable to the value of the ProductName business object property is as follows:&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;dt.Rows[0][&amp;quot;ProductName&amp;quot;] = myProduct.ProductName;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;dt.Rows(0).item(&amp;quot;ProductName&amp;quot;) = myProduct.ProductName&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Using object binding allows you to skip steps 2 and 3. Object binding automatically populates the controls on the user interface from the business object properties. As the users change the contents of the controls, object binding updates the associated business object properties, keeping them in synchronization.&lt;/p&gt;  &lt;p&gt;That still leaves steps 1 and 4 for you. This &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/07/07/dal-data-access-layer.aspx" target="_blank"&gt;link&lt;/a&gt; provides information on building a data access component to handle steps 1 and 4.&lt;/p&gt;  &lt;p&gt;In summary, object binding is the process of binding control properties directly to properties of your business objects. For example, you could bind the Text property of a TextBox control to the ProductName property of a Product business object. When the form is displayed, the runtime automatically displays the value of the ProductName property in the TextBox. And if the user changes the text in the TextBox control, the runtime modifies the ProductName property accordingly. This saves you from writing the code required to transfer data back and forth between the controls on the user interface and the business object properties.&lt;/p&gt;  &lt;p&gt;Visual Studio provides design-time tools for working with your business objects as data sources for your user interface, making it easy to bind each control to its associated business object property. The only requirement for your business objects to work with these tools is that the business object class needs at least one public property. No specific constructors, interfaces, or attributes are needed.&lt;/p&gt;  &lt;h2&gt;Object Binding Versus Data Binding&lt;/h2&gt;  &lt;p&gt;Don’t confuse the term object binding with the more generalized term data binding. Data binding is the broad term for binding control properties to data from any data source. Object binding is just one type of data binding. Some common types of data binding are as follows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Binding to tables in a database (Visual Studio generates code to      &lt;br /&gt;define a typed DataSet and TableAdapters) &lt;/li&gt;    &lt;li&gt;Binding to stored procedures in a database (Visual Studio generates      &lt;br /&gt;code to define a typed DataSet and TableAdapters) &lt;/li&gt;    &lt;li&gt;Binding to a business object (object binding does not generate code;      &lt;br /&gt;it just sets control properties) &lt;/li&gt;    &lt;li&gt;Binding to an array or collection of data &lt;/li&gt;    &lt;li&gt;Binding to a Web service &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;When binding to a database, Visual Studio generates a significant amount of code and then binds the user interface to that generated code. Object binding binds to &lt;strong&gt;your&lt;/strong&gt; code. That gives you much more control and greatly simplifies the maintenance of your application.     &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Using Object Binding&lt;/h2&gt;  &lt;p&gt;You use object binding by following these steps:&lt;/p&gt;  &lt;p&gt;1. Build the business objects for your application.&lt;/p&gt;  &lt;p&gt;2. Define a business object data source in the Windows Application    &lt;br /&gt;project containing your user interface.&lt;/p&gt;  &lt;p&gt;3. Bind properties of the controls on the form to business object    &lt;br /&gt;properties.&lt;/p&gt;  &lt;p&gt;Although it is much easier to think about object binding as a direct binding of a control’s property to a specific business object’s property, object binding frequently uses a BindingSource component as an intermediary. A &lt;strong&gt;BindingSource&lt;/strong&gt; is a component on a form that binds the controls on the form to the business object. Each control is bound to the BindingSource component, which in turn is bound to the business object. This makes it much easier to change the binding for all controls by changing the BindingSource without having to separately rebind each control.&lt;/p&gt;  &lt;p&gt;You set the BindingSource to an individual business object instance in your code. The runtime then binds all the properties associated with that instance to the controls, thereby displaying the business object property values in the controls. And as the user changes the content of any controls, the business object property values are changed accordingly.&lt;/p&gt;  &lt;p&gt;A form can contain multiple BindingSource components. For example, a ProductWin form can contain product data and display a drop-down list of product types. You can define a BindingSource component for the product data and a second BindingSource component for the product type data.&lt;/p&gt;  &lt;p&gt;(Based on an except from &amp;quot;Doing Objects in Visual Basic 2005&amp;quot;.)&lt;/p&gt;  &lt;p&gt;For more information on object binding, see these links:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/09/08/using-object-binding.aspx" target="_blank"&gt;Using Object Binding&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/09/16/binding-control-properties-to-business-object-properties.aspx"&gt;Binding Control Properties to Business Object Properties&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1721653" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/OOP/default.aspx">OOP</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category></item><item><title>Using Linq with Microsoft Word and Excel</title><link>http://msmvps.com/blogs/deborahk/archive/2009/08/14/using-linq-with-microsoft-word-and-excel.aspx</link><pubDate>Fri, 14 Aug 2009 20:14:16 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1715753</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1715753</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/08/14/using-linq-with-microsoft-word-and-excel.aspx#comments</comments><description>&lt;p&gt;Some of the collections in the Microsoft Office object models implement IEnumerable. The IEnumerable interface provides the ability to perform a for/each against the collection. With .NET 3.5, a Cast extension method of IEnumerable allows you to work with these collections using Linq.&lt;/p&gt;  &lt;h2&gt;Microsoft Word&lt;/h2&gt;  &lt;p&gt;For example, say you want to bind the set of open Word document names in a ComboBox.&lt;/p&gt;  &lt;p&gt;First, set a reference to the desired version of the &lt;strong&gt;Microsoft Word Object Library&lt;/strong&gt; from the COM tab of the Add Reference dialog. The resulting reference appears as Microsoft.Office.Interop.Word.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Add to the top of the code file      &lt;br /&gt;using Word = Microsoft.Office.Interop.Word;       &lt;br /&gt;      &lt;br /&gt;// Add to a subroutine       &lt;br /&gt;Word.Application Wd;       &lt;br /&gt;Word.Document doc;       &lt;br /&gt;Word.Document doc2;       &lt;br /&gt;object missingValue = Missing.Value; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Start Word and get Application object      &lt;br /&gt;Wd = new Word.Application(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Define documents      &lt;br /&gt;doc = Wd.Documents.Add(ref missingValue,ref missingValue,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ref missingValue,ref missingValue );       &lt;br /&gt;doc2 = Wd.Documents.Add(ref missingValue, ref missingValue,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ref missingValue, ref missingValue); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Use Linq to access the document names.      &lt;br /&gt;var query = from d in Wd.Documents.Cast&amp;lt;Word.Document&amp;gt;()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select d.Name;       &lt;br /&gt;comboBox1.DataSource = query.ToList(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Or use Lambda expressions      &lt;br /&gt;var query2 = Wd.Documents.Cast&amp;lt;Word.Document&amp;gt;().Select(d=&amp;gt; d.Name);       &lt;br /&gt;comboBox1.DataSource = query2.ToList(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Close      &lt;br /&gt;doc.Close(ref missingValue, ref missingValue, ref missingValue);       &lt;br /&gt;doc = null;       &lt;br /&gt;doc2.Close(ref missingValue, ref missingValue, ref missingValue);       &lt;br /&gt;doc2 = null;       &lt;br /&gt;Wd.Quit(ref missingValue, ref missingValue, ref missingValue); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Clean up      &lt;br /&gt;// NOTE: When in release mode, this does the trick       &lt;br /&gt;GC.WaitForPendingFinalizers();       &lt;br /&gt;GC.Collect();       &lt;br /&gt;GC.WaitForPendingFinalizers();       &lt;br /&gt;GC.Collect() ;&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Add to the top of the code file      &lt;br /&gt;Imports Word = Microsoft.Office.Interop.Word&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Add to a subroutine      &lt;br /&gt;Dim Wd As Word.Application       &lt;br /&gt;Dim doc As Word.Document       &lt;br /&gt;Dim doc2 As Word.Document       &lt;br /&gt;      &lt;br /&gt;&amp;#39; Start Word and get Application object       &lt;br /&gt;Wd = New Word.Application&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Define documents      &lt;br /&gt;doc = Wd.Documents.Add       &lt;br /&gt;doc2 = Wd.Documents.Add &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Use Linq to access the document names.      &lt;br /&gt;Dim query = From d In Wd.Documents.Cast(Of Word.Document)() _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select d.Name       &lt;br /&gt;ComboBox1.DataSource = query.ToList &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Or use Lambda expressions      &lt;br /&gt;Dim query2 = Wd.Documents.Cast(Of Word.Document) _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(Function(d) d.Name)       &lt;br /&gt;ComboBox1.DataSource = query2.ToList &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Close      &lt;br /&gt;doc.Close()       &lt;br /&gt;doc = Nothing       &lt;br /&gt;doc2.Close()       &lt;br /&gt;doc2 = Nothing       &lt;br /&gt;Wd.Quit() &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Clean up      &lt;br /&gt;&amp;#39; NOTE: When in release mode, this does the trick       &lt;br /&gt;GC.WaitForPendingFinalizers()       &lt;br /&gt;GC.Collect()       &lt;br /&gt;GC.WaitForPendingFinalizers()       &lt;br /&gt;GC.Collect()&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In both of these examples, the code starts Word, creates two Word documents, uses either Linq or a Lambda expression to define a query and then binds the resulting set of document names to a Combo Box.&lt;/p&gt;  &lt;p&gt;Notice the missingValue variable in the C# code that is not in the VB code. VB supports default parameters, but C# does not. So any time a parameter is defined for a Word method, C# must provide it. VB will use the default parameter values.&lt;/p&gt;  &lt;p&gt;NOTE: A new feature in C# 4.0 (Visual Studio 2010) allows for default parameters in C# as well, dramatically simplifying the C# code that interacts with Word or Excel.&lt;/p&gt;  &lt;p&gt;As another example, the following code retrieves all of the words from the defined Word document.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt; &lt;font color="#65402e" face="Consolas"&gt;var query = from w in doc.Words.Cast&amp;lt;Word.Range&amp;gt;()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select w.Text;     &lt;br /&gt;comboBox1.DataSource = query.ToList();&lt;/font&gt;   &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim query = From w In doc.Words.Cast(Of Word.Range)() _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select w.Text       &lt;br /&gt;ComboBox1.DataSource = query3.ToList&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This code retrieves all of the words in the document defined by the doc variable. Instead of selecting the list of words, you could use any Linq feature such as finding only a specific set of words that match a criteria or counting the number of occurrences of a given word.&lt;/p&gt;  &lt;h2&gt;Microsoft Excel&lt;/h2&gt;  &lt;p&gt;This technique works with Excel as well. Say you want to bind the list of spreadsheets in an Excel workbook.&lt;/p&gt;  &lt;p&gt;First, set a reference to the desired version of the &lt;strong&gt;Microsoft Excel Object Library&lt;/strong&gt; from the COM tab of the Add Reference dialog. The resulting reference appears as Microsoft.Office.Interop.Excel.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In C#:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Add to the top of the code file      &lt;br /&gt;using Excel = Microsoft.Office.Interop.Excel;       &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Add to a subroutine      &lt;br /&gt;Excel.Application oXL;       &lt;br /&gt;Excel.Workbook oWB;       &lt;br /&gt;Excel.Worksheet oSheet;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Start Excel and get Application object.      &lt;br /&gt;oXL = new Excel.Application(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Get a new workbook.      &lt;br /&gt;oWB = oXL.Workbooks.Add(Missing.Value); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Get the active sheet and change its name      &lt;br /&gt;oSheet = (Excel.Worksheet)oWB.ActiveSheet ;       &lt;br /&gt;oSheet.Name = &amp;quot;Test&amp;quot;;       &lt;br /&gt;      &lt;br /&gt;// Use Linq to access the spreadsheet names.       &lt;br /&gt;var query = from s in oXL.Worksheets.Cast&amp;lt;Excel.Worksheet&amp;gt;()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; select s.Name;       &lt;br /&gt;comboBox1.DataSource = query.ToList(); &lt;/font&gt;&lt;/p&gt; &lt;font color="#65402e" face="Consolas"&gt;// Or use Lambda expressions.    &lt;br /&gt;var query2 = oXL.Worksheets.Cast&amp;lt;Excel.Worksheet&amp;gt;()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .select(s =&amp;gt; s.Name);     &lt;br /&gt;comboBox1.DataSource = query2.ToList(); &lt;/font&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Close      &lt;br /&gt;oSheet = null;       &lt;br /&gt;oWB.Close(Missing.Value, Missing.Value, Missing.Value);       &lt;br /&gt;oWB = null;       &lt;br /&gt;oXL.Quit(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Clean up      &lt;br /&gt;// NOTE: When in release mode, this does the trick       &lt;br /&gt;GC.WaitForPendingFinalizers();       &lt;br /&gt;GC.Collect();       &lt;br /&gt;GC.WaitForPendingFinalizers();       &lt;br /&gt;GC.Collect();&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In VB:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Add to the top of the code file      &lt;br /&gt;Imports Excel = Microsoft.Office.Interop.Excel &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Add to a subroutine      &lt;br /&gt;Dim oXL As Excel.Application       &lt;br /&gt;Dim oWB As Excel.Workbook       &lt;br /&gt;Dim oSheet As Excel.Worksheet       &lt;br /&gt;      &lt;br /&gt;&amp;#39; Start Excel and get Application object.       &lt;br /&gt;oXL = New Excel.Application       &lt;br /&gt;      &lt;br /&gt;&amp;#39; Get a new workbook.       &lt;br /&gt;oWB = oXL.Workbooks.Add       &lt;br /&gt;      &lt;br /&gt;&amp;#39; Get the active sheet and change its name       &lt;br /&gt;oSheet = DirectCast(oWB.ActiveSheet, Excel.Worksheet)       &lt;br /&gt;oSheet.Name = &amp;quot;Test&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Use Linq to access the spreadsheet names.      &lt;br /&gt;Dim query = From s In oXL.Worksheets.Cast(Of Excel.Worksheet)() _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Select s.Name       &lt;br /&gt;ComboBox1.DataSource = query.ToList       &lt;br /&gt;      &lt;br /&gt;&amp;#39; Or use Lambda expressions       &lt;br /&gt;Dim query2 = oXL.Worksheets.Cast(Of Excel.Worksheet) _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(Function(s) s.Name)       &lt;br /&gt;ComboBox1.DataSource = query2.ToList&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Close      &lt;br /&gt;oSheet = Nothing       &lt;br /&gt;oWB.Close()       &lt;br /&gt;oWB = Nothing       &lt;br /&gt;oXL.Quit()       &lt;br /&gt;      &lt;br /&gt;&amp;#39; Clean up       &lt;br /&gt;&amp;#39; NOTE: When in release mode, this does the trick       &lt;br /&gt;GC.WaitForPendingFinalizers()       &lt;br /&gt;GC.Collect()       &lt;br /&gt;GC.WaitForPendingFinalizers()       &lt;br /&gt;GC.Collect()&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In both examples, the code starts Excel, changes the name of the active sheet, uses either Linq or a Lambda expression to define a query and then binds the resulting set of sheet names to a Combo Box.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;  &lt;p&gt;EDITED 11/16/09: Added information on setting the appropriate reference.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1715753" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Lambda/default.aspx">Lambda</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Excel/default.aspx">Excel</category></item><item><title>Building a Business Object Base Class</title><link>http://msmvps.com/blogs/deborahk/archive/2009/07/21/building-a-business-object-base-class.aspx</link><pubDate>Tue, 21 Jul 2009 18:49:48 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1704681</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1704681</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/07/21/building-a-business-object-base-class.aspx#comments</comments><description>&lt;p&gt;If you are building applications in .NET to manage data for a business, you are most likely creating business object classes. Depending on the business, these classes could include Customer, Product, Order, Invoice, PurchaseOrder, Employee, TimeCard and so on.&lt;/p&gt;  &lt;p&gt;A simple sample Customer class is shown &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/07/03/generics-building-a-list-of-customers.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;There are some features that all business objects need to support. For example:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Entity State: The business object needs to track whether it is new, updated, or deleted so it can make the appropriate change to the database. &lt;/li&gt;    &lt;li&gt;Validation: Is the current data defined for the business object valid? &lt;/li&gt;    &lt;li&gt;Save: Saves the changes to the database. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Notice that data retrieval functionality is not included in this list. That is because in most cases, you may never retrieve a single business object. Rather, you would retrieve a set of them. For example, all active orders or all customers with overdue invoices. So the retrieve functionality is not included in the class that manages a single object. (Most on this in a later post.)&lt;/p&gt;  &lt;p&gt;Instead of repeating this common functionality in each business object, it makes sense to build a base class. Each business object can then inherit from this base class to share this common functionality.&lt;/p&gt;  &lt;p&gt;So let’s get started.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;using System;      &lt;br /&gt;using System.ComponentModel;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public abstract class BoBase :      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; IDataErrorInfo,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; INotifyPropertyChanged       &lt;br /&gt;{       &lt;br /&gt;      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Imports System.ComponentModel      &lt;br /&gt;      &lt;br /&gt;Public MustInherit Class BOBase       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Implements IDataErrorInfo       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Implements INotifyPropertyChanged       &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;End Class&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The class is abstract (MustInherit in VB) to indicate that it is meant to be a base class and not to be used on its own. An abstract class cannot be instantiated directly, so no other code can create an instance of the class.&lt;/p&gt;  &lt;p&gt;The class then implements two interfaces:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;IDataErrorInfo: This interface provides error information that the user interface can use to report validation errors to the user. It works well with the ErrorProvider control provided in WinForms and supports ASP.NET and WPF features. &lt;/li&gt;    &lt;li&gt;INotifyPropertyChanged: This interface ensures that the user interface is notified when a property value changes, keeping your business object and user interface in sync. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We’ll look at the implementation of these interfaces shortly.&lt;/p&gt;  &lt;p&gt;First, define the valid set of entity states.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;protected internal enum EntityStateType      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Unchanged,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Added,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Deleted,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Modified       &lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Protected Friend Enum EntityStateType      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Unchanged       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Added       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Deleted       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Modified       &lt;br /&gt;End Enum&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;The Enum is declared Protected because the entity state should only be accessible from the business object itself. However, Internal (Friend in VB) was added so that related objects (such as Order and OrderLineItem) could reference the related object state.&lt;/p&gt;  &lt;p&gt;The business object state is retained using an EntityState property.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;protected EntityStateType EntityState { get; private set; }&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private _EntityState As EntityStateType      &lt;br /&gt;Protected Property EntityState() As EntityStateType       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _EntityState       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Set(ByVal value As EntityStateType)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _EntityState = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;This property is protected, but the setter is private. So the business objects that inherit from this class can read the entity state, but only the base class can set the value.&lt;/p&gt;  &lt;p&gt;Additional properties provide a way to get the entity’s state in an easier fashion. These properties are not required, but they make the base class a little easier to use.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;[BindableAttribute(false)]      &lt;br /&gt;[BrowsableAttribute(false)]       &lt;br /&gt;public bool IsDirty       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; get { return this.EntityState != EntityStateType.Unchanged; }       &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;[BindableAttribute(false)]      &lt;br /&gt;[BrowsableAttribute(false)]       &lt;br /&gt;public bool IsNew       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; get { return this.EntityState == EntityStateType.Added; }       &lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;lt;BindableAttribute(False)&amp;gt; _      &lt;br /&gt;&amp;lt;BrowsableAttribute(False)&amp;gt; _       &lt;br /&gt;Public ReadOnly Property IsDirty() As Boolean       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Me.EntityState &amp;lt;&amp;gt; EntityStateType.Unchanged       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;lt;BindableAttribute(False)&amp;gt; _      &lt;br /&gt;&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;lt;BrowsableAttribute(False)&amp;gt; _      &lt;br /&gt;Public ReadOnly Property IsNew() As Boolean       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return Me.EntityState = EntityStateType.Added       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;End Property&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;The IsDirty and IsNew properties are public, so they can be accessed from anywhere. They are marked with two attributes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Bindable: Defines whether the property should be used for binding. In this case the value is false because the user interface should not be able to bind to this property. &lt;/li&gt;    &lt;li&gt;Browsable: Defines whether the property should be displayed in the Properties window. Again, the value is false. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Two other properties handle the validation.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;[BindableAttribute(false)]      &lt;br /&gt;[BrowsableAttribute(false)]       &lt;br /&gt;public bool IsValid       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; get { return (ValidationInstance.Count == 0); }       &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;protected Validation ValidationInstance { get; set; }&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt; &lt;font color="#65402e" face="Consolas"&gt;&amp;lt;Bindable(False)&amp;gt; _&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;lt;BrowsableAttribute(False)&amp;gt; _     &lt;br /&gt;Public ReadOnly Property IsValid() As Boolean     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return (ValidationInstance.Count = 0)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get     &lt;br /&gt;End Property &lt;/font&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private _ValidationInstance As Validation      &lt;br /&gt;Protected Property ValidationInstance() As Validation       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _ValidationInstance       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Private Set(ByVal value As Validation)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _ValidationInstance = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Again, the public property is marked with the Browsable and Bindable attributes. The ValidationInstance property retains an instance of the Validation class for the business object. The code for the Validation class is &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/07/16/validation-class.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The constructor creates an instance of the Validation class.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;protected BoBase()      &lt;br /&gt;{&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; ValidationInstance = new Validation();       &lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Protected Sub New()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ValidationInstance = New Validation      &lt;br /&gt;End Sub&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The following is the implementation of IDataErrorInfo.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;#region IDataErrorInfo Members &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;[BrowsableAttribute(false)]      &lt;br /&gt;[BindableAttribute(false)]       &lt;br /&gt;public string Error       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; get { return ValidationInstance.ToString(); }       &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;[BrowsableAttribute(false)]      &lt;br /&gt;[BindableAttribute(false)]       &lt;br /&gt;public string this[string columnName]       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; get { return ValidationInstance[columnName]; }       &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;#endregion&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;#Region &amp;quot; Properties required by the IDataErrorInfo&amp;quot;      &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Bindable(False)&amp;gt; _&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;BrowsableAttribute(False)&amp;gt; _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public ReadOnly Property [Error]() As String _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Implements IDataErrorInfo.Error       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return ValidationInstance.ToString       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;BrowsableAttribute(False)&amp;gt; _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Bindable(False)&amp;gt; _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Default Protected ReadOnly Property Item(ByVal columnName _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; As String) As String _&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Implements IDataErrorInfo.Item       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return ValidationInstance.Item(columnName)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property       &lt;br /&gt;      &lt;br /&gt;#End Region&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;Error&lt;/strong&gt; property uses the overridden ToString method of the validation class to return the full list of validation errors.&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;Item&lt;/strong&gt; property provides access to the validation errors given a property name. This property is implemented as the class indexer in C#.&lt;/p&gt;  &lt;p&gt;The following in the implementation of INotifyPropertyChanged.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;#region INotifyPropertyChanged Members     &lt;br /&gt;public event PropertyChangedEventHandler PropertyChanged;      &lt;br /&gt;#endregion&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;#Region &amp;quot; Events required by INotifyPropertyChanged&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Event PropertyChanged(ByVal sender As Object, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal e As System.ComponentModel.PropertyChangedEventArgs) _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Implements INotifyPropertyChanged.PropertyChanged      &lt;br /&gt;#End Region&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This interface only defines a single event. This event should be raised whenever the data is changed.&lt;/p&gt;  &lt;p&gt;Since every business object will have unique requirements for the save operation, the &lt;strong&gt;SaveItem&lt;/strong&gt; method is not implemented. Rather it is defined as abstract.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public abstract Boolean SaveItem();&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public MustOverride Function SaveItem() As Boolean&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Defining an abstract (MustOverride in VB) SaveItem method ensures that every business object has a SaveItem method.&lt;/p&gt;  &lt;p&gt;Finally, since the EntityState property setter is private, the base class needs a method to set the entity state.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;protected internal void SetEntityState(EntityStateType newEntityState)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; switch (newEntityState)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; case EntityStateType.Deleted:      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; case EntityStateType.Unchanged:      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; case EntityStateType.Added:      &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.EntityState = newEntityState;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; default:     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (this.EntityState == EntityStateType.Unchanged)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.EntityState = newEntityState;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;protected internal void SetEntityState(EntityStateType newEntityState, string propertyName)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetEntityState(newEntityState);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (PropertyChanged != null)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyChanged(this,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;new PropertyChangedEventArgs(propertyName));     &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Protected Friend Sub SetEntityState(ByVal dataState As EntityStateType)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SetEntityState(dataState, Nothing)      &lt;br /&gt;End Sub &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Protected Friend Sub SetEntityState( _     &lt;br /&gt; ByVal newEntityState As EntityStateType, ByVal propertyName As String)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Select Case newEntityState      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Case EntityStateType.Deleted, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EntityStateType.Unchanged, _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EntityStateType.Added      &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Me.EntityState = newEntityState &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Case Else     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If Me.EntityState = EntityStateType.Unchanged Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Me.EntityState = newEntityState      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Select &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; If Not String.IsNullOrEmpty(propertyName) Then     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim e As New PropertyChangedEventArgs(propertyName)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RaiseEvent PropertyChanged(Me, e)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;End Sub&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;SetEntityState&lt;/strong&gt; method has two overloads. The first is used when changing the entity state in general and the second is used when changing the entity state because a specific property is changed.&lt;/p&gt;  &lt;p&gt;For example, when setting an object as Unchanged, Added, or Deleted, it does not matter which property was changed. But when a particular property is changed, the code must also raise the PropertyChanged event.&lt;/p&gt;  &lt;p&gt;In this case, the C# and VB code was implemented differently. In the C# code, the code to set the entity state is in the first overload. The second overload then calls the first and then raises the event.&lt;/p&gt;  &lt;p&gt;In the VB code, the first overload simply calls the second overload. The second overload then sets the entity state and then raises the event as appropriate. You can use either technique in either language.&lt;/p&gt;  &lt;p&gt;That’s it! You now have a base class that can be used with any business object class. If you have any other common functionality, you can add it to this base class. &lt;/p&gt;  &lt;p&gt;Here is an example of how you use this base class.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public class Customer : BoBase     &lt;br /&gt;{      &lt;br /&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private string _LastName;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public string LastName      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return _LastName; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (_LastName == null || _LastName != value)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string propertyName = &amp;quot;LastName&amp;quot;;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _LastName = value; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Validate the last name     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationInstance.ValidateClear(propertyName);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationInstance.ValidateRequired(propertyName, value); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SetEntityState(EntityStateType.Modified, propertyName);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; public override Boolean SaveItem()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // TODO: Add code here      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Class Customer     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Inherits BoBase&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Private _LastName As String     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Public Property LastName() As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Get      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _LastName      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Get      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As String)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If _LastName Is Nothing OrElse _LastName &amp;lt;&amp;gt; value Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim propertyName As String = &amp;quot;LastName&amp;quot;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _LastName = value &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;#39; Validate the last name     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationInstance.ValidateClear(propertyName)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ValidationInstance.ValidateRequired(propertyName, value) &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SetEntityState(EntityStateType.Modified, propertyName)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End Set      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Property&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Public Overrides Function SaveItem() As Boolean     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;#39; TODO: Add code here      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Function      &lt;br /&gt;End Class&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Notice how the class statement includes the syntax to inherit from BoBase. The LastName property uses the ValidationInstance defined in the base class to validate the value. It also sets the entity state when the last name is changed.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1704681" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/OOP/default.aspx">OOP</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Enum/default.aspx">Enum</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category></item><item><title>Dates: Binding to Day Numbers</title><link>http://msmvps.com/blogs/deborahk/archive/2009/07/14/dates-binding-to-day-numbers.aspx</link><pubDate>Tue, 14 Jul 2009 21:07:07 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1701370</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1701370</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/07/14/dates-binding-to-day-numbers.aspx#comments</comments><description>&lt;p&gt;My &lt;a href="http://msmvps.com/blogs/deborahk/archive/2009/07/14/dates-binding-to-month-names.aspx" target="_blank"&gt;prior post&lt;/a&gt; demonstrated how to bind to a list of month names. Once the user picks the desired month, you may want to provide a list of valid dates to pick a date in that month. For example: 1-30 for September and 1-31 for July.&lt;/p&gt;  &lt;p&gt;You can accomplish this using a switch statement (Select Case in VB), but that hard-codes the dates, does not handle leap year, and does not support localization.&lt;/p&gt;  &lt;p&gt;Another option is to use the culture specific calendar as shown below.&lt;/p&gt;  &lt;p&gt;The code is first shown in both VB and C#. It is then described in detail below.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;private List&amp;lt;int&amp;gt; GetListOfDays(int yearNumber , int monthNumber)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Calendar currentCalendar&amp;#160; = CultureInfo.CurrentCulture.Calendar;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int numberOfDays&amp;#160; =       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; currentCalendar.GetDaysInMonth(yearNumber, monthNumber);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return Enumerable.Range(1, numberOfDays).ToList();      &lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private Function GetListOfDays(ByVal yearNumber As Integer, _     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ByVal monthNumber As Integer) As List(Of Integer)      &lt;br /&gt;&amp;#160; Dim currentCalendar As Calendar = CultureInfo.CurrentCulture.Calendar      &lt;br /&gt;&amp;#160; Dim numberOfDays As Integer = _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; currentCalendar.GetDaysInMonth(yearNumber, monthNumber)      &lt;br /&gt;&amp;#160; Return Enumerable.Range(1, numberOfDays).ToList()      &lt;br /&gt;End Function&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;This function first defines the calendar based on the current culture. It then uses the calendar’s GetDaysInMonth method to get the appropriate number of days in the month.&lt;/p&gt;  &lt;p&gt;It then uses the Range method of Enumerable to build a list of numbers from 1 to the number of days in the month and returns it as a list of integers.&lt;/p&gt;  &lt;p&gt;This method is called as follows:&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;comboBox1.DataSource = GetListOfDays(2009, 2);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;ComboBox1.DataSource = GetListOfDays(2009, 2)&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1701370" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/WinForms/default.aspx">WinForms</category></item><item><title>Dates: Binding to Month Names</title><link>http://msmvps.com/blogs/deborahk/archive/2009/07/14/dates-binding-to-month-names.aspx</link><pubDate>Tue, 14 Jul 2009 20:14:38 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1701334</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1701334</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/07/14/dates-binding-to-month-names.aspx#comments</comments><description>&lt;p&gt;Visual Studio comes with DateTimePicker and MonthCalendar controls that provide a standard looking calendar for the user to pick a date. But there are times when these controls don’t provide the features you need.&lt;/p&gt;  &lt;p&gt;For example, say you want to ask the user for the month and year that their credit card expires. Or you want to ask for a birth date and don’t want the user to have to scroll back to 1932. Or better yet, don’t need to know the year (not that I refuse to admit my birth year &amp;lt;G&amp;gt;.)&lt;/p&gt;  &lt;p&gt;There is an easy way to achieve this. &lt;/p&gt;  &lt;p&gt;The code is first shown in both VB and C#. It is then described in detail below.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;string[] MonthNames=     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CultureInfo.CurrentCulture.DateTimeFormat.MonthNames;      &lt;br /&gt;comboBox1.DataSource = MonthNames;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim MonthNames As String() =&amp;#160; _     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CultureInfo.CurrentCulture.DateTimeFormat.MonthNames      &lt;br /&gt;ComboBox1.DataSource = MonthNames&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This code gets the month names based on the current culture. This ensures that you get the correct localized names. You can then bind the array to a ComboBox or ListBox.&lt;/p&gt;  &lt;p&gt;NOTE: In both cases, be sure to set a reference and import System.Globalization.&lt;/p&gt;  &lt;p&gt;When looking at the list from the US (and most countries), there is a problem. There appears to be room for 13 values in the list. This is for those countries that have 13 months, such as &lt;a href="http://en.wikipedia.org/wiki/Ethiopian_calendar" target="_blank"&gt;Ethiopia&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;So for most countries, there is a blank entry at the bottom of the list when it is bound. There are numerous ways of removing the empty entry. Even though it might not be the most performant, I like lambda expressions, so here is one way to remove the empty entry.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;comboBox1.DataSource =&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MonthNames.Where(m =&amp;gt; !string.IsNullOrEmpty(m)).ToList();&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;ComboBox1.DataSource = _     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MonthNames.Where(Function(m) Not String.IsNullOrEmpty(m)).ToList()&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1701334" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Lambda/default.aspx">Lambda</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/WinForms/default.aspx">WinForms</category></item><item><title>Enum: Binding to the Description Attribute</title><link>http://msmvps.com/blogs/deborahk/archive/2009/07/10/enum-binding-to-the-description-attribute.aspx</link><pubDate>Fri, 10 Jul 2009 23:31:04 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1699394</guid><dc:creator>Deborah Kurata</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/deborahk/rsscomments.aspx?PostID=1699394</wfw:commentRss><comments>http://msmvps.com/blogs/deborahk/archive/2009/07/10/enum-binding-to-the-description-attribute.aspx#comments</comments><description>&lt;p&gt;The Enum keyword allows you to define a standard set of named constants for use in your application. Sometimes you may want to present this same list of&amp;#160; values to your user. &lt;/p&gt;  &lt;p&gt;You can display the set of Enum values in a ComboBox or ListBox using data binding. And even better, if you use the DescriptionAttribute in the Enum, you can display a more user-friendly set of values.&lt;/p&gt;  &lt;p&gt;For example, a Customer business object may have a CustomerType defined with a specific set of options for corporations, individuals, schools, and charities. You want to use these values in your code, but also display them to the user in a ComboBox.&lt;/p&gt;  &lt;h2&gt;Enum Definition&lt;/h2&gt;  &lt;p&gt;The Enum can reside in the Customer class, or in its own class.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public enum CustomerTypeOption      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; NotDefined,&amp;#160; &lt;br /&gt;&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Corp,&amp;#160; &lt;br /&gt;&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; IndividualorFamily,&amp;#160; &lt;br /&gt;&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; SchoolorUniversity,&amp;#160; &lt;br /&gt;&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Charity      &lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Enum CustomerTypeOption      &lt;br /&gt;&amp;#160;&amp;#160; NotDefined       &lt;br /&gt;&amp;#160;&amp;#160; Corp       &lt;br /&gt;&amp;#160;&amp;#160; IndividualorFamily       &lt;br /&gt;&amp;#160;&amp;#160; SchoolorUniversity       &lt;br /&gt;&amp;#160;&amp;#160; Charity       &lt;br /&gt;End Enum&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;CustomerType Property&lt;/h2&gt;  &lt;p&gt;A CustomerType property in the Customer class can use this enum type.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;public CustomerTypeOption CustomerType { get; set; }&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Private _CustomerType As CustomerTypeOption      &lt;br /&gt;Public Property CustomerType() As CustomerTypeOption       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Return _CustomerType       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Get       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Set(ByVal value As CustomerTypeOption)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _CustomerType = value       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End Set       &lt;br /&gt;End Property&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;The C# code uses the automatically implemented properties feature introduced with .NET 3.5. The VB code uses the full property definition.&lt;/p&gt;  &lt;h2&gt;Binding To an Enum&lt;/h2&gt;  &lt;p&gt;The Enum can also be used by the user interface. For example, you can bind a comboBox or listBox to a set of customer type options.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dictionary&amp;lt;string, int&amp;gt; CustomerTypeList =      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new Dictionary&amp;lt;string, int&amp;gt;();       &lt;br /&gt;      &lt;br /&gt;foreach (int enumValue in       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Enum.GetValues(typeof(Customer.CustomerTypeOption)))       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CustomerTypeList.Add(       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;Enum.GetName(typeof(Customer.CustomerTypeOption),      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; enumValue ), enumValue);       &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Bind the customer type combo box      &lt;br /&gt;CustomerTypeComboBox.DisplayMember = &amp;quot;Key&amp;quot;;       &lt;br /&gt;CustomerTypeComboBox.ValueMember = &amp;quot;Value&amp;quot;;       &lt;br /&gt;CustomerTypeComboBox.DataSource = new BindingSource(CustomerTypeList,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; null);&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim CustomerTypeList As New Dictionary(Of String, Integer)      &lt;br /&gt;      &lt;br /&gt;For Each enumValue As Integer In _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Enum].GetValues(GetType(Customer.CustomerTypeOption))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CustomerTypeList.Add( _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Enum].GetName(GetType(Customer.CustomerTypeOption), _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; enumValue), enumValue)       &lt;br /&gt;Next &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Bind the combo box      &lt;br /&gt;CustomerTypeComboBox.DisplayMember = &amp;quot;Key&amp;quot;       &lt;br /&gt;CustomerTypeComboBox.ValueMember = &amp;quot;Value&amp;quot;       &lt;br /&gt;CustomerTypeComboBox.DataSource = New BindingSource(CustomerTypeList, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Nothing)&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;This code defines a Dictionary to contain the name of the enum and the integer value of the enum. The for/each loop iterates through the set of Enum values and adds the name and value to the dictionary.&lt;/p&gt;  &lt;p&gt;The code then binds to the ComboBox, setting the DisplayMember to the “Key” of the dictionary and the ValueMember to the “Value” of the Dictionary.&lt;/p&gt;  &lt;p&gt;The result looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/7853.image_5F00_2296F6DF.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/0511.image_5F00_thumb_5F00_6BBCA298.png" width="236" height="96" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;While it does provide the appropriate options, it is not very user-friendly. It would be nicer if there were appropriate spaces and full words. For that, you can use the DescriptionAttribute on the Enum.&lt;/p&gt;  &lt;h2&gt;Using the DescriptionAttribute&lt;/h2&gt;  &lt;p&gt;NOTE: Be sure to import the &lt;strong&gt;System.ComponentModel&lt;/strong&gt; and the &lt;strong&gt;System.Reflection&lt;/strong&gt; namespaces.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public enum CustomerTypeOption      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [DescriptionAttribute(&amp;quot;Not Specified&amp;quot;)]       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; NotDefined, &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; [DescriptionAttribute(&amp;quot;Corporation&amp;quot;)]      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Corp, &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; [DescriptionAttribute(&amp;quot;Individual or Family&amp;quot;)]      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; IndividualorFamily, &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; [DescriptionAttribute(&amp;quot;School or University&amp;quot;)]      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SchoolorUniversity, &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; [DescriptionAttribute(&amp;quot;Charity&amp;quot;)]      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Charity       &lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Public Enum CustomerType      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DescriptionAttribute(&amp;quot;Corporate Customer&amp;quot;)&amp;gt; _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CorpCustomer &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DescriptionAttribute(&amp;quot;Individual or Family&amp;quot;)&amp;gt; _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; IndividualorFamily &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DescriptionAttribute(&amp;quot;School or University&amp;quot;)&amp;gt; _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SchoolorUniversity &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DescriptionAttribute(&amp;quot;Charity&amp;quot;)&amp;gt; _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Charity &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DescriptionAttribute(&amp;quot;Kingdom&amp;quot;)&amp;gt; _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Kingdom       &lt;br /&gt;End Enum&lt;/font&gt; &lt;/p&gt;  &lt;h2&gt;Binding to an Enum Description&lt;/h2&gt;  &lt;p&gt;Now you can bind to the description instead of to the Enum constant.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;Dictionary&amp;lt;string, int&amp;gt; CustomerTypeList =      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new Dictionary&amp;lt;string, int&amp;gt;(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;FieldInfo fi;      &lt;br /&gt;DescriptionAttribute da;       &lt;br /&gt;foreach (Customer.CustomerTypeOption enumValue in       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Enum.GetValues(typeof(Customer.CustomerTypeOption)))       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; fi = typeof(Customer.CustomerTypeOption).       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GetField((enumValue.ToString()));       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; typeof(DescriptionAttribute));       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (da != null)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CustomerTypeList.Add(da.Description, (int)enumValue);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;// Bind the customer type combo box      &lt;br /&gt;CustomerTypeComboBox.DisplayMember = &amp;quot;Key&amp;quot;;       &lt;br /&gt;CustomerTypeComboBox.ValueMember = &amp;quot;Value&amp;quot;;       &lt;br /&gt;CustomerTypeComboBox.DataSource = new BindingSource(CustomerTypeList,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; null);&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim CustomerTypeList As New Dictionary(Of String, Integer)      &lt;br /&gt;      &lt;br /&gt;Dim fi As FieldInfo       &lt;br /&gt;Dim da As DescriptionAttribute       &lt;br /&gt;For Each enumValue As Customer.CustomerTypeOption In _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Enum].GetValues(GetType(Customer.CustomerTypeOption))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; fi = GetType(Customer.CustomerTypeOption). _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GetField(enumValue.ToString)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; da = DirectCast(Attribute.GetCustomAttribute(fi, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GetType(DescriptionAttribute)), DescriptionAttribute)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If da IsNot Nothing Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CustomerTypeList.Add(da.Description, enumValue)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If       &lt;br /&gt;Next &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Bind the combo box      &lt;br /&gt;CustomerTypeComboBox.DisplayMember = &amp;quot;Key&amp;quot;       &lt;br /&gt;CustomerTypeComboBox.ValueMember = &amp;quot;Value&amp;quot;       &lt;br /&gt;CustomerTypeComboBox.DataSource = New BindingSource(CustomerTypeList, _       &lt;br /&gt;&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Nothing) &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This code defines a Dictionary to contain the description of the enum and the integer value of the enum. The for/each loop iterates through the set of Enum values. It uses reflection to find the DescriptionAttribute. It then adds the description and value to the dictionary. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="ver"&gt;The code then binds to the ComboBox, setting the DisplayMember to the “Key” of the dictionary and the ValueMember to the “Value” of the Dictionary.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="ver"&gt;&lt;font color="#65402e"&gt;Now the combo&lt;/font&gt; box looks like this:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/3568.image_5F00_2B1A5629.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/deborahk.metablogapi/7360.image_5F00_thumb_5F00_1F8498EA.png" width="234" height="94" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Much better!&lt;/p&gt;  &lt;h2&gt;Extension Methods&lt;/h2&gt;  &lt;p&gt;So the user interface looks nicer, but the code to get the DescriptionAttribute looks rather tedious. It would be much nicer if there was a GetDescription method on the Enum. But hey, with the extension method feature introduced in .NET 3.5, we can build one ourselves!&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;public static string GetDescription(this Enum currentEnum)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; string description = String.Empty;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DescriptionAttribute da ; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; FieldInfo fi = currentEnum.GetType().      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GetField(currentEnum.ToString());       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;typeof(DescriptionAttribute));      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (da != null)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; description = da.Description;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; description = currentEnum.ToString(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; return description;      &lt;br /&gt;&lt;/font&gt;&lt;font color="#65402e" face="Consolas"&gt;}&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;lt;ExtensionAttribute()&amp;gt; _      &lt;br /&gt;Public Function GetDescription(ByVal currentEnum As [Enum]) As String       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim description As String = String.Empty       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dim da As DescriptionAttribute &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Dim fi As FieldInfo = currentEnum.GetType. _      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GetField(currentEnum.ToString)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; da = DirectCast(Attribute.GetCustomAttribute(fi, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GetType(DescriptionAttribute)), DescriptionAttribute)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; If da IsNot Nothing Then       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; description = da.Description       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Else       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; description = currentEnum.ToString       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; End If &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; Return description      &lt;br /&gt;End Function&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The C# code can reside in any static class. The VB code must reside in a module, which provides the same features as a static class.&lt;/p&gt;  &lt;p&gt;This code uses reflection to get the DescriptionAttribute for any Enum value. So it can be readily reused. The code returns the DescriptionAttribute if one is found, otherwise it returns the name.&lt;/p&gt;  &lt;h2&gt;Binding to an Enum Description - Redux&lt;/h2&gt;  &lt;p&gt;Now the binding code is much easier to work with.&lt;/p&gt;  &lt;p&gt;In C#:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dictionary&amp;lt;string, int&amp;gt; CustomerTypeList =      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new Dictionary&amp;lt;string, int&amp;gt;(); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;foreach (Customer.CustomerTypeOption enumValue in      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Enum.GetValues(typeof(Customer.CustomerTypeOption)))       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CustomerTypeList.Add(enumValue.GetDescription(), (int)enumValue);       &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;// Bind the customer type combo box      &lt;br /&gt;CustomerTypeComboBox.DisplayMember = &amp;quot;Key&amp;quot;;       &lt;br /&gt;CustomerTypeComboBox.ValueMember = &amp;quot;Value&amp;quot;;       &lt;br /&gt;CustomerTypeComboBox.DataSource = new BindingSource(CustomerTypeList,&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; null);&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;In VB:&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;Dim CustomerTypeList As New Dictionary(Of String, Integer)      &lt;br /&gt;      &lt;br /&gt;For Each enumValue As Customer.CustomerTypeOption In _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Enum].GetValues(GetType(Customer.CustomerTypeOption))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CustomerTypeList.Add(enumValue.GetDescription, enumValue)       &lt;br /&gt;Next &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#65402e" face="Consolas"&gt;&amp;#39; Bind the combo box      &lt;br /&gt;CustomerTypeComboBox.DisplayMember = &amp;quot;Key&amp;quot;       &lt;br /&gt;CustomerTypeComboBox.ValueMember = &amp;quot;Value&amp;quot;       &lt;br /&gt;CustomerTypeComboBox.DataSource = New BindingSource(CustomerTypeList, _       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Nothing)&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1699394" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/deborahk/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Enum/default.aspx">Enum</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Binding/default.aspx">Binding</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/Extension+Method/default.aspx">Extension Method</category><category domain="http://msmvps.com/blogs/deborahk/archive/tags/WinForms/default.aspx">WinForms</category></item></channel></rss>