tag:blogger.com,1999:blog-51322101022530961662024-03-13T04:33:22.381-06:00VBRocks' BlogVB.NET, ASP.NET, VB6, VBA, C# and SQLVBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-5132210102253096166.post-41634320792021782552010-04-09T19:05:00.001-06:002010-04-09T19:05:52.159-06:00How to loop through all controls on a form<p>There are times when a developer needs to loop through all of the controls on the form.  Initially, a recursive method comes to mind, however, with VB.NET, it’s really a lot easier than you think. <br /> <br />In a regular Windows Forms Application, where “Me” represents the form, use the following snippet of code to loop through all controls on the form, even controls nested in various layers of panels, group boxes, etc.: <br /> </p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:177a901c-8e6a-4fa2-827a-b24cc04d07bc" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">Dim</span> ctl <span style="color:#0000ff">As</span> Control = <span style="color:#0000ff">Me</span><br> <br> <span style="color:#0000ff">Do</span><br> ctl = <span style="color:#0000ff">Me</span>.GetNextControl(ctl, <span style="color:#0000ff">True</span>)<br> <br> <span style="color:#0000ff">If</span> ctl <span style="color:#0000ff">IsNot</span> <span style="color:#0000ff">Nothing</span> <span style="color:#0000ff">Then</span> _<br> MessageBox.Show(ctl.Name)<br> <br> <span style="color:#0000ff">Loop</span> <span style="color:#0000ff">Until</span> ctl <span style="color:#0000ff">Is</span> <span style="color:#0000ff">Nothing</span></div> </div> </div> <p> <br /> <br /></p> <p></p> <p>If you are looking for a control of a particular type, then just check for that type, and then perform your desired actions: <br /> <br /></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:337e1d43-14ac-4756-b3be-cbb317ab9e07" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">Dim</span> ctl <span style="color:#0000ff">As</span> Control = <span style="color:#0000ff">Me</span><br> <br> <span style="color:#0000ff">Do</span><br> ctl = <span style="color:#0000ff">Me</span>.GetNextControl(ctl, <span style="color:#0000ff">True</span>)<br> <br> <span style="color:#0000ff">If</span> ctl <span style="color:#0000ff">IsNot</span> <span style="color:#0000ff">Nothing</span> <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">' Search for a TextBox</span><br> <span style="color:#0000ff">If</span> <span style="color:#0000ff">TypeOf</span> ctl <span style="color:#0000ff">Is</span> TextBox <span style="color:#0000ff">Then</span> _<br> MessageBox.Show(ctl.Name)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If</span><br> <br> <br> <span style="color:#0000ff">Loop</span> <span style="color:#0000ff">Until</span> ctl <span style="color:#0000ff">Is</span> <span style="color:#0000ff">Nothing</span></div> </div> </div> <p></p> <p> <br /> <br />And that’s all there is to it!</p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-39364824990475351342010-02-12T23:42:00.001-07:002010-02-14T00:04:31.094-07:00What I Love About Paola<p><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/S3egfOSZloI/AAAAAAAAAVM/2XyDVnJluLk/s1600-h/Paola2%5B1%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; margin: 5px 5px 5px 0px; width: 232px; display: inline; border-top: 0px; border-right: 0px" title="Paola2" border="0" alt="Paola2" align="left" src="http://lh4.ggpht.com/_dhkDWtu14Jc/S3ZJ5igj25I/AAAAAAAAAVQ/tfVyCSQumWE/Paola2_thumb.jpg?imgmax=800" width="232" height="185" /></a> </p> <p></p> <blockquote> <p>Paola is absolutely the most wonderful woman in the world. <br /> <br />Although many may contend they have found others more grandeur, I will not be persuaded that there is one more resplendent than the one who single handedly captured my heart. <br /> <br />Of Peruvian descent, Paola bears the image of Incan royalty in her graces.  Her dignity is manifested in her actions.  Her honor is recherché among many. <br /> <br />From the high mountains of Machu Picchu to the floor of the Sacred Valley, follow the venerable Vilcanota River, search among the daughters of men, if you can, and find one like unto Paola. <br /> <br />Paola is beautiful, because she is beautiful.  She is one of the most warm, loving, kind, considerate, friendly, cheerful, thoughtful, faithful, loyal, reliable, trustworthy, responsible women I know. <br /> <br />Her oldest son is now a man.  Serving in the United States Army, he is a humble soldier to be proud of; one who has laid down his life to defend the blessed freedom, and the flag of America.  Standing tall, he reflects the sacrifices and disciplines of his mother; Standing firm, he reflects her reliability and steadfastness.  He continues to carry the banner of our nation with the strength imparted by his mother. <br /> <br />Two children remain yet under her wing:  The oldest of which is a bright and beautiful boy, who is gentle, polite and well mannered. He is such a pleasure to have around.  He is intelligent, curious and quick, and exuberates his mother’s charm.  The youngest is beautiful as well: assertive, energetic, fun and very outgoing. <br /> <br />Paola is one of the most loving mothers.  She has done, and continues to do a fantastic job with her children.  She works so hard to provide for them, and makes sure that they have everything they need.  Even though she works, she is up early to dress them, and to prepare them for their day.  She works so hard to make sure they get to school, and to all of their appointments on time.  She calls to follow up on them, and many times just to hear their voice.  After her work is over, she cooks a wonderful healthy dinner for them, ensures they do their homework, and spends time with them before kissing them and sending them to bed. <br /> <br />She is also a very good housekeeper.  She is very diligent at keeping her house neat and tidy, and presentable, but not in an innocuous way.  I appreciate how much effort she puts into her home. <br /> <br />One of the things I love most about her is her personality.  She has an excellent personality!  It is so enjoyable to be around her, and watch her laugh and play with her friends.  She can be giddy at times, funny, very cute, and witty.  She is so friendly, she can be friends with almost anyone. <br /> <br />I also love her intimacy.  She is a very soft and loving person.  She is very gentle, and submissive.  It is such a pleasure to be close to someone who loves you, and is real.  She is a very real, beautiful woman in every way! <br /> <br />Paola is also a Christian.  This is something that I really appreciate.  Some of the best times I’ve had with her have been when we read the bible and prayed together. <br /> <br />Last, but not least, Paola is a very beautiful woman.  She is very attractive.  I love her long, naturally curly black hair!  She can wash her hair, dry it with a towel, then let it hang down the sides of her beautiful face, and all so lovely.  Her eyes are so beautiful!  They are a beautiful brown, warm, and full of tenderness.  It is easy to become captivated by her eyes.  Additionally, her complexion is tan and very smooth.  Her nose is perfect, and cute.  Her lips are perfect as well.  Her face is round, and alluring, wonderful to touch. <br /> <br />Paola is the most wonderful woman in the world. <br /> <br />I will love you forever! </p></blockquote> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-67889836099926649162009-10-05T08:46:00.000-06:002009-10-09T08:47:55.770-06:00Silverlight 3: Slideshow<p>Wow!  I am so excited about sharing this Slideshow with you!  Not because it’s the greatest in the world, but because it’s <em>(not only)</em> my first Silverlight Slideshow that I’ve created, but it’s also my first Silverlight user control that I’ve created! <br />  <br /><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/SsuScfmSPGI/AAAAAAAAAUk/dInGOddC9L4/s1600-h/SlideShowPicture7.jpg"><img style="border-right-width: 0px; width: 306px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="SlideShowPicture" border="0" alt="SlideShowPicture" src="http://lh5.ggpht.com/_dhkDWtu14Jc/SsuSc-HKpSI/AAAAAAAAAUo/GnRgyE2tmeM/SlideShowPicture_thumb5.jpg?imgmax=800" width="306" height="198" /></a>  <br />  <br />Before I begin, let me show you a couple of great Silverlight Slideshows that I found: <br /> <br />Mike Swanson’s Blog:</p> <p><a href="http://blogs.msdn.com/mswanson/archive/2007/12/18/silverlight-slide-show.aspx" target="_blank">http://blogs.msdn.com/mswanson/archive/2007/12/18/silverlight-slide-show.aspx</a> <br /> <br /></p> <p>Andrew Arnott’s Blog: <br /><a href="http://blogs.msdn.com/andrewarnottms/archive/2008/01/01/an-impressive-silverlight-slideshow-control.aspx" target="_blank">http://blogs.msdn.com/andrewarnottms/archive/2008/01/01/an-impressive-silverlight-slideshow-control.aspx</a> <br /> <br /> <br />Koen Zwikstra’s Blog: <br /><a href="http://firstfloorsoftware.com/slideshow/silverlight-slideshow/" target="_blank">http://firstfloorsoftware.com/slideshow/silverlight-slideshow/</a> <br /> <br /> <br />Now, I actually tried using these slideshows before I ever decided to create my own, because they are beautiful slideshows!  The only problem with them is that they have to be embedded directly in an ASP.NET webpage.  Which means, they cannot be embedded in a Silverlight UserControl (.xaml).  That’s frustrating!  Especially if you, like me, have an entire Silverlight 3 website, and need the slideshow to be able to work in a Silverlight UserControl. <br />  <br /><strong> </strong></p> <h4><strong>Download the Source Code</strong></h4> <p> </p> <p><strong></strong></p> <p>Download either the Slideshow Class Library Project, which you can add directly to your solution; or the Complete Demo Solution, which includes the SlideShowTest Silverlight website created in this demo, and the Slideshow Class Library Project.  <br />  </p> <p>Slideshow Class Library Project:   <a href="http://www.visualbasicrocks.com/SlideShow.zip">SlideShow.zip</a> <br /> </p> <p>Complete Demo Solution:   <a href="http://www.visualbasicrocks.com/SlideShowTest.zip">SlideShowTest.zip</a></p> <p> <br /> </p> <h4><strong>Creating a Silverlight Website</strong></h4>           <br />The first thing we’ll do is create a Silverlight website that we can use to test our Slideshow in.  So, Fire up Visual Studio 2008… <br /> <br />-  Click on the File menu | New | Project… <p> </p> <p>When the “New Project” window opens, perform the following actions: <br />  <br />-  In the Project Type TreeView, Expand the Visual Basic node, then click on the Silverlight node.</p> <p> </p> <p>-  Select the Silverlight Application from the Template ListView. <br /> <br />-  Make sure you have the “.NET Framework 3.5” selected. <br /> <br />-  Name the project “SlideShowTest” <br />  <br />-  Click the OK button when you’re ready . <br />  <br />  <br />Here’s what mine looks like: <br />  <br /></p> <p><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/SsuUIm-PdLI/AAAAAAAAAUs/vGtMDFRyTvQ/s1600-h/NewProject5.jpg"><img style="border-right-width: 0px; width: 439px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="NewProject" border="0" alt="NewProject" src="http://lh4.ggpht.com/_dhkDWtu14Jc/SsuUJMKwAsI/AAAAAAAAAUw/dNkcIs5iS94/NewProject_thumb3.jpg?imgmax=800" width="439" height="355" /></a>   <br />  <br />After you click the “OK” button the following “New Silverlight Application” window will open.  Just click the “OK” button to accept the default settings, and create the solution. <br />  <br />  <br /><strong>Download the Source Code <br /></strong>If you haven’t done it already, download the “SlideShow Class Library” source code to your computer.  The source code is in a .zip file, so open the .zip file and extract the SlideShow Project into the “SlideShowTest” solution folder. <br /> <br /> <br /><strong>Adding the Project</strong> <br />After you have downloaded the source code, and extracted it into the solution folder, add it as a reference to your project:  <br />  <br />-  Click on the File menu | Add | Existing Project… <br /> <br />-  When the “Add Existing Project” window opens, browse to the “SlideShowTest” solution folder, then to the “SlideShow” folder, and select  “SlideShow.vbproj”. <br />  <br />  <br />If you’re added the project successfully, then the Solution Explorer should now look like this:  <br />  <br /><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/SsuUJs7FSFI/AAAAAAAAAU0/UAb4aXKfusQ/s1600-h/SlideShowAdded4.jpg"><img style="border-right-width: 0px; width: 270px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="SlideShowAdded" border="0" alt="SlideShowAdded" src="http://lh5.ggpht.com/_dhkDWtu14Jc/SsuUJ6Kis3I/AAAAAAAAAU4/qXxL7Tu3I5w/SlideShowAdded_thumb2.jpg?imgmax=800" width="270" height="204" /></a>   <br />  <br />After you have added the project, you need to add a reference to it: <br /> <br />-  In Solution Explorer, Right-Click on the “SlideShowTest” project node, then select “Add Reference…” from the popup menu. <br />  <br />-  When the “Add Reference” window opens, click the “Projects” tab, then select “SlideShow”, and click the “OK” button. <br /> <br /> <br /><strong>Add Your Images</strong> <br />Next, right-click on the “images” folder, in the SlideShow project, and select Add | Existing Item…  and then add all of the images you want to view in your slideshow.  <br /> <br /><em>Just as a note, you don’t have to add images if you don’t want to.  If you have the url’s to images on the web, and would like to view them in your slideshow, then you can use those url’s, instead of local images. <br /> <br /></em>I’ve added several images to mine, as you can see: <br />  <br /><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/SsuUKUO8PkI/AAAAAAAAAU8/6YH2xmo0XkM/s1600-h/images20.jpg"><img style="border-right-width: 0px; width: 270px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="images" border="0" alt="images" src="http://lh5.ggpht.com/_dhkDWtu14Jc/SsuUK8GyqWI/AAAAAAAAAVA/Ejh5NHP1los/images_thumb16.jpg?imgmax=800" width="270" height="528" /></a>     <br /> <br />After you add your images, right-click on the SlideShowControl and select View Code.  In the AddImages() method, then add the url’s to your images as follows:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:48f44eac-fe33-4507-9a6b-38890fe911d6" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Add the url's of your images here.</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' This is the only sub that you need to update.</span><br> <span style="color:#008000">'</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> AddImages()<br> <br> <span style="color:#008000">'Add the images to be displayed here.</span><br> ImageList.Add(<span style="color:#a31515">"images/Blue hills.jpg"</span>)<br> ImageList.Add(<span style="color:#a31515">"images/Sunset.jpg"</span>)<br> ImageList.Add(<span style="color:#a31515">"images/Water lilies.jpg"</span>)<br> ImageList.Add(<span style="color:#a31515">"images/Winter.jpg"</span>)<br> <br> <span style="color:#008000">'You can also add url's to images on the web</span><br> ImageList.Add(<span style="color:#a31515">"http://tiny.cc/NX6Kv"</span>)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span> <span style="color:#008000">'AddImages</span>
</p>
</div>
</div>
</div> <p>  <br />  <br /><strong>Adding the ContentGrid <br /></strong>Once you have your images in place, you are ready to add a grid to the MainPage.xaml user control, in the SlideShowTest project, for hosting the Slideshow.  So, double-click on the MainPage.xaml user control to open the design view.  Then, drag a “Grid” from the ToolBox onto the xaml designer, and name it “ContentGrid”, as follows: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:edcdbebc-14ac-4228-bdf6-dac07820f073" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">Grid</span><span style="color:#ff0000"> x</span><span style="color:#0000ff">:</span><span style="color:#ff0000">Name</span><span style="color:#0000ff">="LayoutRoot"></span><br> <br> <span style="color:#0000ff"></span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid</span><span style="color:#ff0000"> x</span><span style="color:#0000ff">:</span><span style="color:#ff0000">Name</span><span style="color:#0000ff">="ContentGrid"></span><br> <span style="color:#0000ff"> </span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"> </span><span style="color:#a31515"></span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p>  <br />Save and Build your project. <br /> <br /> <br /><strong>Wiring it up <br /></strong>After you’ve added the ContentGrid, you are ready to wire up the SlideShowControl.  So, right-click on the xaml designer, and select “View Code” to open the code window. <br /> <br />Then, in the New() constructor method, create a new instance of the SlideShowControl, and add it to the SlideShowControl to the ContentGrid.Children collection. <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6e653683-95b1-4ab8-9584-1d9ac5078601" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Partial</span> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> MainPage<br> <span style="color:#0000ff">Inherits</span> UserControl<br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> <span style="color:#0000ff">New</span>()<br> <br> InitializeComponent()<br> <br> <span style="color:#0000ff">Dim</span> ssc <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> SlideShow.SlideShowControl()<br> <span style="color:#0000ff">Me</span>.ContentGrid.Children.Add(ssc)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> <br /> <br /><strong>Running the project</strong></p> <p>And that is all there is to it!  Save your project, then run it (F5), and view the slideshow… <br /> <br /> <br /><strong>Conclusion <br /></strong>I really hope you find this slideshow as useful as I did.  The code is easy to modify, so if you want to go in and tweak it, have at it.</p> <p> </p> <p>Happy programming!</p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-50507493713963967852009-10-02T08:16:00.000-06:002009-10-02T10:09:04.931-06:00Silverlight 3: Using a Timer<p>While working on a Silverlight 3 website, I found I had a need for a Timer.  After looking through the 60+ controls that are part of the Silverlight Toolkit, I realized there wasn’t one there.  Fortunately, I didn’t have to get discouraged, because there is a nice timer that can be accessed and used in the System.Windows.Threading namespace, called the “DispatcherTimer”. <br /> <br />You can use the timer in a Silverlight UserControl by declaring it at the member level, at the top of your class as follows.  Use the “WithEvents” keyword to enable it’s selection from the Class Name dropdown list: </p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:12274ac5-2e82-4ffb-a046-d110aab36eed" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Partial</span> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> MyUserControl<br> <span style="color:#0000ff">Inherits</span> UserControl<br> <br> <span style="color:#008000">'Declare the timer at the member level using</span><br> <span style="color:#008000">' the WithEvents keyword</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">WithEvents</span> mTimer <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> System.Windows.Threading.DispatcherTimer()<br> <br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> <span style="color:#0000ff">New</span>()<br> InitializeComponent()<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p>  <br />  <br />After declaring the timer, select if from the Class Name dropdown list at the top of the code window, and then select the “Tick” method from the Method Name dropdown list, as follows: </p> <p>  </p> <p><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/SsYlnohQLLI/AAAAAAAAAUc/6Lhx-T7Wx2I/s1600-h/ClassName%5B11%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; width: 432px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="ClassName" border="0" alt="ClassName" src="http://lh3.ggpht.com/_dhkDWtu14Jc/SsYloKoYsYI/AAAAAAAAAUg/e-Z6EEGUO-M/ClassName_thumb%5B8%5D.jpg?imgmax=800" width="432" height="107" /></a>  <br />  <br />When you select the “Tick” method from the Method Name dropdown list, the mTimer_Tick event will be automatically created.  This is the event that gets fired at the specified intervals: </p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b6b0d1fa-9a3c-4036-9e89-fd630e70740b" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mTimer_Tick( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> mTimer.Tick<br> <br> <span style="color:#008000">'Insert the code here that will be executed</span><br> <span style="color:#008000">' at the specified interval.</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p>  <br />  <br /></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p>The final thing to do is set the timer’s Interval, and then call the Start method.  This can be perform in whatever method you prefer, I will use the constructor:  <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4a05ae43-af76-4493-81a7-4a577aaa7f26" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> <span style="color:#0000ff">New</span>()<br> InitializeComponent()<br> <br> <span style="color:#008000">'Initialize timer for 5 seconds</span><br> mTimer.Interval = <span style="color:#0000ff">New</span> TimeSpan(0, 0, 5)<br> <br> <span style="color:#008000">'Start the timer</span><br> mTimer.Start()<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p>  <br />  <br />The complete class looks like the following:  <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d5c77af4-a7de-4162-9d61-f5f43387535f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Partial</span> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> MyUserControl<br> <span style="color:#0000ff">Inherits</span> UserControl<br> <br> <span style="color:#008000">'Declare the timer at the member level using</span><br> <span style="color:#008000">' the WithEvents keyword</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">WithEvents</span> mTimer <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> System.Windows.Threading.DispatcherTimer()<br> <br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> <span style="color:#0000ff">New</span>()<br> InitializeComponent()<br> <br> <span style="color:#008000">'Initialize timer for 5 seconds</span><br> mTimer.Interval = <span style="color:#0000ff">New</span> TimeSpan(0, 0, 5)<br> <br> <span style="color:#008000">'Start the timer</span><br> mTimer.Start()<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mTimer_Tick( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> mTimer.Tick<br> <br> <span style="color:#008000">'Insert the code here that will be executed</span><br> <span style="color:#008000">' at the specified interval.</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p>  <br />  <br />And that’s all there is to it!  I used the timer to change the pictures in a Silverlight SlideShow, and it works great!  Hopefully you’ll find some creative uses for it as well. </p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-81807882509470764412009-09-09T07:00:00.000-06:002009-09-14T16:04:13.374-06:00Silverlight 3: Displaying SQL Server data<blockquote> <p>Silverlight 3 is by far, the coolest technology for web programming!  I’m so excited about Silverlight 3!  I hope I can share some things with you here that will help you get up and running with Silverlight 3 and SQL Server Databases. <br /> <br />This article walks you through displaying data from an SQL Server Database in a Silverlight 3 application. <br /> <br />There are three technologies that will be used in this example, which are:  SQL Server, Windows Communication Foundation (WCF), and Silverlight 3, which runs in Visual Studio 2008. <br />  <br />  <br /></p> <h4>Preview…</h4> <p>This article is going to retrieve the top 1000 rows from the Person.Contact table in the AdventureWorks SQL Server database, and display them in a Silverlight DataGrid.</p> <p> </p> <p>Here’s a preview of what things are going to look like when we finish this article: <br /> <br /><a href="http://lh4.ggpht.com/_dhkDWtu14Jc/Sq69n-sKyuI/AAAAAAAAARw/YBWTYqiBFQQ/s1600-h/demo6.jpg"><img style="border-right-width: 0px; width: 439px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="demo" border="0" alt="demo" src="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq69ocfnNtI/AAAAAAAAAR0/AEzWxF4N65w/demo_thumb4.jpg?imgmax=800" width="439" height="303" /></a>  <br />  <br /></p> <h4>Setting Things Up…</h4> <p>Before we get started, let’s make sure we get the following things setup: <br />  <br /></p> <p><strong>SQL Server</strong> <br />First, you have to have SQL Server or SQL Express setup on your computer.  Since you’ve already started reading this article, I’m guessing you do.  However, if you do not, then follow this link for instructions on downloading and installing SQL Express: <br /> <br /><a href="http://www.microsoft.com/Sqlserver/2005/en/us/express.aspx" target="_blank">http://www.microsoft.com/Sqlserver/2005/en/us/express.aspx</a> <br />  <br /> <br /><strong>AdventureWorks Database</strong> <br />Next, you have to download the AdventureWorks database and get it setup with SQL Server.  For instructions on how to do that, follow this link: <br /> <br /><a title="http://msdn.microsoft.com/en-us/library/aa992075(VS.80).aspx" href="http://msdn.microsoft.com/en-us/library/aa992075(VS.80).aspx">http://msdn.microsoft.com/en-us/library/aa992075(VS.80).aspx</a> <br /> <br /> <br /><strong>Silverlight 3</strong> <br />Additionally, you have to have Silverlight 3 installed.  Silverlight 3 runs inside of Visual Studio 2008.  To install Silverlight 3, please visit the following link: <br /> <br /><a href="http://silverlight.net/getstarted/silverlight3/default.aspx" target="_blank">http://silverlight.net/getstarted/silverlight3/default.aspx</a> <br /> <br /> <br /></p> <h4>Creating the Project…</h4> To begin, fire up Visual Studio 2008 and create a new Project (File menu | New | Project…) <br /> <br />In the Project Types treeview on the left, under the Visual Basic node, click the Silverlight node, then select the Silverlight Application template on the right.  Name the project “AdventureWorks”.  Make sure the .NET Framework 3.5 is selected.  Click OK when you’re finished. <br /> <br />Here’s what mine looks like: <br /> <br /></blockquote> <a href="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq69ow8lo1I/AAAAAAAAAR4/WwKWZQ_v1R4/s1600-h/newProject8.jpg"><img style="border-right-width: 0px; width: 438px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="newProject" border="0" alt="newProject" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69qVbuCdI/AAAAAAAAAR8/_fXQBfaAMwM/newProject_thumb6.jpg?imgmax=800" width="438" height="374" /></a>  <br /> <br />After you click the OK button, the New Silverlight Application window should open.  Here we will be prompted to select whether we want to create a new ASP.NET Web Site project, or a ASP.NET Web Application Project, which is used to host the Silverlight Application within.  We will leave the ASP.NET Web Application Project selected, but change the New Web Project Name from “AdventureWorks.Web” to “AdventureWorks_WebServer”, to make it a little more clear.  Click the OK button when you’re done. <br /> <br />Here’s what mine looks like: <br /> <br /><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69q0sY7AI/AAAAAAAAASA/w806IAD9CJQ/s1600-h/newSilverlightApp18.jpg"><img style="border-right-width: 0px; width: 438px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="newSilverlightApp1" border="0" alt="newSilverlightApp1" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69rPg31WI/AAAAAAAAASE/NQr2MHrA88Q/newSilverlightApp1_thumb6.jpg?imgmax=800" width="438" height="349" /></a> <br /> <br /> <br />  <br /> <p></p> <p></p> <p></p> <p></p> <p> <br />After we click the OK button, Visual Studio will create a Solution for us containing both the “AdventureWorks_WebServer” ASP.NET web server application in it, which will serve as a test environment for the “AdventureWorks” Silverlight client application, which was also created. <br /> <br />A look at Solution Explorer will reveal the following: <br /> <br /></p> <blockquote> <p><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq69rutOvHI/AAAAAAAAASI/Liy4OueC5eE/s1600-h/solutionExplorer15.jpg"><img style="border-right-width: 0px; width: 374px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="solutionExplorer1" border="0" alt="solutionExplorer1" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69rxagR4I/AAAAAAAAASM/EgdtPuW6Kss/solutionExplorer1_thumb3.jpg?imgmax=800" width="374" height="327" /></a>  <br /> <br />In the AdventureWorks Silverlight client application, there are 2 .xaml files: an App.xaml file, which is used to declare resources; and the MainPage.xaml file, which is the default user control that loads when the application starts.  The MainPage.xaml file is the file we will use later to design our interface. <br /> <br />In the AdventureWorks_WebServer application, any of the following 4 files can be used to host the Silverlight application: <br /> <br />     -  AdventureWorksTestPage.aspx <br />     -  AdventureWorksTestPage.html</p> </blockquote> <p>     -  Default.aspx</p> <p>     -  Silverlight.js <br /> <br />The AdventureWorksTestPage.aspx file is the default startup page that will load when the application runs, and will host the MainPage.xaml user control. <br /> <br /><em>The AdventureWorksTestPage.html file, the Default.aspx file, and the Silverlight.js file can all be deleted from this example, because they will not be used.</em> <br /> <br />The Web.config file is used to store configuration information for the web server.  We will learn more about this in a bit. <br />  <br />  <br /></p> <h4>Creating the AdventureWorks Connection…</h4> <p>If you already have SQL Server installed, and the AdventureWorks database attached, then you are ready to move forward with creating the connection. <br /> <br />In Visual Studio, click on the Tools menu | Connect to Database…  The Add Connection window will open, and be ready for configuration.  Make sure the Data Source is set to Microsoft SQL Server (SqlClient).  Set the Server name to either “localhost”, if you attached the database to SQL Server, or “localhost\SQLExpress”, if you attached the database to SQL Express (If you changed the instance name from something other than the default, than be sure you specify that, instead of “SQLExpress”).  Finally, select the “AdventureWorks” database.  Click the OK button when you’re finished. <br /> <br />Here’s what mine looks like: <br /> <br /><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sq69sbHJpwI/AAAAAAAAASQ/8Mw9_DTxMa0/s1600-h/connection8.jpg"><img style="border-right-width: 0px; width: 371px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="connection" border="0" alt="connection" src="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq69s049IeI/AAAAAAAAASU/U4DngcrIaUI/connection_thumb6.jpg?imgmax=800" width="371" height="516" /></a>  <br />Now that we have the connection created, we’ll create a LINQ to SQL Class, and configure it to use the AdventureWorks database. <br /></p> <p>  <br /> </p> <h4>Adding LINQ to SQL Classes…</h4> <p>Since we’ve just created the connection to the SQL Server AdventureWorks database in ServerExplorer, we’ll add a LINQ to SQL Class to our application that will be used to store the connection information, and retrieve the data from the Person.Contact table. <br /> <br />To perform this step, right-click on the AdventureWorks_WebServer project, then select Add | New Item…  When the Add New Item window opens, click on the Data node, then select the LINQ to SQL Classes Template from the right.  Leave the name as “DataClasses1.dmbl”, then click the Add button. <br /> <br />Here’s an example: <br /> <br /><a href="http://lh4.ggpht.com/_dhkDWtu14Jc/Sq69tLvttlI/AAAAAAAAASY/wvm2vzuWjcY/s1600-h/linq2sql6.jpg"><img style="border-right-width: 0px; width: 428px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="linq2sql" border="0" alt="linq2sql" src="http://lh4.ggpht.com/_dhkDWtu14Jc/Sq69tvRr0ZI/AAAAAAAAASc/xf2NJ_5_DZg/linq2sql_thumb4.jpg?imgmax=800" width="428" height="344" /></a> <br /> <br />After you click the Add button, the “DataClasses1.dbml” file will be added to the AdventureWorks_WebServer project, and will be visible in Solution Explorer.  If it did not open up automatically for you, then double-click on it to open the designer. <br /> <br />Next, make sure the Server Explorer is open (View menu | Server Explorer).  Then, expand the AdventureWorks database node, and expand the Tables node.  Find the “Contact (Person)” table, left-click on it, then drag it from the Server Explorer, to the DataClasses1.dbml designer, as follows: <br /> <br /><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq69uSMnzCI/AAAAAAAAASg/UDFGIJg5rDA/s1600-h/contacttable8.jpg"><img style="border-right-width: 0px; width: 437px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="contacttable" border="0" alt="contacttable" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69u4nQGGI/AAAAAAAAASk/9RrXz-ImyRs/contacttable_thumb6.jpg?imgmax=800" width="437" height="356" /></a> <br />After successfully adding the Contact table to the DataClasses1.dbml, save the project (File menu | Save All).  Then, close the DataClasses1.dbml designer, because we are finished with it. <br />  <br />  <br /></p> <h4>Adding the ContactRecord class…</h4> <p>Just by looking at the Contact table above, you can tell there is a lot of information!  There are a lot of columns, such as:  ContactID, NameStyle, Title, etc. Since we only want the FirstName, LastName and EmailAddress columns, we will make a custom ContactRecord class to represent each contact row from the table, instead of using the exposed Contact type. <br /> <br /><em>As a note, one of the first things I wondered was, Why not just use ADO.NET?  DataSets and DataTables are much easier to work with!  While this is true, WCF was designed to follow the SOA principles, which means we need to program against contracts, not implementation. Since DataSets and DataTables are .NET specific types, we cannot use them.  Although they can be used within the WCF service, they cannot be passed to Silverlight.</em> <br /> <br />To create the ContactRecord class, right-click on the AdventureWorks_WebServer project node in Solution Explorer, select Add | Class…  Name it “ContactRecord.vb”, then click the Add button. <br /> <br />After the class has been added, add 3 public members to it:  FirstName, LastName and Email.  Our class should now look like this:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ffb9ded1-a627-48fc-8f49-fd943f6fdb86" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> ContactRecord<br> <br> <span style="color:#0000ff">Public</span> FirstName <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span><br> <span style="color:#0000ff">Public</span> LastName <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span><br> <span style="color:#0000ff">Public</span> Email <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> <br />Save the project (File menu | Save All).  Next, we’ll look at adding a WCF service. <br />  <br />  <br /></p> <h4>Adding WCF…</h4> <p>Now that we have the LINQ to SQL Class set up, and our ContactRecord class created, we are ready to add a Windows Communication Foundation class to our AdventureWorks_WebServer project.  This class will act as a service, which will use the LINQ to SQL Class to retrieve the data from the AdventureWorks database, and return it to the Silverlight client application. <br /> <br />In Solution Explorer, right-click on the AdventureWorks_WebServer project node, and select Add | New Item…  Click on the Silverlight node, then select the Silverlight-enabled WCF Service template.  Leave it named “Service1.svc”, and click the Add button.  <br /> <br />Here’s what mine looks like: <br /> <br /></p> <img style="border-right-width: 0px; width: 434px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="addWcf" border="0" alt="addWcf" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69vKObuzI/AAAAAAAAASo/RSbWiwfWbvY/addWcf_thumb4.jpg?imgmax=800" width="434" height="360" /> <blockquote> <p></p> <br />After the WCF service has been added, you’ll find a “Service1.svc” file added to the AdventureWorks_WebServer project node in Solution Explorer.  If it did not automatically open, then double-click it to open the code window. <br /> <br />The code window should now look like this: <br />  <br /></blockquote> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e7f39256-2cba-45cc-951f-986d0990fe07" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Imports</span> System.ServiceModel<br> <span style="color:#0000ff">Imports</span> System.ServiceModel.Activation<br> <br> <ServiceContract(Namespace:=<span style="color:#a31515">""</span>)> _<br> <AspNetCompatibilityRequirements( _<br> RequirementsMode:= _<br> AspNetCompatibilityRequirementsMode.Allowed)> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Service1<br> <br> <OperationContract()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> DoWork()<br> <span style="color:#008000">' Add your operation implementation here</span><br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <span style="color:#008000">' Add more operations here and mark them </span><br> <span style="color:#008000">' with <OperationContract()></span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> <br />A couple of things we will do to this service: <br /> <br />     -  Add a Namespace to the ServiceContract.  This will make sure our <br />        custom types are unique. <br /> <br />        <em>As a note, a Namespace should be a uri, but does not actually have to  <br />        point to a real location on the web.  It is only used as a unique identifier <br />        for the custom type.</em> <br /> <br />     -  Delete all of the code and comments within the class. <br /> <br /> <br /><strong>Add the GetContacts Function</strong> <br />Now we are ready to add our own GetContacts() Function, which will be called from the Silverlight client application.  When adding this function, declare the return type to be List(Of ContactRecord), and be sure to add the <OperationContract()> attribute just above the function name.  This allows this function to be accessible to the Silverlight client.</p> <p> </p> <p>After adding the namespace and the GetContactions() Function, the code window should look like this: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d1059336-b152-46f1-833c-aabcc7167c62" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Imports</span> System.ServiceModel<br> <span style="color:#0000ff">Imports</span> System.ServiceModel.Activation<br> <br> <ServiceContract( _<br> Namespace:=<span style="color:#a31515">"http://adventureworks.com"</span>)> _<br> <AspNetCompatibilityRequirements( _<br> RequirementsMode:= _<br> AspNetCompatibilityRequirementsMode.Allowed)> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Service1<br> <br> <OperationContract()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> GetContacts() _<br> <span style="color:#0000ff">As</span> List(<span style="color:#0000ff">Of</span> ContactRecord)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> <br /> <br /><strong>Add the Code to the GetContacts Function</strong> <br />Within the GetContacts() Function, we can use the “DataClasses1.dbml” LINQ to SQL Class that we added, and of course, LINQ, to access the to data in the Contact table of the AdventureWorks database.  Add the first 1000 rows to a list, and return it.  <br /> <br />Here’s what our Function looks like: <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3e5e8687-6ef0-4dd1-8200-8c01e5aaf5d0" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <OperationContract()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> GetContacts() _<br> <span style="color:#0000ff">As</span> List(<span style="color:#0000ff">Of</span> ContactRecord)<br> <br> <span style="color:#008000">'Use the LINQ to SQL Class to access</span><br> <span style="color:#008000">' the Contact table in the Adventure-</span><br> <span style="color:#008000">' Works database.</span><br> <span style="color:#0000ff">Dim</span> db <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataClasses1DataContext()<br> <br> <span style="color:#008000">'Use LINQ to retrieve the rows from the</span><br> <span style="color:#008000">' Contact table.</span><br> <span style="color:#008000">' Notice that the ".Take(1000)" method</span><br> <span style="color:#008000">' returns the first (top) 1000 rows </span><br> <span style="color:#008000">' of the result set.</span><br> <span style="color:#0000ff">Dim</span> contacts = _<br> (<span style="color:#0000ff">From</span> contact _<br> <span style="color:#0000ff">In</span> db.Contacts _<br> Order By contact.FirstName, _<br> contact.LastName _<br> <span style="color:#0000ff">Select</span> contact).Take(1000)<br> <br> <span style="color:#008000">'Create a new generic list of Contact-</span><br> <span style="color:#008000">' Record type. This list will be</span><br> <span style="color:#008000">' returned to the Silverlight client</span><br> <span style="color:#008000">' application.</span><br> <span style="color:#0000ff">Dim</span> list <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> List(<span style="color:#0000ff">Of</span> ContactRecord)<br> <br> <span style="color:#008000">'Loop through each row of the Contact</span><br> <span style="color:#008000">' table and add it to the list.</span><br> <span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> c <span style="color:#0000ff">In</span> contacts<br> <br> list.Add( _<br> <span style="color:#0000ff">New</span> ContactRecord <span style="color:#0000ff">With</span> _<br> {.FirstName = c.FirstName, _<br> .LastName = c.LastName, _<br> .Email = c.EmailAddress})<br> <br> <span style="color:#0000ff">Next</span><br> <br> <span style="color:#008000">'Return the list</span><br> <span style="color:#0000ff">Return</span> list<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span>
</p>
</div>
</div>
</div> <p> <br />Next, Save the project (File menu | Save All). <br />  <br />   <br /></p> <h4>Updating the Web.config file…</h4> The WCF Service that we added uses the Web.config file to access configuration information.  The configuration information that it needs to retrieve is the <em>address</em>, <em>binding</em> and <em>contract</em>, which you’ll find in the <endpoint> tag. <br /> <br />Find the “Web.config” file in the Solution Explorer, and double-click on it to open it up.  Once you’ve opened it, scroll to the bottom, and look for the <em><services></em> section.  Here’s what the services section from my web.config file looks like: <br />  <br /> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:15116bd8-04a1-4a93-8ee6-85225d4340eb" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">service</span><span style="color:#0000ff"> </span><span style="color:#ff0000">behaviorConfiguration</span><span style="color:#0000ff">=</span><br> <span style="color:#0000ff"> </span>"<span style="color:#0000ff">AdventureWorks_WebServer.Service1Behavior</span>"<br> <span style="color:#0000ff"> </span><span style="color:#ff0000">name</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">AdventureWorks_WebServer.Service1</span>"<span style="color:#0000ff">></span><br> <span style="color:#0000ff"> </span><br> <span style="color:#0000ff"> <</span><span style="color:#a31515">endpoint</span><span style="color:#0000ff"> </span><span style="color:#ff0000">address</span><span style="color:#0000ff">=</span>""<span style="color:#0000ff"> </span><span style="color:#ff0000">binding</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">customBinding</span>"<span style="color:#0000ff"> </span><br> <span style="color:#0000ff"> </span><span style="color:#ff0000">bindingConfiguration</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">customBinding0</span>"<br> <span style="color:#ff0000">contract</span><span style="color:#0000ff">=</span><br> <span style="color:#0000ff"> </span>"<span style="color:#0000ff">AdventureWorks_WebServer.Service1</span>"<span style="color:#0000ff"> /></span><br> <span style="color:#0000ff"> </span><br> <span style="color:#0000ff"> <</span><span style="color:#a31515">endpoint</span><span style="color:#0000ff"> </span><span style="color:#ff0000">address</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">mex</span>"<span style="color:#0000ff"> </span><br> <span style="color:#0000ff"> </span><span style="color:#ff0000">binding</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">mexHttpBinding</span>"<span style="color:#0000ff"> </span><br> <span style="color:#0000ff"> </span><span style="color:#ff0000">contract</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">IMetadataExchange</span>"<span style="color:#0000ff"> /></span><br> <span style="color:#0000ff"> </span><br> <span style="color:#0000ff"></</span><span style="color:#a31515">service</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <br /> <p>Notice that there are two <em>endpoint</em> tags:   the top one, which has an address=””, and the bottom one, which has an address=”mex”.  We want to focus on the top one, with the address=””, as follows: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:259a5ba2-827d-4565-b1eb-e06d8733540f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">endpoint</span><span style="color:#0000ff"> </span><span style="color:#ff0000">address</span><span style="color:#0000ff">=</span>""<span style="color:#0000ff"> </span><span style="color:#ff0000">binding</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">customBinding</span>"<span style="color:#0000ff"> </span><br> <span style="color:#0000ff"> </span><span style="color:#ff0000">bindingConfiguration</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">customBinding0</span>"<br> <span style="color:#ff0000">contract</span><span style="color:#0000ff">=</span><br> <span style="color:#0000ff"> </span>"<span style="color:#0000ff">AdventureWorks_WebServer.Service1</span>"<span style="color:#0000ff"> /></span>
</p>
</div>
</div>
</div> <p> <br />In order to successfully communicate with the Silverlight client application, we need to change the binding to “basicHttpBinding”, and remove the <em>bindingConfiguration</em>, as follows: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6785ceac-416c-4715-bd69-f919ae9fb486" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">endpoint</span><span style="color:#0000ff"> </span><span style="color:#ff0000">address</span><span style="color:#0000ff">=</span>""<span style="color:#0000ff"> </span><span style="color:#ff0000">binding</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">basicHttpBinding</span>"<span style="color:#0000ff"> </span><br> <span style="color:#0000ff"> </span><span style="color:#ff0000">contract</span><span style="color:#0000ff">=</span><br> <span style="color:#0000ff"> </span>"<span style="color:#0000ff">AdventureWorks_WebServer.Service1</span>"<span style="color:#0000ff"> /></span>
</p>
</div>
</div>
</div> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p>  <br />When you’ve made those changes, save the project (File menu | Save All), then close the web.config file. <br />  <br />Ok, so now we have the connection setup, the LINQ to SQL Class added, the ContactRecord class created, the WCF service programmed, and the web.config file updated…  So we are ready to start working with the Silverlight client interface. <br />  <br /> </p> <h4>Adding a Service Reference to the Silverlight Client…</h4> Now for the exciting part!  We get to start working with Silverlight 3 itself!  <br /> <br />View the Solution Explorer, and go to the AdventureWorks silverlight client application, as shown here: <br /> <br /><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq69vc_DSFI/AAAAAAAAASs/2sLCKlVbibg/s1600-h/silverlightProject%5B11%5D.jpg"><img style="border-right-width: 0px; width: 263px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="silverlightProject" border="0" alt="silverlightProject" src="http://lh4.ggpht.com/_dhkDWtu14Jc/Sq69vwvmvuI/AAAAAAAAASw/Swe8vIBLNoc/silverlightProject_thumb%5B9%5D.jpg?imgmax=800" width="263" height="116" /></a>   <br />The first thing we’ll do is add a reference to the WCF Service that we created earlier.  This will enable our Silverlight client application to communicate with the WCF service we created earlier.  To do this, right-click on the AdventureWorks project node, then select “Add Service Reference…”, as follows: <br /> <br /><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq69wKfscFI/AAAAAAAAAS0/I6f2amYVBi0/s1600-h/addServiceRef%5B11%5D.jpg"><img style="border-right-width: 0px; width: 263px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="addServiceRef" border="0" alt="addServiceRef" src="http://lh4.ggpht.com/_dhkDWtu14Jc/Sq69wsJXWPI/AAAAAAAAAS4/m77yUzA1gjs/addServiceRef_thumb%5B9%5D.jpg?imgmax=800" width="263" height="255" /></a> <br /> <p></p> <p>Once you’ve clicked the menu item, the Add Service Reference window will open.  After it has opened, perform the following steps: <br /> <br />     -  Click the Discover button to find the Address of our service. <br />     -  In the Services treeview, you should see our service listed. <br />     -  Expand the “Service1.svc” node. <br />     -  Expand the “Service1” node.</p> <p>     -  Click on the final “Service1” child node.</p> <p>     -  You should be able to see the “GetContacts” method in the Operations <br />        listview on the right. <br /> <br />Here’s what the window looked like for me: <br /> <br /><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sq69w87f5hI/AAAAAAAAAS8/ouHjlWWn0PQ/s1600-h/addService%5B7%5D.jpg"><img style="border-right-width: 0px; width: 437px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="addService" border="0" alt="addService" src="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq69xR_7KPI/AAAAAAAAATA/M_BilmsDIVI/addService_thumb%5B5%5D.jpg?imgmax=800" width="437" height="356" /></a> <br /><em>If after you have clicked the Discover button, you do not see the Service1.svc service listed, go back to the web.config file and make sure you configured it correctly, as demonstrated above.  Be sure to remove any unnecessary spaces between the address, binding and contract attributes and their values.</em></p> <p> <br />Next, click the Advanced… button to display the Service Reference Settings windows.  Here, we need to change the Collection type to System.Collections.Generic.List, as follows: <br /> <br /><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69x-dESwI/AAAAAAAAATE/5xv2Xjybtv4/s1600-h/serviceRefSettings%5B6%5D.jpg"><img style="border-right-width: 0px; width: 436px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="serviceRefSettings" border="0" alt="serviceRefSettings" src="http://lh4.ggpht.com/_dhkDWtu14Jc/Sq69yRUgA6I/AAAAAAAAATI/gieeuKiBsnU/serviceRefSettings_thumb%5B4%5D.jpg?imgmax=800" width="436" height="455" /></a> <br />After you have changed the collection type, click the OK button to close the Service Reference Settings window, then OK again, to close the Add Service Reference window. <br />  <br /></p> <p>Now you should be able to see the new service reference that we added in Solution Explorer: <br /> <br /><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69y8QkTlI/AAAAAAAAATM/rUv5xmwFP7U/s1600-h/solutionExplorer2%5B12%5D.jpg"><img style="border-right-width: 0px; width: 263px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="solutionExplorer2" border="0" alt="solutionExplorer2" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sq69zCT3zaI/AAAAAAAAATQ/P5RNh3W7lQg/solutionExplorer2_thumb%5B10%5D.jpg?imgmax=800" width="263" height="184" /></a>  <br />We will use the service reference later. <br />  <br /> </p> <h4>Programming the Interface…</h4> <p>Now we have everything in place!  The last thing we need to do is program the interface of our Silverlight client application, and then add the Visual Basic code necessary to retrieve the data, and display it on our interface. <br /> <br />In the Solution Explorer, find the MainPage.xaml file, and double-click on it.  This will open the file in the XAML editor. <br /> <br />Once the MainPage.xaml file is open in the XAML editor, you will notice that it is a UserControl.  This is obvious, just by looking at the starting and ending <UserControl> tags.  As mentioned earlier, the AdventureWorksTestPage.aspx is the start up web page that gets loaded when the application runs, but within it is the embedded MainPage.xaml user control.  The interface that we program in the MainPage.xaml user control is the actual interface that will appear on the web page when the program runs. <br /> <br /> <br /><strong>Configuring the main Grid</strong> <br />The first thing to do is find the <em><Grid</em> tag and add a Margin attribute, setting it to a value of 10.  This will give us a margin of 10 all the way around all 4 sides of the UserControl.  Additionally, set ShowGridLines=”True”, so that the grid lines will be visible while we program the interface.  We will remove this later, but for now it will let us see the grid as we work. <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b125b0b4-66e4-4853-bc50-089f8e161a94" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#a31515"></span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid</span><span style="color:#ff0000"> x</span><span style="color:#0000ff">:</span><span style="color:#ff0000">Name</span><span style="color:#0000ff">="LayoutRoot"</span> <br> <span style="color:#ff0000">Margin</span><span style="color:#0000ff">="10"</span><span style="color:#ff0000"> ShowGridLines</span><span style="color:#0000ff">="True" ></span><br> <br> <span style="color:#a31515"></span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p> <br />The next thing we’ll do is break the interface up into 2 sections:  a header section at the top, and a data section filling the remainder of the page.  To do that, configure the Grid to have 1 column and 2 rows: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9ff3c940-766b-457d-9e38-e860f2f32ece" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#a31515"></span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid</span><span style="color:#ff0000"> x</span><span style="color:#0000ff">:</span><span style="color:#ff0000">Name</span><span style="color:#0000ff">="LayoutRoot"</span> <br> <span style="color:#ff0000">Margin</span><span style="color:#0000ff">="10"</span><span style="color:#ff0000"> ShowGridLines</span><span style="color:#0000ff">="True" ></span><br> <br> <span style="color:#0000ff"></span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid.ColumnDefinitions</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">ColumnDefinition</span><span style="color:#ff0000"> Width</span><span style="color:#0000ff">="*" /></span><br> <span style="color:#0000ff"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid.ColumnDefinitions</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"> </span><span style="color:#a31515"></span><br> <span style="color:#a31515"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid.RowDefinitions</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">RowDefinition</span><span style="color:#ff0000"> Height</span><span style="color:#0000ff">="50" /></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">RowDefinition</span><span style="color:#ff0000"> Height</span><span style="color:#0000ff">="*" /></span><br> <span style="color:#0000ff"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid.RowDefinitions</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p> <br /><em>Notice that the asterisk (“*”) is used to indicate the remaining space available.  This will cause the width of the column to automatically adjust to the width of the Grid. <br /> <br /></em>Now, run the application (F5).  Since this is the first time running the application, you should be prompted to enable debugging when the following window opens: <br /> <br /><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sq69zWrx3UI/AAAAAAAAATU/kJJvQA3vAko/s1600-h/enableDebugging%5B6%5D.jpg"><img style="border-right-width: 0px; width: 428px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="enableDebugging" border="0" alt="enableDebugging" src="http://lh5.ggpht.com/_dhkDWtu14Jc/Sq690LJS7AI/AAAAAAAAATY/ryejqG8dBds/enableDebugging_thumb%5B4%5D.jpg?imgmax=800" width="428" height="217" /></a> <br />Leave the default selected, and click the OK button. <br /> <br />Once the application runs, and the web page loads, you’ll be able to see how the web page is divided into 2 separate sections:  a header at the top, and a data section that fills the remainder of the page.  Here’s what mine looks like: <br /> <br /><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sq690TqJ5eI/AAAAAAAAATc/HmBnkUD8eI0/s1600-h/page1%5B6%5D.jpg"><img style="border-right-width: 0px; width: 427px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="page1" border="0" alt="page1" src="http://lh4.ggpht.com/_dhkDWtu14Jc/Sq690wQGMkI/AAAAAAAAATg/nRTGA68kZi4/page1_thumb%5B4%5D.jpg?imgmax=800" width="427" height="333" /></a>  <br />Close Internet Explorer, and return to the MainPage.xaml editor.  Remove  ShowGridLines=”True” from the grid tag. <br /> <br /> <br /><strong>Configure the header Grid</strong> <br />In the header section of the main grid (row 0), we are going to add another grid that will be used to position the title of the page, and the button that will be used to retrieve and load the data. <br /> <br />Before we add the grid though, add a nice maroon border, with a thickness of “1”.  This border will encompass the grid. <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6537b8e5-3b6a-489a-9363-1dc4fece443e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">Border</span><span style="color:#ff0000"> BorderBrush</span><span style="color:#0000ff">="Maroon"</span><span style="color:#ff0000"> BorderThickness</span><span style="color:#0000ff">="1" ></span><br> <span style="color:#0000ff"></span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Border</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p> <br />Add the grid within the Border tags, and set the background color to light yellow.  Additionally, add extended attributes to the grid, instructing it to be positioned in the header section (first column (column 0); top row (row 0)) of the main grid. <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:56711906-3471-4978-8013-ee0c04b0a8d6" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">Border</span><span style="color:#ff0000"> BorderBrush</span><span style="color:#0000ff">="Maroon"</span><span style="color:#ff0000"> BorderThickness</span><span style="color:#0000ff">="1" ></span><br> <br> <span style="color:#0000ff"></span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid</span><span style="color:#ff0000"> Background</span><span style="color:#0000ff">="LightYellow"</span> <br> <span style="color:#ff0000"> Grid.Column</span><span style="color:#0000ff">="0"</span><span style="color:#ff0000"> Grid.Row</span><span style="color:#0000ff">="0" ></span><br> <br> <br> <span style="color:#0000ff"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"></span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Border</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p> <br />Define 2 columns for the grid:  The first column will have a width of “*”, and will store the title.  The second column will have a width of “100”, and will store the button that will be used to load the data. <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4acaa291-c585-483f-8edf-205a5dce0cb4" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">Border</span><span style="color:#ff0000"> BorderBrush</span><span style="color:#0000ff">="Maroon"</span><span style="color:#ff0000"> BorderThickness</span><span style="color:#0000ff">="1" ></span><br> <br> <span style="color:#0000ff"></span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid</span><span style="color:#ff0000"> Background</span><span style="color:#0000ff">="LightYellow"</span> <br> <span style="color:#ff0000"> Grid.Column</span><span style="color:#0000ff">="0"</span><span style="color:#ff0000"> Grid.Row</span><span style="color:#0000ff">="0" ></span><br> <br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid.ColumnDefinitions</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">ColumnDefinition</span><span style="color:#ff0000"> Width</span><span style="color:#0000ff">="*" /></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">ColumnDefinition</span><span style="color:#ff0000"> Width</span><span style="color:#0000ff">="100" /></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid.ColumnDefinitions</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"> </span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"></span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Border</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p> <br />Finally, add a TextBlock to display the title of the page.  Set the Text to “AdventureWorks Contacts”.  Use the grid’s extended attributes to position the TextBlock in column 0, row 0. <br /> <br />Then, add a Button that will be used to display the data.  Set it’s Name to “btnLoad”, the Content to “Load”, and then use the grid’s extended attributes to position the Button in column 1, row 0.  Set the Click attribute to “btnLoad_Click”. <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f73e2b70-f195-496a-b757-ef11e881425d" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">Border</span><span style="color:#ff0000"> BorderBrush</span><span style="color:#0000ff">="Maroon"</span><span style="color:#ff0000"> BorderThickness</span><span style="color:#0000ff">="1" ></span><br> <br> <span style="color:#0000ff"></span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid</span><span style="color:#ff0000"> Background</span><span style="color:#0000ff">="LightYellow"</span> <br> <span style="color:#ff0000"> Grid.Column</span><span style="color:#0000ff">="0"</span><span style="color:#ff0000"> Grid.Row</span><span style="color:#0000ff">="0" ></span><br> <br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">Grid.ColumnDefinitions</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">ColumnDefinition</span><span style="color:#ff0000"> Width</span><span style="color:#0000ff">="*" /></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">ColumnDefinition</span><span style="color:#ff0000"> Width</span><span style="color:#0000ff">="100" /></span><br> <span style="color:#0000ff"> </span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid.ColumnDefinitions</span><span style="color:#0000ff">></span><br> <br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">TextBlock</span><span style="color:#ff0000"> Padding</span><span style="color:#0000ff">="10,0,0,0"</span> <br> <span style="color:#ff0000"> VerticalAlignment</span><span style="color:#0000ff">="Center"</span> <br> <span style="color:#ff0000"> Text</span><span style="color:#0000ff">="AdventureWorks Contacts"</span> <br> <span style="color:#ff0000"> FontSize</span><span style="color:#0000ff">="28"</span> <br> <span style="color:#ff0000"> Foreground</span><span style="color:#0000ff">="Maroon"</span> <br> <span style="color:#ff0000"> Grid.Row</span><span style="color:#0000ff">="0"</span><span style="color:#ff0000"> Grid.Column</span><span style="color:#0000ff">="0" /></span><br> <br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">Button</span><span style="color:#ff0000"> x</span><span style="color:#0000ff">:</span><span style="color:#ff0000">Name</span><span style="color:#0000ff">="btnLoad"</span> <span style="color:#ff0000"> Content</span><span style="color:#0000ff">="Load"</span> <br> <span style="color:#ff0000">VerticalAlignment</span><span style="color:#0000ff">="Center"</span> <br> <span style="color:#ff0000">Margin</span><span style="color:#0000ff">="10"</span> <br> <span style="color:#ff0000">Grid.Row</span><span style="color:#0000ff">="0"</span><span style="color:#ff0000"> Grid.Column</span><span style="color:#0000ff">="1"</span> <br> <span style="color:#ff0000">Click</span><span style="color:#0000ff">="btnLoad_Click"/></span><br> <span style="color:#0000ff"> </span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Grid</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"></span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">Border</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p> <br />And that’s the end of the header! <br /> <br />Before moving on, find the <em>Click attribute</em> of the Button, and right-click on “btnLoad_Click”, then select “Navigate to Event Handler” to create the respective sub routine.  After the sub routine has been created, return to the xaml editor. <br /> <br /> <br /><strong>Configure the data grid <br /></strong>The next thing to do is add a Silverlight DataGrid to the interface.  To do this, display the ToolBox, find the DataGrid control, then drag it onto the xaml editor, and drop it just under the </Border> tag. <br /> <br />Set the Name to “dataGrid1”; AutoGenerateColumns to “False”, because we are going to add the columns manualy; Visibility to “Collapsed”, because we want the grid to be hidden when the page loads; and then use the main grid’s extended attributes to position the DataGrid in Column 0, Row 1 (which is the bottom part of the main grid). <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:659d4c04-cc62-478d-8259-972242048979" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGrid</span> <span style="color:#ff0000"> x</span><span style="color:#0000ff">:</span><span style="color:#ff0000">Name</span><span style="color:#0000ff">="dataGrid1"</span> <br> <span style="color:#ff0000">AutoGenerateColumns</span><span style="color:#0000ff">="False"</span> <br> <span style="color:#ff0000">Visibility</span><span style="color:#0000ff">="Collapsed"</span><br> <span style="color:#ff0000">Grid.Row</span><span style="color:#0000ff">="1"</span><span style="color:#ff0000"> Grid.Column</span><span style="color:#0000ff">="0" ></span><br> <span style="color:#0000ff"></span><br> <span style="color:#a31515"></span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGrid</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p> <br />The last thing we need to do to the DataGrid is add three text columns:  one for FirstName, one for LastName, and one for Email. <br /> <br />In particular, notice below how each column is bound to the DataSource, by setting the Binding attribute.  Additionally, notice how the value for the Binding attribute is a string expression, enclosed in curly braces {}, using the <em>Binding</em> keyword, and the name of the property in the DataSource to bind to.  <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:45cf6158-7f18-4a97-b646-04f73e60bcaf" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff"><</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGrid</span> <span style="color:#ff0000"> x</span><span style="color:#0000ff">:</span><span style="color:#ff0000">Name</span><span style="color:#0000ff">="dataGrid1"</span> <br> <span style="color:#ff0000">AutoGenerateColumns</span><span style="color:#0000ff">="False"</span> <br> <span style="color:#ff0000">Visibility</span><span style="color:#0000ff">="Collapsed"</span><br> <span style="color:#ff0000">Grid.Row</span><span style="color:#0000ff">="1"</span><span style="color:#ff0000"> Grid.Column</span><span style="color:#0000ff">="0" ></span><br> <br> <span style="color:#0000ff"></span><span style="color:#0000ff"><</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGrid.Columns</span><span style="color:#0000ff">></span><br> <br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGridTextColumn</span> <br> <span style="color:#ff0000">Binding</span><span style="color:#0000ff">="{</span><span style="color:#a31515">Binding</span><span style="color:#ff0000"> FirstName</span><span style="color:#0000ff">}"</span> <br> <span style="color:#ff0000">Header</span><span style="color:#0000ff">="First Name" /></span><br> <br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGridTextColumn</span> <br> <span style="color:#ff0000">Binding</span><span style="color:#0000ff">="{</span><span style="color:#a31515">Binding</span><span style="color:#ff0000"> LastName</span><span style="color:#0000ff">}"</span> <br> <span style="color:#ff0000">Header</span><span style="color:#0000ff">="Last Name" /></span><br> <br> <span style="color:#0000ff"> </span><span style="color:#0000ff"><</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGridTextColumn</span> <br> <span style="color:#ff0000">Binding</span><span style="color:#0000ff">="{</span><span style="color:#a31515">Binding</span><span style="color:#ff0000"> Email</span><span style="color:#0000ff">}"</span> <br> <span style="color:#ff0000">Header</span><span style="color:#0000ff">="Email Address" /></span><br> <br> <span style="color:#0000ff"></span><span style="color:#0000ff"></</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGrid.Columns</span><span style="color:#0000ff">></span><br> <span style="color:#0000ff"></span><br> <span style="color:#a31515"></span><span style="color:#0000ff"></</span><span style="color:#a31515">data</span><span style="color:#0000ff">:</span><span style="color:#a31515">DataGrid</span><span style="color:#0000ff">></span>
</p>
</div>
</div>
</div> <p> <br />At this point, you can save the project (File menu | Save All).  Then, run the application (F5).  The end result should look like this: <br />  <br /><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq691JK41qI/AAAAAAAAATk/jZDad9b51t4/s1600-h/page2%5B5%5D.jpg"><img style="border-right-width: 0px; width: 439px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="page2" border="0" alt="page2" src="http://lh4.ggpht.com/_dhkDWtu14Jc/Sq691cTgIxI/AAAAAAAAATo/1vNZT6ENS1I/page2_thumb%5B3%5D.jpg?imgmax=800" width="439" height="284" /></a>  <br />Close Internet Explorer, and return to the xaml editor when you’re finished. <br /> <br /> <br /><strong>Adding the Visual Basic Code <br /></strong>The last thing we need to do is add the Visual Basic Code to tie it all together, and make things work!  So to start, right-click on the xaml editor and select “View Code” to go to the code window. <br /> <br />At the top of the code window, using the <em>WithEvents</em> keyword, add a declaration to our WCF service: <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:de626026-742b-41e8-be41-722a8c07d6d3" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new instance of our WCF Service</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">WithEvents</span> mService <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> ServiceReference1.Service1Client()
</p>
</div>
</div>
</div> <p> <br />Then, go to the Class Name drop down list at the top of the code window and select “mService”; following, go to the Method Name drop down list at the top of the code window and select “GetContactsCompleted”. <br />  <br /><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sq691_xrb3I/AAAAAAAAATs/h-zEnngPZr4/s1600-h/ClassName%5B8%5D.jpg"><img style="border-right-width: 0px; width: 440px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="ClassName" border="0" alt="ClassName" src="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq692HtgLQI/AAAAAAAAATw/5t_VLNi6UUs/ClassName_thumb%5B6%5D.jpg?imgmax=800" width="440" height="76" /></a>  <br />Selecting “GetContactsCompleted” from the Method Name drop down list will create the mService_GetContactsCompleted event handler.  Within this event handler, just add 2 lines of code:  One to make the grid visible, and one to load the DataGrid with data: <br />  <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c5404607-24f0-4ae9-a429-5f555cbb3335" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mService_GetContactsCompleted( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> ServiceReference1 _<br> .GetContactsCompletedEventArgs) _<br> <span style="color:#0000ff">Handles</span> mService.GetContactsCompleted<br> <br> dataGrid1.ItemsSource = e.Result<br> dataGrid1.Visibility = _<br> Windows.Visibility.Visible<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> <br /><em>The “GetContactsCompleted”</em> event handler is executed after the WCF service has retrieved the data from the SQL Server, and is ready to pass the data to our Silverlight client. <br /> <br />The final thing to do is add the code that starts the asynchronous process of getting the Contact data from our WCF service.  Add this 1 line of code to the btnLoad_Click event handler: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:55f10a1c-2755-4415-b541-6216ef3c2a14" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> btnLoad_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.Windows.RoutedEventArgs)<br> <br> mService.GetContactsAsync()<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> <br />So now, the complete code window should look like this: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f3a1d913-5865-448e-a96c-114cd9925307" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Partial</span> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> MainPage<br> <span style="color:#0000ff">Inherits</span> UserControl<br> <br> <span style="color:#008000">'Create a new instance of our WCF Service</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">WithEvents</span> mService <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> ServiceReference1.Service1Client()<br> <br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> <span style="color:#0000ff">New</span>()<br> InitializeComponent()<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> btnLoad_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.Windows.RoutedEventArgs)<br> <br> mService.GetContactsAsync()<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mService_GetContactsCompleted( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> ServiceReference1 _<br> .GetContactsCompletedEventArgs) _<br> <span style="color:#0000ff">Handles</span> mService.GetContactsCompleted<br> <br> dataGrid1.ItemsSource = e.Result<br> dataGrid1.Visibility = _<br> Windows.Visibility.Visible<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> <br />And that’s all there is to it! <br /> <br />Save the project (File menu | Save All).  Then run the application (F5).  When the application opens, click the “Load” button to retrieve the data from the SQL Server AdventureWorks database, and load it into the Silverlight DataGrid.  If everything worked right, you should see the following: <br />  <br /><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq692q5Wx5I/AAAAAAAAAT0/t6hzDN83xMU/s1600-h/demo%5B11%5D.jpg"><img style="border-right-width: 0px; width: 439px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="demo" border="0" alt="demo" src="http://lh3.ggpht.com/_dhkDWtu14Jc/Sq693OSE7hI/AAAAAAAAAT4/DrF2FUHrlqU/demo_thumb%5B8%5D.jpg?imgmax=800" width="439" height="303" /></a>  <br />  <br /></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <h4>Summary</h4> This article demonstrated how to create a WCF service that used LINQ to SQL to retrieve data from the Person.Contact table of the AdventureWorks database, how to update the service endpoint configuration of the web.config file to enable the WCF service to return the results to the Silverlight Client application, plus how to reference a WCF service from a Silverlight Client application, and how to program the Silverlight Client interface to display the retrieved data in a Silverlight DataGrid. VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-5578085788793401322009-09-07T07:00:00.000-06:002009-09-08T14:13:35.268-06:00ADO.NET: DataView<p>DataTables are a great solution for caching data in memory.  In fact, out of the box, there is no .NET class that is more suited for the task than a DataTable.</p> <p> </p> <p>But, a DataTable, in and of itself, is not flexible enough to support sorting, searching and filtering of data.  The only 2 methods that a DataTable has that can be used for searching are:  the <em>Find</em> method, which lets you locate a row based on its primary key value; and the other is the <em>Select</em> method, which returns an array of rows based on filter criteria.  When you want more flexibility for performing sorting, searching, and filtering, you’ll want to use a DataView.</p> <p> </p> <p>A DataView was essentially designed to be a <em>view</em> of the data that is stored in a DataTable.  It is not a separate cache of data, so it does not maintain its own copy of data.  But, it provides a more flexible way of working with the data that is stored in a DataTable, and in many times is actually used in place of a DataTable.</p> <p> </p> <p>Every DataTable has a <em>Default </em>DataView.  If you didn’t know that, consider this:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:af72fe18-d9d9-435c-9bfb-915327494c51" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Get a reference to the DataTable's <br> ' Default DataView<br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Setting Things Up…</h4> <p>First, let’s create a new Visual Basic Windows Forms Application project called “WorkingWithDataViews”.  Add 2 DataGridViews to the form and set the <em>AutoSizeColumnMode</em> property for each to “<em>DisplayedCells”</em>, then add 2 labels, and a button.  Mine looks like this:</p> <p> </p> <p><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sqa63Qzh2bI/AAAAAAAAAQE/kH1mSwillYw/s1600-h/form.jpg"><img style="border-bottom: 0px; border-left: 0px; width: 350px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="form" border="0" alt="form" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sp6FYPKj5qI/AAAAAAAAAQI/3rvKoZebEw8/form_thumb.jpg?imgmax=800" width="350" height="352" /></a> </p> <p> </p> <p> </p> <p>Next, before we get started working with DataView’s, let’s create a DataTable and populate it with some data so that we have something to work with.</p> <p> </p> <p>If you are new to DataTables, then you may want to take a look at 2 other articles that I’ve written about them:</p> <p> </p> <p><a href="http://garylima.blogspot.com/2009/08/adonet-datatables-introduction_07.html" target="_blank">ADO.NET:  DataTables, An Introduction</a></p> <p> </p> <p><a href="http://garylima.blogspot.com/2009/08/adonet-datatables-in-depth.html" target="_blank">ADO.NET:  DataTables, In-depth</a></p> <p></p> <p> </p> <p> </p> <p>Create an Employee DataTable, then fill it with some employees.</p> <p> </p> <p><em>You can just double-click on Button1, and insert this code into the Button1_Click event handler, if you want.</em></p> <p> </p> <p></p> <p></p> <p><em></em></p> <p><em></em></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fbb5b9be-ef18-4259-9920-288bcf8fc1dc" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable(<span style="color:#a31515">"Employee"</span>)<br> <br> <span style="color:#008000">'Add an auto ID column</span><br> table.Columns.Add(<span style="color:#a31515">"ID"</span>, <span style="color:#0000ff">GetType</span>(<span style="color:#0000ff">Integer</span>)) _<br> .AutoIncrement = <span style="color:#0000ff">True<br> <br> </span><span style="color:#008000">'Add additional columns</span><br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> table.Columns.Add(<span style="color:#a31515">"LastName"</span>)<br> table.Columns.Add(<span style="color:#a31515">"HireDate"</span>, <span style="color:#0000ff">GetType</span>(<span style="color:#0000ff">Date</span>))<br> <br> <span style="color:#008000">'Set the PrimaryKey for the table</span><br> table.PrimaryKey = _<br> <span style="color:#0000ff">New</span> DataColumn() {table.Columns(<span style="color:#a31515">"ID"</span>)}<br> <br> <span style="color:#008000">'Add data to it.<br> </span><span style="color:#0000ff">With</span> table.Rows<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Gary"</span>, <span style="color:#a31515">"Lima"</span>, #1/1/2000#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Paola"</span>, <span style="color:#a31515">"Rael"</span>, #12/25/2008#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Anthony"</span>, <span style="color:#a31515">"Rael"</span>, #2/1/2009#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Andrew"</span>, <span style="color:#a31515">"Roberts"</span>, #2/1/2009#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Daniel"</span>, <span style="color:#a31515">"Parks"</span>, #6/15/1990#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Jay"</span>, <span style="color:#a31515">"Adams"</span>, #6/15/1990#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Amy"</span>, <span style="color:#a31515">"Alberts"</span>, #6/15/1990#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Sean"</span>, <span style="color:#a31515">"Allen"</span>, #6/15/1990#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"John"</span>, <span style="color:#a31515">"Black"</span>, #6/15/1990#)<br> .Add(<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Jordan"</span>, <span style="color:#a31515">"Perry"</span>, #6/15/1990#)<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">With<br> <br> <br> </span><span style="color:#008000">'Accept changes, changing the RowState from<br> ' "Added" to "UnModified"</span><br> table.AcceptChanges() </p>
</div>
</div>
</div> <p><em> </em></p> <p><em>The Employees table above will be used for all of the DataView examples below, except for the Sorting dates example.</em></p> <p> </p> <p> </p> <h4>How DataViews Work…</h4> <p>As mentioned above, a DataView is simply a <em>view</em> of the data that is stored in a DataTable.  It is not a separate copy of the data.  Therefore, viewing the contents of a DataView is just like viewing the contents of a DataTable.</p> <p> </p> <p>To demonstrate this, let’s take a look at this code added to the Button1_Click event handler:</p> <p> </p> <p></p> <p></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b7e17d0f-876f-4535-9bd4-9e433ed11b25" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Set the DataSource of DataGridView1 to the<br> ' DataTable itself.<br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = table<br> <br> <br> <span style="color:#008000">'Set the DataSource of DataGridView2 to the <br> ' DataTable's Default DataView<br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <span style="color:#0000ff">Me</span>.DataGridView2.DataSource = view
</p>
</div>
</div>
</div> <p><em> </em></p> <p><em>Notice that DataGridView1 is displaying data directly from the DataTable, and DataGridView2 is displaying data directly from the table’s default DataView</em></p> <p> </p> <p>Now, run the project (F5), and click Button1.  </p> <p> </p> <p>You’ll immediately notice that both DataGridViews look exactly the same.  They are both displaying the same data.</p> <p> </p> <p><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/Sp6FYrNelzI/AAAAAAAAAQM/xdrIZOTTpF8/s1600-h/form1.jpg"><img style="border-bottom: 0px; border-left: 0px; width: 350px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="form1" border="0" alt="form1" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sp6FY9SQY_I/AAAAAAAAAQQ/8o3DWdT16nA/form1_thumb.jpg?imgmax=800" width="350" height="352" /></a> </p> <p> </p> <p> </p> <p><u>DataViews are only a <em>view</em> of the data</u></p> <p>To prove that the DataView is simply a <em>view</em> of the data stored in the DataTable, and not a separate copy:  in DataGridView1 (top DataGridView), change the LastName for Paola from “Rael” to “Lima”.  Make sure to move to a different cell after changing the name.</p> <p> </p> <p>Notice that in DataGridView2 (bottom DataGirdView), Paola’s name immediately changes, so that both DataGridViews are displaying the same data.</p> <p> </p> <p>Here’s how it looks:</p> <p> </p> <p><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/Sp6FZYQu8nI/AAAAAAAAAQU/_pWa1JpMygA/s1600-h/form2%5B1%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; width: 350px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="form2" border="0" alt="form2" src="http://lh5.ggpht.com/_dhkDWtu14Jc/Sp6FZ6bnEzI/AAAAAAAAAQk/vuEIMJEalfg/form2_thumb.jpg?imgmax=800" width="350" height="352" /></a> </p> <p> </p> <p> </p> <p>Another thing to notice is that the DataGridViews are not in synch:  Their row positions are separate from each other.  So, if in DataGridView1, you click on the cell containing “Anthony”, DataGridView2 does not immediately move to that row.  Furthermore, if you click on a cell of any row in DataGridView2, DataGridView1 does not automatically move to that row.</p> <p> </p> <p> </p> <p><u>DataView References</u></p> <p>Now, let’s go back and change the code so that both DataGridViews are using DataViews, just like I’ve done here:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4174a96e-e1d6-4129-9dff-ff2f22aa1c4c" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Set the DataSource of DataGridView1 to the<br> ' DataTable itself.<br> </span><span style="color:#0000ff">Dim</span> view1 <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view1<br> <br> <br> <span style="color:#008000">'Set the DataSource of DataGridView2 to the <br> ' DataTable's Default DataView<br> </span><span style="color:#0000ff">Dim</span> view2 <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <span style="color:#0000ff">Me</span>.DataGridView2.DataSource = view2
</p>
</div>
</div>
</div> <p> </p> <p>Now run the program again, and notice that both DataGridViews are displaying the exact same data.</p> <p> </p> <p>In DataGridView1, try clicking on cells that are in different rows.  Notice that DataGridView2 automatically moves to the same row that DataGridView1 is on (although not the same cell).  Try clicking on different cells in DataGridView2, and notice that DataGridView1 automatically moves to the same row.</p> <p> </p> <p><u>Important notice</u></p> <p>There is something that I would really like you to notice here.  Even though my code example above declared two different variables (view1 and view2), both variables are actually pointing to the same DataView in memory, which in this case is the table’s DefaultView.</p> <p> </p> <p>This is very important to understand.  Because, any sorting or filtering applied to one DataView, automatically affects the other.</p> <p> </p> <p>Let’s test this out by sorting view1 by the FirstName column:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bd7912ce-379f-4725-96df-d338b3b4e49d" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Set the DataSource of DataGridView1 to the<br> ' DataTable itself.<br> </span><span style="color:#0000ff">Dim</span> view1 <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> view1.Sort = <span style="color:#a31515">"FirstName"<br> <br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view1<br> <br> <br> <span style="color:#008000">'Set the DataSource of DataGridView2 to the <br> ' DataTable's Default DataView<br> </span><span style="color:#0000ff">Dim</span> view2 <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#0000ff">Me</span>.DataGridView2.DataSource = view2
</p>
</div>
</div>
</div> <p> </p> <p>Now, run the program (F5) and look at the results.  The data in both DataGridViews are sorted by the FirstName column, as you can see:</p> <p> </p> <p><a href="http://lh4.ggpht.com/_dhkDWtu14Jc/Sp6FaHnJQlI/AAAAAAAAAQs/XCYlqhOQyWk/s1600-h/form3%5B1%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; width: 350px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="form3" border="0" alt="form3" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sp6Faihh8vI/AAAAAAAAAQw/m6AsT8E3WAQ/form3_thumb.jpg?imgmax=800" width="350" height="352" /></a></p> <p> </p> <p>  </p> <p><u>DataViews have a constructor</u></p> <p>If you were to try to use multiple DataViews for displaying data from a DataTable in different controls on the same form, like we are above, you may find yourself frustrated when you realize they are all in synch, especially if you are trying to apply different sorting and filtering for each DataView.</p> <p> </p> <p><em>This is a mistake I made when I first started programming with DataViews.</em></p> <p> </p> <p>Fortunately, the DataView has a constructor that can be used to create a completely separate DataView object in memory.  This means that any sorting and filtering applied to that view does not affect any other view that references the same DataTable.  Here’s an example of what I mean:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c91b44b7-dc7c-4c28-bed8-1603c3479aaf" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a NEW DataView,<br> ' passing the DataTable as an a reference<br> </span><span style="color:#0000ff">Dim</span> view1 <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataView(table)<br> view1.Sort = <span style="color:#a31515">"FirstName"<br> <br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view1<br> <br> <br> <span style="color:#008000">'Create a NEW DataView,<br> ' passing the DataTable as an a reference<br> </span><span style="color:#0000ff">Dim</span> view2 <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataView(table)<br> <br> <span style="color:#0000ff">Me</span>.DataGridView2.DataSource = view2
</p>
</div>
</div>
</div> <p> </p> <p>Now run the program again (F5), and notice that DataGridView1 is sorted, but DataGridView2 is not sorted.</p> <p> </p> <p><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sp6FbMvWRsI/AAAAAAAAAQ8/AcQMOvKSrS0/s1600-h/form4%5B1%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; width: 350px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="form4" border="0" alt="form4" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sp6Fbj4hcTI/AAAAAAAAARE/2ak9yNhRnYM/form4_thumb.jpg?imgmax=800" width="350" height="352" /></a> </p> <p> </p> <p> </p> <h4>Sorting…</h4> <p>The examples above have already shown you how to sort a column, using the “FirstName” column.  When sorting was applied, the FirstName column was automatically sorted in Ascending order.</p> <p> </p> <p>There are 2 directions that sorting can be applied:  In Ascending (ASC) order, and in Descending (DESC) order.  Ascending is the default.</p> <p> </p> <p>To specify which direction to apply when sorting, simply add the “ASC” or “DESC” keywords after the column you wish to sort, as such:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7a58a520-cc5f-4520-98d4-4916572d1eec" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Sort the view by FirstName column<br> ' in Ascending Order</span><br> view1.Sort = <span style="color:#a31515">"FirstName ASC"<br> <br> <br> </span><span style="color:#008000">'Sort the view by FirstName column<br> ' in Descending Order</span><br> view1.Sort = <span style="color:#a31515">"FirstName DESC"</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p><u>Sorting by multiple columns</u></p> <p>Sorting can not only be applied to one column, but it can also be applied to multiple columns.  All you have to do is list the columns that you want to sort by, separated by a comma.  </p> <p> </p> <p>For example, to sort by LastName, and then FirstName, use the following syntax:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a983e71a-1135-4cef-b5dc-2fc0c2f2d9f4" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Sort the view by LastName column, then<br> ' by FirstName column in Ascending Order<br> ' (which is the default)</span><br> view1.Sort = <span style="color:#a31515">"LastName, FirstName"</span>
</p>
</div>
</div>
</div> <p> </p> <p>To specify the sort direction for each individual column, simply add the ASC or DESC keywords after the column names:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:54de6363-3cd9-425e-b101-e50144d6f067" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Sort the view by LastName column in Descending<br> ' order, then by FirstName column in Descending<br> ' order</span><br> view1.Sort = <span style="color:#a31515">"LastName DESC, FirstName DESC"</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p><u>Data Types affect sorting</u></p> <p>Another very important note is that the Data Type of a column affects the way the data is sorted.  Because Strings sort one way, Integers sort another way, Dates sort another way, etc…  So if your sorting does not work the way you expect, go back and check the Data Type of the column you are trying to sort, and make sure it is correct for the type of data that is being stored in it.</p> <p> </p> <p>Let me give you an example:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:925a5e2f-c777-4a18-a7b1-fdc85d082665" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new table with a Date Colum<br> ' The default Data Type is String<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table.Columns.Add(<span style="color:#a31515">"Date"</span>)<br> <br> <span style="color:#008000">'Add 24 months of data<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = -24 <span style="color:#0000ff">To</span> -1<br> table.Rows.Add(Today.AddMonths(i)) : <span style="color:#0000ff">Next<br> <br> </span><span style="color:#008000">'Get the DataView for the table<br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Sort by Date Ascending<br> ' NOTE: The data type for the Date<br> ' column is a String</span><br> view.Sort = <span style="color:#a31515">"Date ASC"<br> <br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view
</p>
</div>
</div>
</div> <p> </p> <p>Take a look at the result here:  It’s not sorted correctly.  </p> <p> </p> <p><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sp6FcKrGpMI/AAAAAAAAARQ/8uvYeXIZRP8/s1600-h/form6%5B1%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; width: 350px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="form6" border="0" alt="form6" src="http://lh3.ggpht.com/_dhkDWtu14Jc/Sp6FcZ7X-vI/AAAAAAAAARU/Pt-DZJANzQw/form6_thumb.jpg?imgmax=800" width="350" height="352" /></a> </p> <p> </p> <p>  </p> <p>Notice that the first date is January 2008, then January 2009, then October 2007, then October 2008, etc.</p> <p> </p> <p>That’s why it’s very important to make sure your columns have the correct data type.  </p> <p> </p> <p> </p> <p>Now, let’s fix this problem by setting the Date column’s data type to Date, and then try sorting again:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:035e1a97-b644-470c-962e-3f4991175ae9" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new table with a Date Column<br> ' The default Data Type is String<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Set the data type to Date</span><br> table.Columns.Add(<span style="color:#a31515">"Date"</span>, <span style="color:#0000ff">GetType</span>(<span style="color:#0000ff">Date</span>))<br> <br> <span style="color:#008000">'Add 24 months of data<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = -24 <span style="color:#0000ff">To</span> -1<br> table.Rows.Add(Today.AddMonths(i)) : <span style="color:#0000ff">Next<br> <br> </span><span style="color:#008000">'Get the DataView for the table<br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Sort by Date Ascending<br> ' NOTE: The data type for the Date<br> ' column is a String</span><br> view.Sort = <span style="color:#a31515">"Date ASC"<br> <br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view
</p>
</div>
</div>
</div> <p> </p> <p>And the result:</p> <p> </p> <p><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sp6Fczj3V_I/AAAAAAAAARY/1_Lq7SaZ02M/s1600-h/form7%5B1%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; width: 350px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="form7" border="0" alt="form7" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Sp6FdrMdkAI/AAAAAAAAARg/4d0w8wmv6gw/form7_thumb.jpg?imgmax=800" width="350" height="352" /></a> </p> <p> </p> <p> </p> <h4>Searching…</h4> <p>Not only can DataViews be used for sorting, but they can be used for Searching as well.  The Find and FindRows methods are the two methods that the DataView uses to perform searches.</p> <p> </p> <p><u>Set the Sort property First</u></p> <p>Before searching can be performed using the Find or FindRows methods, the Sort property must be set.  It can be set to 1 column (as “FirstName”) or to multiple columns (as "LastName, FirstName”).  Setting the Sort property on a DataView causes the corresponding DataTable to create an index on each column referenced.</p> <p> </p> <p><u>Using the Find method</u></p> <p>When a search is performed using the Find method, you pass the value you want to search for (eg.:  “Gary”), or an array of values you want to search for (eg.:  “Paola”, “Rael”), that correspond to the columns applied to the Sort property.  When a match is found, an integer is returned that indicates the index of the matching row within the DataView.  If no matching row is found, then a –1 is returned.</p> <p> </p> <p>Here’s an example of using the Find method to search for “Gary”:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e685534b-23b1-4b3e-869a-9c6838c7bae4" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Get a reference to the table's <br> ' default DataView<br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Set the Sort to the name of the column<br> ' that we want to search</span><br> view.Sort = <span style="color:#a31515">"FirstName"<br> <br> </span><span style="color:#008000">'Set the view as the source for DataGridView 1<br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view<br> <br> <span style="color:#008000">'Create a variable to store the index of<br> ' the row, if found<br> </span><span style="color:#0000ff">Dim</span> index <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer<br> <br> </span><span style="color:#008000">'Search for "Gary"</span><br> index = view.Find(<span style="color:#a31515">"Gary"</span>)<br> <br> <span style="color:#008000">'If it was found Gary, then the value of <br> ' index will be greater than -1<br> </span><span style="color:#0000ff">If</span> index > -1 <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'A match was found, so use the row index </span><br> <span style="color:#008000">' to set the current cell of DataGridView 1</span><br> <span style="color:#0000ff">Me</span>.DataGridView1.CurrentCell = _<br> DataGridView1.Rows(index).Cells(1)<br> <br> <span style="color:#0000ff">Else</span><br> MsgBox(<span style="color:#a31515">"Match not found"</span>)<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Here’s another example of using the Find method to search for multiple values (a FirstName and a LastName) matching “Paola" “Rael”:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e8ee04aa-0406-49da-8291-d922f1014aca" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Get a reference to the table's <br> ' default DataView <br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Set the Sort to the name of the columns <br> ' that we want to search: The FirstName <br> ' column and the LastName column </span><br> view.Sort = <span style="color:#a31515">"FirstName, LastName"<br> <br> </span><span style="color:#008000">'Set the view as the source for DataGridView 1 <br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view<br> <br> <span style="color:#008000">'Create a variable to store the index of <br> ' the row, if found <br> </span><span style="color:#0000ff">Dim</span> index <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer<br> <br> </span><span style="color:#008000">'Search for a row containing "Paola" in the <br> ' FirstName column, and "Rael" in the LastName <br> ' column. </span><br> index = view.Find(<span style="color:#0000ff">New</span> <span style="color:#0000ff">Object</span>() {<span style="color:#a31515">"Paola"</span>, <span style="color:#a31515">"Rael"</span>})<br> <br> <span style="color:#008000">'If it was found, then the value of index will <br> ' be greater than -1 <br> </span><span style="color:#0000ff">If</span> index > -1 <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'A match was found, so use the row index </span><br> <span style="color:#008000">' to set the current cell of DataGridView 1 </span><br> <span style="color:#0000ff">Me</span>.DataGridView1.CurrentCell = _<br> DataGridView1.Rows(index).Cells(1)<br> <br> <span style="color:#0000ff">Else</span><br> MsgBox(<span style="color:#a31515">"Match not found"</span>)<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p><u>Using the FindRows method</u></p> <p>The FindRows method can be used to return an array of rows that match the value(s), you are searching for.  This is useful when there may be multiple rows containing the same value(s).  </p> <p> </p> <p>If you’ve been looking at the data we’ve been using for demonstration, you’ll notice that there are two persons with the last name of “Rael”, they are “Paola” and “Anthony”.</p> <p> </p> <p>Let’s use the FindRows method to display rows that have a LastName of “Rael":</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d4a53b54-ea8d-4dee-bff5-0880efd0a8fa" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Get a reference to the table's <br> ' default DataView<br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Set the Sort to the name of the columns<br> ' that we want to search: The LastName <br> ' column</span><br> view.Sort = <span style="color:#a31515">"LastName"<br> <br> </span><span style="color:#008000">'Set the view as the source for DataGridView1<br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view<br> <br> <span style="color:#008000">'Create an array to store the rows found<br> </span><span style="color:#0000ff">Dim</span> rows <span style="color:#0000ff">As</span> DataRowView()<br> <br> <span style="color:#008000">'Search for all rows containing the<br> ' LastName of "Rael"</span><br> rows = view.FindRows(<span style="color:#a31515">"Rael"</span>)<br> <br> <span style="color:#008000">'Loop through each row in DataGridView1<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> _<br> <span style="color:#0000ff">Me</span>.DataGridView1.Rows.Count - 1<br> <br> <span style="color:#008000">'See if the row in the DataView that is </span><br> <span style="color:#008000">' bound to row in the grid is in the </span><br> <span style="color:#008000">' array of rows that were found.</span><br> <span style="color:#0000ff">If</span> rows.Contains( _<br> DataGridView1.Rows(i).DataBoundItem) <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'If it was, select it.</span><br> DataGridView1.Rows(i).Selected = <span style="color:#0000ff">True</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If<br> <br> Next</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Remember that, like the Find method, the FindRows method can search for multiple values that correspond the columns applied to the Sort property.</p> <p> </p> <p>So, let’s see an example of searching for rows that have a FirstName of “Paola” and a LastName of “Rael”:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2dff7d41-26bc-4254-91c5-f0263b3215af" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Get a reference to the table's <br> ' default DataView <br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Set the Sort to the name of the columns <br> ' that we want to search: The FirstName <br> ' column and the LastName column </span><br> view.Sort = <span style="color:#a31515">"FirstName, LastName"<br> <br> </span><span style="color:#008000">'Set the view as the source for DataGridView1 <br> </span><span style="color:#0000ff">Me</span>.DataGridView1.DataSource = view<br> <br> <span style="color:#008000">'Create an array to store the rows found <br> </span><span style="color:#0000ff">Dim</span> rows <span style="color:#0000ff">As</span> DataRowView()<br> <br> <span style="color:#008000">'Search for all rows containing the FirstName of<br> ' "Paola" and the LastName of "Rael" </span><br> rows = view.FindRows( _<br> <span style="color:#0000ff">New</span> <span style="color:#0000ff">Object</span>() {<span style="color:#a31515">"Paola"</span>, <span style="color:#a31515">"Rael"</span>})<br> <br> <span style="color:#008000">'Loop through each row in DataGridView1 <br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> _<br> <span style="color:#0000ff">Me</span>.DataGridView1.Rows.Count - 1<br> <br> <span style="color:#008000">'See if the row in the DataView that is </span><br> <span style="color:#008000">' bound to row in the grid is in the </span><br> <span style="color:#008000">' array of rows that were found. </span><br> <span style="color:#0000ff">If</span> rows.Contains( _<br> DataGridView1.Rows(i).DataBoundItem) <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'If it was, select it. </span><br> DataGridView1.Rows(i).Selected = <span style="color:#0000ff">True</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If<br> <br> Next</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Filtering…</h4> <p>Ok, so now we’ve learned how to Sort a DataView, and how to Search it using the Find and FindRows method.  Now we’re ready for filtering.</p> <p> </p> <p>Filtering is, in my opinion, one of the most useful features of a DataView.  It is very common to have a DataTable filled with records, and then filter a DataView so that a subset of the records can be displayed on a form for a user.</p> <p> </p> <p>There are, essentially, two filters that can be applied to a DataView, they are:  a RowFilter and a RowStateFilter.</p> <p> </p> <p>Let’s begin by looking at the RowFilter.</p> <p> </p> <p><u>Using the RowFilter</u></p> <p>Filtering rows in a DataView is as easy as setting the RowFilter property to an expression that is similar to an SQL WHERE clause.  You have to include the name of the column(s) you want to filter, and the value(s) you want to filter by.</p> <p> </p> <p>An important thing to keep in mind, is the type of data in the column you are filtering.  If a column contains data of a String data type, then be sure to enclose your criteria in single quotes (‘), if a column contains data of a Date data type, then be sure to enclose your criteria in a pound character (#), if your column contains data of a numeric data type, like Integer, then don’t use any enclosure.</p> <p> </p> <p>Here are some examples:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8a507c45-8f12-4f3c-bead-a29a5a2479b4" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Filter the View by FirstName='Gary'<br> </span><span style="color:#0000ff">Dim</span> criteria1 <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = <span style="color:#a31515">"Gary"</span><br> View.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"FirstName='{0}'"</span>, criteria1)<br> <br> <br> <span style="color:#008000">'Fiter the View by HireDate=#12/25/2008#<br> </span><span style="color:#0000ff">Dim</span> criteria2 <span style="color:#0000ff">As</span> <span style="color:#0000ff">Date</span> = #12/25/2008#<br> View.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"HireDate=#{0}#"</span>, criteria2)<br> <br> <br> <span style="color:#008000">'Filter the View by ID=3<br> </span><span style="color:#0000ff">Dim</span> criteria3 <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 3<br> View.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"ID={0}"</span>, criteria3)
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p><u></u></p> <p><u>Wild Cards</u></p> <p>The RowFilter property allows you to perform searches using wild cards at either the beginning or ending of a string search.  Either * or % can be used as a wild card.</p> <p> </p> <p>When you use a wild card character to perform a search, you must also use the LIKE keyword, instead of the equal (=) sign.</p> <p> </p> <p><em>As a note, wild card characters can only be used to search columns that have a String data type.</em></p> <p> </p> <p>Here are some examples of performing wild card searches:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:23c9344e-af6f-4b79-a4e3-416762d113cf" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <br> <span style="color:#008000">'Filter by FirstName column starting with<br> ' the letter A</span><br> view.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"FirstName LIKE '{0}'"</span>, <span style="color:#a31515">"A%"</span>)<br> <br> <br> <span style="color:#008000">'Filter by FirstName column that has the <br> ' letter A anywhere in it.</span><br> view.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"FirstName LIKE '{0}'"</span>, <span style="color:#a31515">"%A%"</span>)<br> <br> <br> <span style="color:#008000">'Filtery b FirstName column that ends with<br> ' the letter N</span><br> view.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"FirstName LIKE '{0}'"</span>, <span style="color:#a31515">"%N"</span>)
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Not only can simple searches be performed, as demonstrated above, but complex searches can be performed as well.  Complex searches use more search more than 1 column for matching criteria.</p> <p> </p> <p>When performing a complex search, use the AND or OR keywords.</p> <p> </p> <p>Here are some examples performing complex wild card searches:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:22e05197-0b78-4b44-9af3-813fa09ab263" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <br> <span style="color:#008000">'The filter syntax here is: <br> ' FirstName LIKE 'A%' AND LastName LIKE 'R%' </span><br> view.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"FirstName LIKE '{0}' AND "</span> & _<br> <span style="color:#a31515">"LastName LIKE '{1}'"</span>, _<br> <span style="color:#a31515">"A%"</span>, <span style="color:#a31515">"R%"</span>)<br> <br> <br> <span style="color:#008000">'The filter syntax here is: <br> ' FirstName LIKE '%M%' AND LastName LIKE "%B%' </span><br> view.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"FirstName LIKE '{0}' AND "</span> & _<br> <span style="color:#a31515">"LastName LIKE '{1}'"</span>, _<br> <span style="color:#a31515">"%M%"</span>, <span style="color:#a31515">"%B%"</span>)<br> <br> <br> <span style="color:#008000">'The filter syntax here is: <br> ' FirstName LIKE 'G%' OR FirstName LIKE 'P%' </span><br> view.RowFilter = _<br> <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"FirstName LIKE '{0}' OR "</span> & _<br> <span style="color:#a31515">"FirstName LIKE '{1}'"</span>, _<br> <span style="color:#a31515">"G%"</span>, <span style="color:#a31515">"P%"</span>)
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p><u>Using the RowStateFilter</u></p> <p></p> <p></p> <p></p> <p></p> <p>The RowStateFilter property allows you to filter a DataView by the state of the rows in the table.  For example, a new row that has just been added to the table has a RowState of “Added”; conversely, a row that has been deleted has a RowState of “Deleted”.  </p> <p> </p> <p>The RowStateFilter can be set to any of the following DataViewRowState enumerations:</p> <p> </p> <p>    -  Added:  Filter for Added rows</p> <p>    -  CurrentRows:  Filter for Non-deleted rows.  This is the default</p> <p>    -  Deleted:  Filter for deleted rows</p> <p>    -  ModifiedCurrent:  Filter for Modified rows, displaying the current values</p> <p>    -  ModifiedOriginal:  Filter for Modified rows, displaying the original values</p> <p>    -  None:  No rows are included</p> <blockquote> <p>    -  OriginalRows:  Filter for deleted, modified, and unmodified rows, </p> <p>       displaying the original values</p> <p>    -  Unchanged:  Filter for unmodified rows</p> </blockquote> <p> </p> <p> </p> <p><em>As a note both the RowFilter and RowStateFilter can be applied at the same time.</em></p> <p> </p> <p>So, here are some examples of using the RowStateFilter:</p> <p> </p> <p></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b11c7459-91d7-4bb1-a316-e527ef642aa1" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRowView = <span style="color:#0000ff">Nothing<br> <br> <br> </span><span style="color:#008000">'Add a new record</span><br> row = view.AddNew()<br> row.Item(<span style="color:#a31515">"FirstName"</span>) = <span style="color:#a31515">"Tom"</span><br> row.Item(<span style="color:#a31515">"LastName"</span>) = <span style="color:#a31515">"Messner"</span><br> row.Item(<span style="color:#a31515">"HireDate"</span>) = Today<br> row.EndEdit()<br> <br> <span style="color:#008000">'Modify a record</span><br> row = view(1)<br> row.Item(<span style="color:#a31515">"FirstName"</span>) = <span style="color:#a31515">"Modified"<br> <br> </span><span style="color:#008000">'Delete a record</span><br> row = view(5)<br> row.Delete()<br> <br> <br> <span style="color:#008000">'View all Added rows:</span><br> view.RowStateFilter = DataViewRowState.Added<br> <br> <span style="color:#008000">'View all Deleted rows:</span><br> view.RowStateFilter = DataViewRowState.Deleted<br> <br> <span style="color:#008000">'View all Modified rows</span><br> view.RowStateFilter = _<br> DataViewRowState.ModifiedCurrent<br> <br> <br> <span style="color:#008000">'View all current (non-deleted) rows<br> ' that start with the letter A</span><br> view.RowStateFilter = _<br> DataViewRowState.CurrentRows<br> <br> view.RowFilter = <span style="color:#a31515">"FirstName LIKE 'A%'"</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Iteration…</h4> <p>Now, we’ve seen how to use a DataView, how to sort it, how to search it, and how to filter it.  The next question is, how do you iterate through the DataView?</p> <p> </p> <p>There are times when you need to be able to loop through each row that is in the DataView so that you can perform a certain action, such as testing for a condition, or updating a value.  In those times, you can use <em>Iteration</em> or <em>Looping</em> to accomplish the task.</p> <p> </p> <p>Looping through a table is as easy as using the Do…Loop structure, starting at the first index, and continuing through the last.  Here’s an example of looping through all of the rows in a table:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:45a59128-baed-4cf5-b828-79d753add547" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Filter the view for only current <br> ' (non-deleted) rows</span><br> view.RowStateFilter = _<br> DataViewRowState.CurrentRows<br> <br> <br> <span style="color:#008000">'Declare the row as a DataRowView<br> ' (not a DataRow)<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRowView<br> <br> <br> <span style="color:#008000">'Loop through each row in the view<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> view.Count - 1<br> <br> <span style="color:#008000">'Get a reference to the row</span><br> row = view(i)<br> <br> <span style="color:#008000">'Perform an action </span><br> <span style="color:#008000">' (write to the Output window)</span><br> Console.WriteLine(row(<span style="color:#a31515">"FirstName"</span>))<br> <br> <span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>In addition to looping through each row in the view, you can also Iterate through each row using a For Each…Next structure, as follows:</p> <p> </p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6371ebdb-d939-428a-be74-1aa08d65fd8e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Filter the view for only current <br> ' (non-deleted) rows</span><br> view.RowStateFilter = _<br> DataViewRowState.CurrentRows<br> <br> <br> <span style="color:#008000">'Loop through each row in the view<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> row <span style="color:#0000ff">As</span> DataRowView <span style="color:#0000ff">In</span> view<br> <br> <span style="color:#008000">'Perform an action </span><br> <span style="color:#008000">' (write to the Output window)</span><br> Console.WriteLine(row(<span style="color:#a31515">"FirstName"</span>))<br> <br> <span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Getting Distinct Records…</h4> <p>We are almost to the end of our DataView discussion.  But before we finish, there’s one more tip I’d like to share with you.</p> <p> </p> <p>The DataView has the ability to output it’s contents to a new DataTable by using it’s ToTable method.  One nice feature of the ToTable method is that it is overloaded, and one overload allows you to specify the columns you want to output, and whether or not you want only distinct records copied to the table.  </p> <p> </p> <p><em>A Distinct record is determined by the columns you choose to copy to a new table, not whether every column in the row is an exact match.</em></p> <p> </p> <p>This is really worth knowing, because there are times when you may suspect there are duplicate rows in a DataTable.  The question will arise, how do I remove the duplicates?  This is how:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0a5eb56c-1e99-4ed1-ae0c-4d859c444b77" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new table with a Date Column<br> ' The default Data Type is String<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Add ID and Item columns</span><br> table.Columns.Add(<span style="color:#a31515">"ID"</span>)<br> table.Columns.Add(<span style="color:#a31515">"Item"</span>)<br> <br> <span style="color:#008000">'Add 3 rows of data<br> ' The ID is different for each row<br> ' The Item is the same</span><br> table.Rows.Add(1, <span style="color:#a31515">"Item1"</span>)<br> table.Rows.Add(2, <span style="color:#a31515">"Item1"</span>)<br> table.Rows.Add(3, <span style="color:#a31515">"Item1"</span>)<br> <br> <span style="color:#008000">'Get the default DataView of the table<br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Use the ToTable method to get Distinct<br> ' rows, removing duplicates.<br> </span><span style="color:#0000ff">Dim</span> distinctTable <span style="color:#0000ff">As</span> DataTable<br> distinctTable = view.ToTable(<span style="color:#0000ff">True</span>, <span style="color:#a31515">"Item"</span>)<br> <br> <span style="color:#0000ff">Me</span>.DataGridView1.DataSource = distinctTable
</p>
</div>
</div>
</div> <p><em> </em></p> <p><em>Note:  Because the Item column was the only column that was copied to the new table, the differences in the ID column were ignored, and only the Item column was evaluated for duplicates.</em></p> <p> </p> <p> </p> <h4>Summary</h4> <p>A DataView is the tool of choice, when it comes to viewing the data that is stored in a DataTable, and performing actions such as sorting, searching and filtering, and even grouping.  Plus, DataViews can be used in place of DataTables when performing DataBinding.</p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-30673762591445631112009-09-03T07:00:00.001-06:002009-09-03T09:11:29.321-06:00BackgroundWorker<p>BackgroundWorkers are pretty exciting, because they are one of the easiest classes to use, when it comes to running processor intensive operations on a separate dedicated thread.  <br /> <br />Many programmers that wouldn’t even begin to think about getting into multithreading, because of it’s complexities, can actually feel comfortable with the BackgroundWorker, and quickly begin to incorporate multithreading into their applications.  <br /> <br />Because the BackgroundWorker performs its operations on a separate dedicated thread, it prevents your application from freezing up, and becoming non-responsive while it waits for the operations to be completed.   <br /> <br /> </p> <h4>Simulation…</h4> <p>To begin with, let’s create a scenario that simulates intensive processing by calling the System.Threading.Thread.Sleep method, which will block the main thread, causing the application to freeze for 5 seconds.  <br /> <br />Create a new Visual Basic Windows Forms Application project, and name it WorkerDemo.  As soon as the project has been created, add a new TextBox to the form, and a new Button to the form (leave the button named Button1).  Mine looks like this:  <br />  <br /></p> <p><a href="http://lh4.ggpht.com/_dhkDWtu14Jc/Spb4v8E6KdI/AAAAAAAAAN4/uLVOCjGjZWU/s1600-h/form16.jpg"><img style="border-right-width: 0px; width: 253px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="form1" border="0" alt="form1" align="left" src="http://lh6.ggpht.com/_dhkDWtu14Jc/Spb4wWnmq-I/AAAAAAAAAN8/ka_6KTxEbmg/form1_thumb4.jpg?imgmax=800" width="253" height="117" /></a> </p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />Now, double-click the button to create the Button1_Click event handler, and insert a line of code calling the Sleep method, as follows:  <br /> </p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:829ef953-3a8c-43ba-a2f4-526db9158de8" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Form1<br> <br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button1.Click<br> <br> <span style="color:#008000">'Insert this line of code, calling </span><br> <span style="color:#008000">' the Sleep method. 5000 = 5 seconds. </span><br> System.Threading.Thread.Sleep(5000)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> <br /> <br />Next, run the program (press F5).  Then press the button, and try to enter text into the TextBox.  Can you do it?  Try moving the Form around.  Can you do it?  <br /> <br />If everything worked like it’s supposed to, your application should have froze, and you shouldn’t have been able to do anything for 5 seconds after clicking the button.    <br /> <br />Freezing, obviously, is not the type of behavior you expect from a program.  So let’s look at how we can use the BackgroundWorker to perform our simulated intensive processing operation on a separate dedicated thread. <br /> <br />But before we do, remove the line of code that we added to the Button1_Click event handler.  <br />  <br />  <br /></p> <h4>Getting Started…</h4> <p>To start working with the BackgroundWorker class, we need to create a new instance of it at the member (class) level, using the “WithEvents” keyword.  The “WithEvents” keyword causes the instance of the BackgroundWorker to be listed in the “Class Name” drop-down list at the top of the code window, and it’s methods to be listed in the “Method Name” drop-down list. <br /> <br /><em>Using the “WithEvents” keyword is not required to declare and work with the BackgroundWorker, but we will use it for this example. <br /> <br /></em>Before we make our declaration, add an Imports statement for the System.ComponentModel namespace above the Form1 class. <br /> <br />After importing the ComponentModel namespace, add the declaration for the BackgroundWorker at the top of the Form1 class. <br /> <br />Our code should now look like this:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:acb9a93f-b476-4bde-b918-a62cd73d42c8" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This Import Statement is for the BackgroundWorker <br> </span><span style="color:#0000ff">Imports</span> System.ComponentModel<br> <br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Form1<br> <br> <span style="color:#008000">'Create a new instance of the </span><br> <span style="color:#008000">' BackgrondWorker </span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">WithEvents</span> mWorker <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> BackgroundWorker()
</p>
</div>
</div>
</div> <p> <br /> <br />Now that we have declared our BackgroundWorker, go to the “Class Name” drop-down list at the top of the code window and select “mWorker”.  Then, select “DoWork” from the “Method Name” drop-down list.  This will create the mWorker_DoWork event handler.  Here’s an example: <br /> </p> <p><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/SpgPMFyVptI/AAAAAAAAAOA/ooXgumO3Efg/s1600-h/ClassNameDDL%5B12%5D.jpg"><img style="border-right-width: 0px; width: 440px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="ClassNameDDL" border="0" alt="ClassNameDDL" align="left" src="http://lh3.ggpht.com/_dhkDWtu14Jc/SpgPMiYURHI/AAAAAAAAAOE/e1Q7Le7jZZ4/ClassNameDDL_thumb%5B8%5D.jpg?imgmax=800" width="440" height="112" /></a> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p>If you performed the above step correctly, you should have a new method named “mWorker_DoWork”.  This method will be executed when the BackgroundWorker’s RunWorkerAsync() method is called.  And, it will execute on a separate dedicated thread. <br /> <br />So, the next thing we need to do is add some code to simulate some intensive processing.  Let’s use the same Sleep method that we used above, because we know that caused our form to freeze for 5 seconds last time. <br /> <br />And here you have it: <br /> </p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:158b1c4a-4096-43e2-836c-ee7e98c59956" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This Import Statement is for the BackgroundWorker<br> </span><span style="color:#0000ff">Imports</span> System.ComponentModel<br> <br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Form1<br> <br> <span style="color:#008000">'Create a new instance of the </span><br> <span style="color:#008000">' BackgrondWorker</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">WithEvents</span> mWorker <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> BackgroundWorker()<br> <br> <br> <span style="color:#008000">'This method is executed when </span><br> <span style="color:#008000">' mWorker.RunWorkerAsync is called.</span><br> <span style="color:#008000">' This method will execute on a separate </span><br> <span style="color:#008000">' thread.</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mWorker_DoWork( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.ComponentModel _<br> .DoWorkEventArgs) _<br> <span style="color:#0000ff">Handles</span> mWorker.DoWork<br> <br> <span style="color:#008000">'Sleep this thread for 5 seconds.</span><br> System.Threading.Thread.Sleep(5000)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> <br /> <br />Alright, the last thing we need to do is add the code that is necessary to get the BackgroundWorker running.  Since the BackgroundWorker’s RunWorkerAsync() is the method that starts the processing on a separate thread, we’ll insert that.  If you still have the Button1_Click method in your class, then add it there as follows: <br /> </p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:08fc0cd6-c252-4339-a164-56dec0b19a88" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This Import Statement is for the BackgroundWorker </span><br> <span style="color:#0000ff">Imports</span> System.ComponentModel<br> <br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Form1<br> <br> <span style="color:#008000">'Create a new instance of the </span><br> <span style="color:#008000">' BackgrondWorker </span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">WithEvents</span> mWorker <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> BackgroundWorker()<br> <br> <br> <span style="color:#008000">'This method is executed when </span><br> <span style="color:#008000">' mWorker.RunWorkerAsync is called. </span><br> <span style="color:#008000">' This method will execute on a separate </span><br> <span style="color:#008000">' thread. </span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mWorker_DoWork( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.ComponentModel _<br> .DoWorkEventArgs) _<br> <span style="color:#0000ff">Handles</span> mWorker.DoWork<br> <br> <span style="color:#008000">'Sleep this thread for 5 seconds. </span><br> System.Threading.Thread.Sleep(5000)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button1.Click<br> <br> <span style="color:#008000">'Calling this method causes the </span><br> <span style="color:#008000">' mWorker_DoWork event handler </span><br> <span style="color:#008000">' to be executed on a separate </span><br> <span style="color:#008000">' thread. </span><br> mWorker.RunWorkerAsync()<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> <br />Now that we have the BackgroundWorker all wired up, let’s test it out!  Start your program (F5)… <br /> <br />Can you enter any text into the TextBox?  Can you move the form around?  Absolutely you can!   <br /> <br />Congratulations!  You just learned how to implement multithreading into your application! <br />  <br />  <br /></p> <h4>Working with Arguments…</h4> <p>Ok…  It’s really cool to simulate some processing on a separate thread!  However, what we really need is a real-world example.  Because real-world applications do more meaningful things, like performing downloads and databases transactions. <br /> <br />For this real-world example, let’s retrieve a bunch of data from a database, and load it into a DataGridView for display. <br /> <br />You’re welcome to follow along with me, if you want.  I am going to use the SQL Server AdventureWorks database.  SQL Server Express or SQL Server 2005 is required to run it.  Here’s a link to an MSDN walkthrough: <br /> <br /><a href="http://msdn.microsoft.com/en-us/library/aa992075(VS.80).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/aa992075(VS.80).aspx</a></p> <p> <br />If you’re going to use a different database, then you’ll just have to make sure you have the connection string, the correct provider (OleDb, Odbc, etc.), the query syntax, and enough information to retrieve. <br /> <br />For this example, we will retrieve all of the names in the Contact table of the AdventureWorks database.  There are over 19,000 names in that table, so that should take a little bit of time to retrieve. <br /> <br />Since you already have your form set up, we’ll use that. <br /> <br />This time we’ll start with the Button1_Click method:  Create a string variable to store you SELECT statement in.  Then, pass the string variable as an argument of the RunWorkerAsync() method.   <br /> <br /><em>The RunWorkerAsync() method will actually start the BackgroundWorker on a separate thread, passing the SQL string as an argument. <br /></em> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7231d62d-aa78-4c33-9b62-7ec79136963d" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button1.Click<br> <br> <span style="color:#008000">'Select all of the first and last</span><br> <span style="color:#008000">' names from the Person.Contact</span><br> <span style="color:#008000">' database.</span><br> <span style="color:#0000ff">Dim</span> SQL <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = _<br> <span style="color:#a31515">"SELECT LastName, FirstName "</span> & _<br> <span style="color:#a31515">"FROM Person.Contact "</span> & _<br> <span style="color:#a31515">"ORDER BY LastName, FirstName ASC"</span><br> <br> <span style="color:#008000">'Calling this method causes the </span><br> <span style="color:#008000">' mWorker_DoWork event handler </span><br> <span style="color:#008000">' to be executed on a separate</span><br> <span style="color:#008000">' thread.</span><br> mWorker.RunWorkerAsync(SQL)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> <br /> <br />The next thing we need to do is go to the mWorker_DoWork method, and insert code to retrieve the data from the database.  Remember that this method will run on a separate thread. <br /> <br />The following steps needs to be taken: <br /> <br />     -  Retrieve the SQL string that was passed <br />     -  Create the connection string <br />     -  Create a table to store the data <br />     -  Create and configure a DataAdapter <br />     -  Fill the table using the DataAdapter <br />     -  Return the filled table to the main thread <br /> </p> <p>Here’s our example that accomplishes all of the above: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dcf09608-fb96-4a7f-82c2-efba37569790" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This method is executed when </span><br> <span style="color:#008000">' mWorker.RunWorkerAsync is called.</span><br> <span style="color:#008000">' This method will execute on a separate </span><br> <span style="color:#008000">' thread.</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mWorker_DoWork( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.ComponentModel _<br> .DoWorkEventArgs) _<br> <span style="color:#0000ff">Handles</span> mWorker.DoWork<br> <br> <br> <span style="color:#008000">'Retrieve the SQL string that we passed in</span><br> <span style="color:#0000ff">Dim</span> SQL <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = e.Argument<br> <br> <br> <span style="color:#008000">'Create the connection string</span><br> <span style="color:#0000ff">Dim</span> cnString <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = _<br> <span style="color:#a31515">"Data Source=localhost;"</span> & _<br> <span style="color:#a31515">"Initial Catalog=AdventureWorks;"</span> & _<br> <span style="color:#a31515">"Integrated Security=True;"</span><br> <br> <span style="color:#008000">'Create a table to store our data</span><br> <span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Create a SqlDataAdapter to retrieve the</span><br> <span style="color:#008000">' data from the AdventureWorks database.</span><br> <span style="color:#0000ff">Using</span> adapter <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> _<br> SqlClient.SqlDataAdapter(SQL, cnString)<br> <br> <span style="color:#008000">'Retrieve the data from the database</span><br> adapter.Fill(table)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Using</span><br> <br> <span style="color:#008000">'Return the filled table to the main thread</span><br> e.Result = table<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p></p> <p><em><strong> <br /> <br />Important Note!</strong>  The mWorker_DoWork method is being executed on a separate thread.  Therefore, it cannot directly access controls on the form, such as our DataGridView.  Attempting to do so will result in a cross-threading violation.  So instead of filling the DataGridView from within this method, we must pass the filled table back to the main thread using the e.Result property. <br /> <br /> <br /></em>The final thing we need to do is add the RunWorkerCompleted event handler to our code window.  This method is fired after the BackgroundWorker has completed it’s work.  Therefore, we can use this method to retrieve the filled table from the BackgroundWorker and set it as the DataSource of our DataGridView. <br /> <br />To do so, go to the “Class Name” drop-down list and select “mWorker”, then select “RunWorkerCompleted” from the “Method Name” drop-down list, as follows: <br /> </p> <p><a href="http://lh4.ggpht.com/_dhkDWtu14Jc/Sp_QPQebQGI/AAAAAAAAAP4/8-ZRtheEe3s/s1600-h/ClassNameDDL2.jpg"><img style="border-right-width: 0px; width: 444px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="ClassNameDDL2" border="0" alt="ClassNameDDL2" align="left" src="http://lh5.ggpht.com/_dhkDWtu14Jc/SpgPNUEfciI/AAAAAAAAAP8/u4sPjelAlrU/ClassNameDDL2_thumb.jpg?imgmax=800" width="440" height="112" /></a> </p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />Now that we have the mWorker_RunWorkerCompleted method added to our code window, let’s go to it and insert code to retrieve the filled table from the BackgroundWorker thread, and use it to fill a DataGridView. <br /> <br /><em>By the way, now’s a good time to go to your form design view, remove the TextBox, then add a DataGridView to the form, leaving it named “DataGridView1". <br /> <br /></em>Here’s an example: <br /> </p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4ace71b2-7b71-42fe-bfc1-826ab5fb3067" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This method is called when mWorker is done </span><br> <span style="color:#008000">' This method executes on main thread.</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mWorker_RunWorkerCompleted( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.ComponentModel _<br> .RunWorkerCompletedEventArgs) _<br> <span style="color:#0000ff">Handles</span> mWorker.RunWorkerCompleted<br> <br> <span style="color:#008000">'Retrieve the filled table from the </span><br> <span style="color:#008000">' BackgroundWorker</span><br> <span style="color:#008000">' thread.</span><br> <span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> DataTable = e.Result<br> <br> <span style="color:#008000">'Set the table as the DataSource for </span><br> <span style="color:#008000">' the DataGridView</span><br> <span style="color:#0000ff">Me</span>.DataGridView1.DataSource = table<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> <br /> <br />Now that we have all of the code added, let’s take a look at the full Form1 class to see what it looks like: <br /> </p> <div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bdc107e1-bcc4-433f-b9f0-25cae921f06a" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This Import Statement is for the BackgroundWorker </span><br> <span style="color:#0000ff">Imports</span> System.ComponentModel<br> <br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Form1<br> <br> <span style="color:#008000">'Create a new instance of the </span><br> <span style="color:#008000">' BackgrondWorker </span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">WithEvents</span> mWorker <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> BackgroundWorker()<br> <br> <br> <span style="color:#008000">'This method is executed when </span><br> <span style="color:#008000">' mWorker.RunWorkerAsync is called. </span><br> <span style="color:#008000">' This method will execute on a separate </span><br> <span style="color:#008000">' thread. </span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mWorker_DoWork( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.ComponentModel _<br> .DoWorkEventArgs) _<br> <span style="color:#0000ff">Handles</span> mWorker.DoWork<br> <br> <br> <span style="color:#008000">'Retrieve the SQL string that we passed in </span><br> <span style="color:#0000ff">Dim</span> SQL <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = e.Argument<br> <br> <br> <span style="color:#008000">'Create the connection string </span><br> <span style="color:#0000ff">Dim</span> cnString <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = _<br> <span style="color:#a31515">"Data Source=localhost;"</span> & _<br> <span style="color:#a31515">"Initial Catalog=AdventureWorks;"</span> & _<br> <span style="color:#a31515">"Integrated Security=True;"</span><br> <br> <span style="color:#008000">'Create a table to store our data </span><br> <span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Create a SqlDataAdapter to retrieve the </span><br> <span style="color:#008000">' data from the AdventureWorks database. </span><br> <span style="color:#0000ff">Using</span> adapter <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> _<br> SqlClient.SqlDataAdapter(SQL, cnString)<br> <br> <span style="color:#008000">'Retrieve the data from the database </span><br> adapter.Fill(table)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Using</span><br> <br> <span style="color:#008000">'Return the filled table to the main thread. </span><br> e.Result = table<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This method is called when mWorker is done </span><br> <span style="color:#008000">' This method executes on main thread. </span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> mWorker_RunWorkerCompleted( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.ComponentModel _<br> .RunWorkerCompletedEventArgs) _<br> <span style="color:#0000ff">Handles</span> mWorker.RunWorkerCompleted<br> <br> <span style="color:#008000">'Retrieve the filled table from the </span><br> <span style="color:#008000">' BackgroundWorker </span><br> <span style="color:#008000">' thread. </span><br> <span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> DataTable = e.Result<br> <br> <span style="color:#008000">'Set the table as the DataSource for </span><br> <span style="color:#008000">' the DataGridView </span><br> <span style="color:#0000ff">Me</span>.DataGridView1.DataSource = table<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button1.Click<br> <br> <span style="color:#008000">'Select all of the first and last </span><br> <span style="color:#008000">' names from the Person.Contact </span><br> <span style="color:#008000">' database. </span><br> <span style="color:#0000ff">Dim</span> SQL <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = _<br> <span style="color:#a31515">"SELECT LastName, FirstName "</span> & _<br> <span style="color:#a31515">"FROM Person.Contact "</span> & _<br> <span style="color:#a31515">"ORDER BY LastName, FirstName ASC"</span><br> <br> <span style="color:#008000">'Calling this method causes the </span><br> <span style="color:#008000">' mWorker_DoWork event handler </span><br> <span style="color:#008000">' to be executed on a separate </span><br> <span style="color:#008000">' thread. </span><br> mWorker.RunWorkerAsync(SQL)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> <br />Ok, so are you ready to run it?  Let’s give it a whirl.  Start your application (F5).  When the form comes up, press the button to fill the DataGridView. <br /> <br />You’ll notice that the form is completely responsive while the data is being retrieved on a separate thread using the BackGroundWorker.  The user is free to move the form around, and interact with <em>any </em>other controls that may be on the form. <br /> <br />Here’s what my form looked like after the data was retrieved: <br /> </p> <p><a href="http://lh4.ggpht.com/_dhkDWtu14Jc/SpgPNprxf0I/AAAAAAAAAOQ/mvhDNoCs4-o/s1600-h/form2%5B11%5D.jpg"><img style="border-right-width: 0px; width: 437px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="form2" border="0" alt="form2" align="left" src="http://lh4.ggpht.com/_dhkDWtu14Jc/SpgPOHpX3iI/AAAAAAAAAOU/IdZrIyYwU0w/form2_thumb%5B9%5D.jpg?imgmax=800" width="437" height="354" /></a> </p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /></p> <h4>Summary</h4> <p>The BackgroundWorker class in the System.ComponentModel namespace is very easy to use to perform processor intensive operations on a separate dedicated thread. <br /> <br />With very little knowledge of threading, you can begin to implement multi-threading into your applications, greatly enhancing their responsiveness during time-consuming operations. <br /> <br />For more information on the BackgroundWorker, please see the MSDN Documentation at <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx</a></p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-436405879836015072009-08-31T07:00:00.000-06:002009-08-31T07:00:01.153-06:00Anonymous Types<p>Typically, custom Classes are created to represent entities <em>(such as an Employee)</em>.  These classes can store information, and perform actions for their respective entity.  Structures are a lighter weight alternative to classes, and are used to define a composite value type.</p> <p> </p> <p>A possible example of a custom “Employee” class with an ID property and a Name property:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7df1d396-bf0f-4927-9ab3-de9e716f0e24" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Employee<br> <br> <span style="color:#008000">'Define the Employee ID</span><br> <span style="color:#0000ff">Private</span> mID <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Property</span> ID() <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span><br> <span style="color:#0000ff">Get</span><br> <span style="color:#0000ff">Return</span> mID<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Get</span><br> <span style="color:#0000ff">Set</span>(<span style="color:#0000ff">ByVal</span> value <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>)<br> mID = value<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Set</span><br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Property</span><br> <br> <span style="color:#008000">'Define the Employee Name</span><br> <span style="color:#0000ff">Private</span> mName <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Property</span> Name() <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span><br> <span style="color:#0000ff">Get</span><br> <span style="color:#0000ff">Return</span> mName<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Get</span><br> <span style="color:#0000ff">Set</span>(<span style="color:#0000ff">ByVal</span> value <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> mName = value<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Set</span><br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Property<br> <br> End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>To use the Employee class, you must create a new instance of it, then set the appropriate properties:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cb9396b6-6bbd-4089-b177-a17f11dfec24" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Dim</span> employee <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> Employee()<br> employee.ID = 1<br> employee.Name = <span style="color:#a31515">"Gary Lima"</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Object Initializers…</h4> <p>VB 2008 introduced a new feature called <strong>Object Intializers</strong>, which in essence, allows you to set property values when you create a new instance of your class, not using the class’ constructor.</p> <p> </p> <p>Object Initialization can only be used on classes that have constructors and support initialization with the “New” keyword.</p> <p> </p> <p>To use Object Initialization in code, you must use the new “With” keyword, beginning and ending curly braces “{}”, and provide the name of the property beginning with a period (“.”), plus the value you wish to set it to.</p> <p> </p> <p>Here’s an example of how Object Initialization is used to create a new instance of the Employee class, setting the ID and Name properties at the same time:</p> <p>  </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:df84d6a6-1440-438e-aea7-9ac9d42b5fcb" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Using Object Initialization to set<br> ' the ID and Name properties<br> </span><span style="color:#0000ff">Dim</span> employee <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> Employee() _<br> <span style="color:#0000ff">With</span> {.ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}
</p>
</div>
</div>
</div> <p><em></em></p> <p><em> </em></p> <p><em>Note:  Although the above examples appears to be 2 lines, it’s actually considered 1 line by the compiler, because the line continuation character (“_”) is used at the end of the first line.</em></p> <p> </p> <p> </p> <p></p> <p></p> <h4>Anonymous Types…</h4> <p>There may be times when you could use a light-weight class to store information for something like an Employee, but really don’t want to create an Employee Class or Structure.  Perhaps an Employee Class wouldn’t be needed anywhere else.  And you don’t need methods, events or any other custom functionality.  In times like these, you can consider using an Anonymous Type.</p> <p> </p> <p>Anonymous Types are, essentially, anonymous.  Not to insult your intelligence or anything…  Merriam-Webster’s online dictionary defines <a href="http://www.merriam-webster.com/dictionary/anonymous" target="_blank">anonymous</a> as “1:  Not named or identified”.  That’s a perfect description, because when you declare an Anonymous Type, you don’t <em>name or identify</em> it’s type.  Not specifying the type is actually using <em>implicit typing</em>, which allows the compiler to determine the type of the variable based off of the initialization value.  </p> <p> </p> <p>In the case of an Anonymous Type, the compiler will actually generate a class for you, that has no usable name and is not directly accessible from code.  The class will automatically have all of the properties that were defined in the <u>required</u> Object Initialization syntax.</p> <p> </p> <p>For example, let’s look at declaring an Anonymous Type for an employee:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7f56c5d2-717a-403b-b705-9775e8b87c18" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'An Anonymous Type (no type declared)<br> ' Notice "As Employee" is missing.<br> </span><span style="color:#0000ff">Dim</span> employee = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {.ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}
</p>
</div>
</div>
</div> <p> </p> <p>So some points about the example above:</p> <p> </p> <p>     -  No type was declared (“As Employee” not used)</p> <p>     -  The Equal Sign (“=”) was used</p> <p>     -  The “New” keyword was used</p> <p>     -  The “With” keyword was used</p> <p>     -  Curly Braces were used “{}”</p> <p>     -  The properties were specified using a period “.” (.ID, .Name) </p> <p>     -  The properties were initialized to the specified values.</p> <p>     -  The properties were separated by a comma (“,”)</p> <p> </p> <p> </p> <p>Once an Anonymous Type has been created, accessing the properties is just like accessing the properties of any ordinary class.  An example using the “employee” from above:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ff9ee000-7119-44d2-be51-bdc4bcf6d7dc" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Displays "1 Gary Lima"</span><br> MsgBox(employee.ID & <span style="color:#a31515">" "</span> & employee.Name)
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Additionally, the property values can be modified, just like the property values of any ordinary class can be modified.  For example:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f402f46a-f176-4faa-aff5-871542be48cd" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> employee.ID = 2<br> employee.Name = <span style="color:#a31515">"VBRocks"<br> <br> </span><span style="color:#008000">'Displays "2 VBRocks"</span><br> MsgBox(employee.ID & <span style="color:#a31515">" "</span> & employee.Name)
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p><strong>Key Properties</strong></p> <p>It is possible to define a property as being a “Key” property.  Key properties are different than regular properties, because they are read-only, the values of Key properties are used for equality comparison, and they are included in the hash code algorithm (which we’ll see later).</p> <p> </p> <p>Let’s revisit the “employee” example above, and this time use the “Key” keyword to define the “ID” property as a Key property:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d146df0f-7ec5-41e8-90de-bd073327bd2c" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'An Anonymous Type (no type declared)<br> ' The ID property is a "Key" property<br> </span><span style="color:#0000ff">Dim</span> employee = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Now that we have an employee Anonymous Type created with the “ID” property as a “Key” property, let’s take a look at using it in code:</p> <p></p> <p></p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:da6d658b-3593-4684-afe9-a3e7916276b8" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Error: Can't set the ID, because it's a Key<br> ' property. Trying to will generate a <br> ' compiler error<br> 'employee.ID = 2<br> <br> 'Ok to change the name</span><br> employee.Name = <span style="color:#a31515">"VBRocks"<br> <br> </span><span style="color:#008000">'Displays "1 VBRocks"</span><br> MsgBox(employee.ID & <span style="color:#a31515">" "</span> & employee.Name)
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Just as a note, any property can be defined as a Key property.  Furthermore, you can define as many properties as you want as Key properties.  For example:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:61ab40e4-ae10-402a-8b97-4e4233dc8da4" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'The ID property is a "Key" property<br> ' The Name property is a "Key" property<br> </span><span style="color:#0000ff">Dim</span> employee = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, <span style="color:#0000ff">Key</span> .Name = <span style="color:#a31515">"Gary Lima"</span>}
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p><strong>Inheritance</strong></p> <p>Anonymous Types are directly derived from System.Object.  Because this is true, there are 5 methods that it inherits:  Equals, GetHashCode, GetType, ReferenceEquals, and ToString.</p> <p> </p> <p>If an Anonymous Type contains at least 1 Key property then Equals, GetHashCode and ToString are overridden.  If an Anonymous Type contains no Key properties, then only ToString is overridden.</p> <p> </p> <p> </p> <p><strong>Equals</strong></p> <p>Anonymous Types that have at least 1 Key property defined implement the System.IEquatable(T) interface, which means the .Equal method can be used to determine equality of instances.</p> <p> </p> <p>There are some important things to understand before attempting to use the .Equal method to test equality of Anonymous Types.  Instances of an Anonymous Type are considered equal if:</p> <p> </p> <p>     -  They are declared in the same assembly</p> <p>     -  They have the same properties, same inferred types, and same order</p> <p>     -  They have the same Key properties</p> <p>     -  They have at least 1 Key property</p> <p> </p> <p>So having considered that, let’s take a look at some examples of testing equality.</p> <p> </p> <p>This example returns <u>False</u> (Not Equal), because there is no Key property for each Anonymous Type:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bf7d1701-df41-4d3e-99e1-ec250e13f7f7" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'No Key property<br> </span><span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {.ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'No Key property<br> </span><span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {.ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'Displays "False"</span><br> MsgBox(employee1.Equals(employee2)) </p>
</div>
</div>
</div> <p> </p> <p> </p> <p>This example returns <u>False</u> (Not Equal), because both Anonymous Types do not have the same Key property defined, (only 1 does):</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:50931c98-fd65-494a-a56e-08ef5656356a" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'No Key property<br> </span><span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {.ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'Displays "False"</span><br> MsgBox(employee1.Equals(employee2)) </p>
</div>
</div>
</div> <p> </p> <p> </p> <p></p> <p>This example returns <u>True</u> (Equal), because both Anonymous Types have the same Key property defined, and they are set to the same value.</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:14f249ff-990a-4af7-80a9-0de4b5d3de18" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'Displays "True"</span><br> MsgBox(employee1.Equals(employee2)) </p>
</div>
</div>
</div> <p> </p> <p> </p> <p>This example returns <u>False</u> (Not Equal), because both Anonymous Types do not have the same value for each Key property:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3a65b460-48fc-43c8-ad59-d948f4137475" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 2, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'Displays "True"</span><br> MsgBox(employee1.Equals(employee2)) </p>
</div>
</div>
</div> <p> </p> <p> </p> <p>This example returns <u>True</u> (Equal), because both Anonymous Types have the same Key properties set to the same value, even though the Name is different:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ec3ea0ce-809b-468c-971c-39e8272ed1d0" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"VBRocks"</span>}<br> <br> <span style="color:#008000">'Displays "True"</span><br> MsgBox(employee1.Equals(employee2)) </p>
</div>
</div>
</div> <p> </p> <p> </p> <p>This example returns False (Not Equal), because both Anonymous Types do not have the exact same <em>initializer</em> list of properties:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:621ae622-a618-429e-93ab-1dc9086a01be" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'Key property: ID<br> </span><span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>, _<br> .Department = 1}<br> <br> <span style="color:#008000">'Displays "False"</span><br> MsgBox(employee1.Equals(employee2)) </p>
</div>
</div>
</div> <p> </p> <p> </p> <p><strong>GetHashCode</strong></p> <p>Anonymous Types that do not have a Key property defined return a hash code computation specific to each type, and based on 1 or more of the values of each property.  </p> <p> </p> <p>Therefore, Anonymous Types with no Key property defined <u>will never</u> produce a hash code that matches another Anonymous Type, even if they both have all of the same properties, the same inferred types, and are in the same order.</p> <p> </p> <p>So for example:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9bd4d49c-f730-40fe-b189-2ff84b979409" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'No Key property<br> </span><span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {.ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'No Key property<br> </span><span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {.ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <br> <span style="color:#008000">'employee1.GetHashCode() = 31914638<br> 'employee2.GetHashCode() = 18796293</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Anonymous Types that have 1 or more Key properties defined return a hash code computation specific to each type, and based on the value of each Key property.</p> <p> </p> <p>Therefore, Anonymous Types with a Key property defined <u>will</u> produce a hash code that matches another Anonymous Type that has all of the same properties, the same inferred types, are in the same order, and have the same Key properties that have the same values.</p> <p> </p> <p>So for example:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4e6a605c-f851-49f3-9e66-48db7d0f6b63" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'ID Key property<br> </span><span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'ID Key property<br> </span><span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"VBRocks"</span>}<br> <br> <br> <span style="color:#008000">'employee1.GetHashCode() = -286022222<br> 'employee2.GetHashCode() = -286022222</span>
</p>
</div>
</div>
</div> <p><em></em></p> <p><em> </em></p> <p><em>Remember, that the example above produces identical hash codes, because it is only using Key property values to compute it’s code.  Additionally, both Anonymous Types are Equal, because they have the same Key property values.</em></p> <p> </p> <p> </p> <p><strong>ToString</strong></p> <p>The ToString method is the simplest of the overridden methods, returning a string comprised of each property/value pair, enclosed in curly braces “{}”, as you can see:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ce1f4141-f48b-4da6-aba8-d565b9205549" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Dim</span> employee1 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {<span style="color:#0000ff">Key</span> .ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#0000ff">Dim</span> employee2 = <span style="color:#0000ff">New</span> _<br> <span style="color:#0000ff">With</span> {.ID = 1, .Name = <span style="color:#a31515">"Gary Lima"</span>}<br> <br> <span style="color:#008000">'employee1.ToString() = <br> ' "{ ID = 1, Name = Gary Lima }"<br> <br> 'employee2.ToString() = <br> ' "{ ID = 1, Name = Gary Lima }"</span>
</p>
</div>
</div>
</div> <p> </p> <p></p> <p></p> <p></p> <p></p> <p></p> <p><em>Notice there was no difference in the ToString output, even though employee1 has a Key property.</em></p> <p> </p> <p> </p> <h4>Anonymous Types and LINQ…</h4> <p>Although you may find Anonymous Types interesting and useful, they are realistically not the method of choice to work with entity data.  Standard object oriented programming practices lead to defining entities using Classes, while Interfaces and Structures can be defined and used when and where necessary.</p> <p> </p> <p>The true purpose of Anonymous Types is to support Language-Integrated Query (LINQ).  To this end, they are a perfect match.</p> <p> </p> <p>In a nutshell, LINQ is a structured query language that allows a programmer to write queries against strongly typed collections of objects using Visual Basic keywords and operators.</p> <p> </p> <p>The result of a LINQ query is returned as an Anonymous Type, because the type of the result cannot be defined in advance.  So, the compiler creates a data type matching the properties and their order.</p> <p> </p> <p>Unfortunately, we’re going to keep the introduction to LINQ brief here, but explain just enough to help you understand how Anonymous Types are used with LINQ.</p> <p> </p> <p>Therefore, to assist with this example:  The LINQ query syntax is similar to standard SQL syntax.  In its most basic sense, it says:  SELECT * FROM collection.  In SQL, the <em>collection</em> is usually a table, but in VB it’s a collection of objects.  The syntax is just a little different in VB, because in order for LINQ to support Intellisense, it has to know what type it’s working with.  So in VB the equivalent syntax is:  FROM collection SELECT *.</p> <p> </p> <p>Now that you have a grasp on that…  let’s look at some examples.  (And if your eyes are rolling, and you’re thinking “yeah, right…”, don’t worry about it.  You can get into LINQ later.  The important thing to realize is that it uses Anonymous Types).</p> <p> </p> <p>Let’s start by creating a list of Employees that we can work with in following examples.  The Employees class was the very first example given at the very top of this article.</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f384540a-ff07-4b9a-a16a-5f730c197d08" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new list of Employees<br> </span><span style="color:#0000ff">Dim</span> listOfEmployees <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> List(<span style="color:#0000ff">Of</span> Employee)<br> <br> <span style="color:#008000">'Add 20 employees to our list<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 1 <span style="color:#0000ff">To</span> 20<br> <br> <span style="color:#008000">'Add an Employee to the list</span><br> listOfEmployees.Add( _<br> <span style="color:#0000ff">New</span> Employee _<br> <span style="color:#0000ff">With</span> { _<br> .ID = i, _<br> .Name = <span style="color:#a31515">"Employee "</span> & i})<br> <br> <span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> </p> <p></p> <p> </p> <p>Next, let’s use LINQ to query the “listOfEmployees”:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:39fbd29e-a5ea-450d-a3ff-82c4c8f5c886" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This LINQ query is saying:<br> ' SELECT ID, Name FROM listOfEmployees <br> </span><span style="color:#0000ff">Dim</span> employees = _<br> <span style="color:#0000ff">From</span> emp <span style="color:#0000ff">In</span> listOfEmployees _<br> <span style="color:#0000ff">Select</span> emp.ID, emp.Name
</p>
</div>
</div>
</div> <p> </p> <p><em>At this point, the “employees” variable is holding the definition of the query only, not the actual result, because the query has not been executed yet.</em></p> <p> </p> <p>Notice that the “employees” variable in the example above does not have a type defined.  If you were to check the type by using “employees.GetType.Name”, you would find it contains a list iterator.</p> <p> </p> <p> </p> <p>Now, let’s look at the execution of the LINQ query, and output the results to the Output Window.  </p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2400b221-9f04-4e8c-aa44-714683b604f0" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Execute the query, and iterate through<br> ' the result<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> emp <span style="color:#0000ff">In</span> employees<br> <br> <span style="color:#008000">'emp is an Anonymous Type here</span><br> Console.WriteLine(<span style="color:#a31515">"{0,-2} {1}"</span>, _<br> emp.ID, emp.Name)<br> <br> <span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> </p> <p><em>It’s important to understand the the “emp” variable in the For Each structure is an Anonymous Type.  If we attempted to declare “emp” using “As Employee”, the compiler would have generated an error.</em></p> <p></p> <p> </p> <p> </p> <p>Ok, one final example before wrapping things up:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:97917688-b923-443c-9594-db1723080019" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This LINQ query is saying:<br> ' SELECT ID, Name FROM listOfEmployees <br> ' WHERE ID <= 10<br> </span><span style="color:#0000ff">Dim</span> employees = _<br> <span style="color:#0000ff">From</span> emp <span style="color:#0000ff">In</span> listOfEmployees _<br> <span style="color:#0000ff">Where</span> emp.ID <= 10 _<br> <span style="color:#0000ff">Select</span> emp.ID, emp.Name<br> <br> <br> <span style="color:#008000">'Execute the query, and iterate through<br> ' the result<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> emp <span style="color:#0000ff">In</span> employees<br> <br> <span style="color:#008000">'emp is an Anonymous Type here</span><br> Console.WriteLine(<span style="color:#a31515">"{0,-2} {1,-15} {2}"</span>, _<br> emp.ID, emp.Name, emp.GetType.Name)<br> <br> <span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> </p> <p><em>Notice that this time, the Name of the type was written to the Output window.  Further examination will reveal that it is an anonymous type.</em></p> <p><em> </em></p> <p><em> </em></p> <h4>Summary</h4> <p>As you have seen, Anonymous Types enable a programmer to create objects without writing a class definition or structure for the data type, allowing the compiler to generate the class.  The class that the compiler generates has no usable name, and is not directly accessible in code.</p> <p> </p> <p>Once an Anonymous Type has been created, it can be referenced just like any ordinary class.  Non-Key properties can be read and written to, while Key properties can only be read once they’ve been set.  Key properties are also used for equality comparisons and hash code generation.</p> <p> </p> <p>Finally, Anonymous Types were designed primarily to support LINQ, because the type of the query result cannot be determined in advance.</p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-29831028667958155442009-08-24T09:30:00.000-06:002009-08-25T11:52:51.523-06:00Extension Methods<p>Extension Methods are a very cool and very innovative idea, new in Visual Studio 2008 (.NET Framework 3.5), that allows programmers to add custom methods to data types <em>(without creating a derived type)</em> that can be called just as if they were programmed within the type itself.</p> <p> </p> <p>Whether it’s a class, structure, interface, delegate, etc. it can be extended, without inheritance, enabling it to gain new functionality, without actually having to be updated itself.</p> <p> </p> <p>Imagine being able to add new functionality to the String data type so that it could change the case of it’s contents to Proper Case, maybe something like String.ToProper(); or imagine being able to add new functionality to the Integer data type so that it could raise it’s contents to a specified power, maybe something like Integer.ToPower(2);  or imagine being able to add new functionality to the DataTable data type so that when the Copy method is called, you could tell it exactly what columns of data you want copied, maybe something like DataTable.Copy(“Column1”, “Column2”), etc.  With Extension methods it’s now possible!  And one of the coolest things is, it’s easy.</p> <p> </p> <p> </p> <h4>Rules…</h4> <p>There are a some rules to consider before actually diving into working with Extension Methods, and they are:  </p> <p> </p> <p>1.  An Extension Method can only be a Sub Procedure or a Function, not a property, field or event.</p> <p> </p> <p>2.  An Extension Method must be marked with the <Extension()> attribute, located in the System.Runtime.CompilerServices namespace.</p> <p> </p> <p>3.  An Extension Method must have at least 1 parameter.  This parameter is always the first parameter (when there are more than 1 parameter) that indicates the type that it is extending.  Additionally, this parameter is used to pass in the instance <em>(ByVal or ByRef)</em> of the data type it is extending.</p> <p> </p> <p>4.  Extension Methods must be defined within a Module.</p> <p> </p> <p> </p> <h4>Getting Started…</h4> <p>Ok, so are you ready to see how this works?  Let’s go…</p> <p> </p> <p>First, create a new Windows Forms project.  Next, add a new Module to it, named “ExtensionMethods.”  After the module has been added, Import the System.Runtime.CompilerServices namespace.  Your Module should now look like this:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4d01d3ec-afba-45d5-95ac-965e7d5ab080" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Imports</span> System.Runtime.CompilerServices<br> <br> <span style="color:#0000ff">Module</span> ExtensionMethods<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Module</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p><u>String.ToProper()</u></p> <p>Now we’re ready to add an Extension Method.  Let’s extend the String data type, and add a new method to it that will change it’s contents to Proper Case:</p> <p> </p> <p><em>Remember that the Extension Method must be marked with <Extension()>, and the first parameter indicates what type is being extended.</em></p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:18312788-e0cc-4cd1-84ee-735b28b3b39a" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Imports</span> System.Runtime.CompilerServices<br> <br> <span style="color:#0000ff">Module</span> ExtensionMethods<br> <br> <span style="color:#008000">'Add the <Extension()> attribute.</span><br> <span style="color:#008000">' 1st parameter indicates the type to extend</span><br> <span style="color:#008000">' (which is the String data type)</span><br> <Extension()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> ToProper(<span style="color:#0000ff">ByVal</span> str <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>) _<br> <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span><br> <br> <span style="color:#008000">'"str" passes in the contents of the type</span><br> <span style="color:#008000">' it is extending.</span><br> <span style="color:#0000ff">Return</span> StrConv(str, VbStrConv.ProperCase)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function<br> <br> End</span> <span style="color:#0000ff">Module</span>
</p>
</div>
</div>
</div> <p> </p> <p><em>Reminder:  Not only does the first parameter indicate what type is being extended, it is also used to pass in the instance (ByVal or ByRef) of the data type it is extending. </em></p> <p><em> </em></p> <p><em> </em></p> <p><em></em></p> <p><em></em></p> <p><em></em></p> <p><em></em></p> <p><em></em></p> <p><em></em></p> <p><u>Integer.ToPower()</u></p> <p>Ok, so that’s one Extension Method.  Let’s add another one, this time extending the Integer data type by adding a new method to it that will raise it’s value to the specified power:</p> <p></p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ca376fc3-90c8-476b-95ac-2c68123686ea" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Extend the Integer data type to raise it's </span><br> <span style="color:#008000">' contents to the specified power</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' 1st parameter indicates the type to extend</span><br> <span style="color:#008000">' 2nd parameter indicates the power</span><br> <Extension()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> ToPower(<span style="color:#0000ff">ByVal</span> int <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>, _<br> <span style="color:#0000ff">ByVal</span> power <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>) <span style="color:#0000ff">As</span> <span style="color:#0000ff">Double</span><br> <br> <span style="color:#0000ff">Return</span> Math.Pow(int, power)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span>
</p>
</div>
</div>
</div> <p> </p> <p><em>Note that the return value is a Double.  This is because the return value could be greater than an Integer, and the Math.Pow method returns a Double data type.</em></p> <p> </p> <p> </p> <p><u>DataTable.Copy()</u></p> <p>Let’s add one more Extension Method.  This time we will extend the DataTable data type by adding a new Copy method that will copy the contents of the DataTable to a new DataTable using the specified column names.</p> <p> </p> <p><em>Method Overloading:  You may realize that the DataTable type already has a Copy() method that copies the contents of the DataTable to a new DataTable.  By adding a new Copy method that takes a parameter array of column names, we will actually be overloading the Copy method.  This is permissible, because it has a different (parameter) signature.  </em></p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ee12fa27-f068-4afe-b069-54a7c794fd5f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Extend the DataTable data type to Copy it's</span><br> <span style="color:#008000">' contents to a new DataTable, but only </span><br> <span style="color:#008000">' copying the specifed columns</span><br> <Extension()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> Copy( _<br> <span style="color:#0000ff">ByVal</span> table <span style="color:#0000ff">As</span> DataTable, _<br> <span style="color:#0000ff">ByVal</span> <span style="color:#0000ff">ParamArray</span> columnNames <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>()) _<br> <span style="color:#0000ff">As</span> DataTable<br> <br> <span style="color:#0000ff">Return</span> table.DefaultView _<br> .ToTable(<span style="color:#0000ff">False</span>, columnNames)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span>
</p>
</div>
</div>
</div> <p>  <br /> </p> <p><u>Complete ExtensionMethods Module Example</u></p> <p>Now that we have our 3 Extension Methods in our new ExtensionMethods Module, let’s take a look at what the module looks like:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:52bbe173-4c89-481e-b7b8-b75d2364b1f2" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Imports</span> System.Runtime.CompilerServices<br> <br> <span style="color:#0000ff">Module</span> ExtensionMethods<br> <br> <span style="color:#008000">'Add the <Extension()> attribute.</span><br> <span style="color:#008000">' 1st parameter indicates the type to extend</span><br> <span style="color:#008000">' (which is the String data type)</span><br> <Extension()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> ToProper(<span style="color:#0000ff">ByVal</span> str <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>) _<br> <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span><br> <br> <span style="color:#008000">'"str" passes in the contents of the type</span><br> <span style="color:#008000">' it is extending.</span><br> <span style="color:#0000ff">Return</span> StrConv(str, VbStrConv.ProperCase)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span><br> <br> <br> <span style="color:#008000">'Extend the Integer data type to raise it's </span><br> <span style="color:#008000">' contents to the specified power</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' 1st parameter indicates the type to extend</span><br> <span style="color:#008000">' 2nd parameter indicates the power</span><br> <Extension()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> ToPower(<span style="color:#0000ff">ByVal</span> int <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>, _<br> <span style="color:#0000ff">ByVal</span> power <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>) <span style="color:#0000ff">As</span> <span style="color:#0000ff">Double</span><br> <br> <span style="color:#0000ff">Return</span> Math.Pow(int, power)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span><br> <br> <br> <span style="color:#008000">'Extend the DataTable data type to Copy it's</span><br> <span style="color:#008000">' contents to a new DataTable, but only </span><br> <span style="color:#008000">' copying the specifed columns</span><br> <Extension()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> Copy( _<br> <span style="color:#0000ff">ByVal</span> table <span style="color:#0000ff">As</span> DataTable, _<br> <span style="color:#0000ff">ByVal</span> <span style="color:#0000ff">ParamArray</span> columnNames <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>()) _<br> <span style="color:#0000ff">As</span> DataTable<br> <br> <span style="color:#0000ff">Return</span> table.DefaultView _<br> .ToTable(<span style="color:#0000ff">False</span>, columnNames)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function<br> <br> End</span> <span style="color:#0000ff">Module</span>
</p>
</div>
</div>
</div> <p>  <br /></p> <h4>Testing it out…</h4> <p>Now that we have our Extension Methods defined, let’s test them out.</p> <p> </p> <p>Go back to the form, add a button to it, then double-click the button to create the Button_Click event handler.  Test out the Extension Methods following my example below:</p> <p> </p> <p></p> <p></p> <p></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9057705a-f050-45e2-a067-809b534c909c" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button1.Click<br> <br> <br> <span style="color:#008000">'Test our String Extension Method</span><br> <span style="color:#0000ff">Dim</span> str <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = <span style="color:#a31515">"hello world!"</span><br> <br> <span style="color:#008000">'Displays "Hello World!"</span><br> Console.WriteLine(str.ToProper())<br> <br> <br> <span style="color:#008000">'Test our Integer Extension Method</span><br> <span style="color:#0000ff">Dim</span> int <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 2<br> <br> <span style="color:#008000">'Displays "4"</span><br> Console.WriteLine(int.ToPower(2))<br> <br> <br> <span style="color:#008000">'Test our DataTable Extension Method</span><br> <span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table.Columns.Add(<span style="color:#a31515">"ID"</span>)<br> table.Columns.Add(<span style="color:#a31515">"Item"</span>)<br> table.Columns.Add(<span style="color:#a31515">"ItemDescription"</span>)<br> <br> <span style="color:#008000">'Add 10 rows of data</span><br> <span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 1 <span style="color:#0000ff">To</span> 10<br> <br> table.Rows.Add(i, _<br> <span style="color:#a31515">"Item "</span> & i, _<br> i & <span style="color:#a31515">" Item Description"</span>)<br> <br> <span style="color:#0000ff">Next</span><br> <br> <br> <span style="color:#008000">'Copy the DataTable, but only copy</span><br> <span style="color:#008000">' the "Item" column, not the "ID" or</span><br> <span style="color:#008000">' "ItemDescription" columns</span><br> <span style="color:#0000ff">Dim</span> copiedTable <span style="color:#0000ff">As</span> DataTable = _<br> table.Copy(<span style="color:#a31515">"Item"</span>)<br> <br> <br> <span style="color:#008000">'Loop through the rows in our copiedTable</span><br> <span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> row <span style="color:#0000ff">As</span> DataRow <span style="color:#0000ff">In</span> _<br> copiedTable.Rows<br> <br> <span style="color:#008000">'Ouput each column value</span><br> <span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> col <span style="color:#0000ff">As</span> DataColumn <span style="color:#0000ff">In</span> _<br> copiedTable.Columns<br> <br> Console.WriteLine(row(col))<br> <br> <span style="color:#0000ff">Next</span><br> <br> <span style="color:#0000ff">Next</span><br> <br> <br> <span style="color:#008000">'Displays only the contents of the "Item"</span><br> <span style="color:#008000">' column</span><br> <br> <br> <span style="color:#008000">'View Output Windows for results</span><br> <span style="color:#0000ff">Stop<br> <br> <br> End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>In the background…</h4> <p>If you were to look into the background and find out how the compiler is calling the extension methods, you would find that the compiler simply calls the <em>shared</em> method of the module, and passes it the variable calling the method.  So the compiler’s version below is equivalent to our example above, producing the exact same results:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:03769fa3-13bd-4ecb-8fcd-bb8e65c9bf37" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'String.ToProper()</span><br> Console.WriteLine( _<br> ExtensionMethods.ToProper(str))<br> <br> <span style="color:#008000">'Integer.ToPower(2)</span><br> Console.WriteLine( _<br> ExtensionMethods.ToPower(int, 2))<br> <br> <span style="color:#008000">'DataTable.Copy("Item")</span><br> <span style="color:#0000ff">Dim</span> copiedTable <span style="color:#0000ff">As</span> DataTable = _<br> ExtensionMethods.Copy(table, <span style="color:#a31515">"Item"</span>)
</p>
</div>
</div>
</div> <p> </p> <p>This information is useful, because if you choose to, you can utilize this pattern for calling the ExtensionMethods.  Additionally, in rare situations where ambiguity occurs, this pattern will resolve conflicts.</p> <p> </p> <p> </p> <h4>Extending Interfaces…</h4> <p>As mentioned, interfaces can be extended as well as classes, structures and delegates, etc.  But extending interfaces is a little different, because instead of only defining the Extension Method, you have to actually <u>implement it</u>.  And if you are familiar at all with interfaces, immediately you’ll realize that is quite a bit different than the nature of interface types, which do not provide implementation.</p> <p> </p> <p>Let’s take a look at an example of an IMath interface, and a ToPower() Extension Method:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9a5216ba-b703-4d25-b3ad-aa9188595898" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Imports</span> System.Runtime.CompilerServices<br> <br> <br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Interface</span> IMath<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Interface<br> <br> <br> Module</span> ExtensionMethods<br> <br> <span style="color:#008000">'Extends the IMath interface,</span><br> <span style="color:#008000">' with Implementation.</span><br> <Extension()> _<br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Function</span> ToPower(<span style="color:#0000ff">ByVal</span> im <span style="color:#0000ff">As</span> IMath, _<br> <span style="color:#0000ff">ByVal</span> int <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>, _<br> <span style="color:#0000ff">ByVal</span> power <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>) _<br> <span style="color:#0000ff">As</span> <span style="color:#0000ff">Double</span><br> <br> <span style="color:#0000ff">Return</span> Math.Pow(int, power)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function<br> <br> End</span> <span style="color:#0000ff">Module</span>
</p>
</div>
</div>
</div> <p> </p> <p>And surprisingly enough, here’s how this example can be used in code:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5b73a949-8664-48f7-af5b-35ac2c2e1102" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button1.Click<br> <br> <br> <span style="color:#0000ff">Dim</span> im <span style="color:#0000ff">As</span> IMath<br> <br> <span style="color:#008000">'Displays "4"</span><br> MsgBox(im.ToPower(2, 2))<br> <br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Importing…</h4> <p>If you put the module containing your Extension Methods in a namespace, then you will need to import that namespace in order to be able to access the Extension Methods.  That’s something to keep in mind, because if you try to access one of your Extension Methods through a type instance, and cannot find your Extension Method listed in Intellisense, that’s the reason.</p> <p> </p> <p>Additionally, if you decide to create a library containing all of your Extension Methods, when you add it as a reference to another project, be sure to import the namespace as well.</p> <p> </p> <p> </p> <h4>Summary</h4> <p>Extension Methods allows custom methods to be added to data types.  The custom methods can only be Sub Procedures or Function, not properties, fields or events; they must be placed in a module; they must be marked with the System.Runtime.CompilerServices.Extension attribute; and they must have at least 1 parameter (the first parameter) that indicates the type that is being extended.</p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-87577901985320835512009-08-24T09:00:00.000-06:002009-08-24T09:00:02.135-06:00ADO.NET: SqlBulkCopy<p>There are times in a programmers life when you need to find a way to insert a lot of data into a SQL Server database table as fast as possible, and you’re not concerned about constraints being enforced or triggers being fired.  If that’s your forte, then you’ve come to the right place.</p> <p> </p> <p>SQL Server’s Bulk Copy Protocol has been around for a long time.  It has a significant performance advantage over other methods, because SQL Server basically just inserts the data into a table, bypassing many SQL Server operations.</p> <p> </p> <p>The SqlBulkCopy class, in the System.Data.SqlClient namespace, was introduced with ADO.NET 2.0, and was designed to make working with SQL Server’s Bulk Copy feature easy.  So having said that, let’s take a look at how it works.</p> <p> </p> <p>To begin with, create a new SQL Server Database named “Test”.  Add a new table to the database named “Items”.  Add a “ItemCode” column, of “int” data type; add a “ItemDesc” column, of “varchar(20)” data type.</p> <p> </p> <p>Once you have the SQL Server Database created, with a “Test” table in place, you’re ready to work with the code below.</p> <p> </p> <p>And just for fun, let’s throw in a StopWatch so we can see how long it takes to perform the insert!</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:606ae405-aa6c-471d-93c2-4ca5dbe20927" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a table, add columns and name<br> ' them the same as they are in the <br> ' database table they are updating<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table.Columns.Add(<span style="color:#a31515">"ItemCode"</span>)<br> table.Columns.Add(<span style="color:#a31515">"ItemDesc"</span>)<br> <br> <br> <span style="color:#008000">'Load the table with 100,000 rows!<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 1 <span style="color:#0000ff">To</span> 100000<br> table.Rows.Add(i, <span style="color:#a31515">"Item "</span> & i) : <span style="color:#0000ff">Next<br> <br> <br> </span><span style="color:#008000">'Create a new StopWatch to measure the<br> ' amount of time it takes to perform the<br> ' insert<br> </span><span style="color:#0000ff">Dim</span> swatch <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> Stopwatch()<br> swatch.Start()<br> <br> <br> <span style="color:#008000">'Configure the connection string<br> </span><span style="color:#0000ff">Dim</span> cnString <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = _<br> <span style="color:#a31515">"Data Source=localhost;"</span> & _<br> <span style="color:#a31515">"Initial Catalog=Test;"</span> & _<br> <span style="color:#a31515">"Integrated Security=True;"<br> <br> </span><span style="color:#008000">'Create a new SqlBulkCopy class<br> </span><span style="color:#0000ff">Dim</span> bcp <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> SqlClient.SqlBulkCopy(cnString, _<br> SqlClient.SqlBulkCopyOptions.KeepNulls)<br> <br> <span style="color:#008000">'You MUST specifiy the table you are going to fill</span><br> bcp.DestinationTableName = <span style="color:#a31515">"Items"<br> <br> </span><span style="color:#008000">'Increase the timeout to a more appropriate time<br> ' for the amount of data your are inserting.<br> ' The default is 30 seconds</span><br> bcp.BulkCopyTimeout = 60<br> <br> <span style="color:#008000">'Write the data to the SQL Server Database table</span><br> bcp.WriteToServer(table)<br> <br> <span style="color:#008000">'Close the instance</span><br> bcp.Close()<br> <br> <span style="color:#008000">'Stop the Stopwatch!</span><br> swatch.Stop()<br> <br> MsgBox(<span style="color:#a31515">"Done! Elapsed Milliseconds: "</span> & _<br> swatch.ElapsedMilliseconds) </p>
</div>
</div>
</div> <p> </p> <p><strong>Some things to note:</strong></p> <p>The SqlBulkCopy class constructor is overloaded, so it can take just a connection string; a connection string and SqlBulkCopyOptions; just a SqlConnection; or a SqlConnection, SqlBulkCopyOptions, and a SqlTransaction (which enables a roll back if necessary).</p> <p> </p> <p>The SqlBulkCopy class’ WriteToServer method is also overloaded, so it can take rows from a DataRow() array, a DataTable or a DataReader.</p> <p> </p> <p>The fasted SqlBulkCopyOptions is “KeepNulls”, because the default column values in the table are ignored.  The “Default” option inserts rows, filling in default column values where necessary.</p> <p> </p> <p>For more information, see <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx">SqlBulkCopy on MSDN</a>.</p> <p> </p> <p> </p> <h4>Summary</h4> <p>The System.Data.SqlClient.SqlBulkCopy class can be used to quickly and efficiently insert rows from a DataRow() array, DataTable or DataReader directly into a SQL Table, bypassing many SQL Server operations.  </p> <p> </p> <p>Because the SqlBulkCopy class has a significant performance advantage over other methods, it makes it the insert method of choice when you need fast, direct inserting of data into a SQL Table.</p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-35719147036329648292009-08-24T08:17:00.000-06:002009-08-24T08:17:00.571-06:00Delegates<p>If you are comfortable working with methods (Sub Procedures and Functions) in Visual Basic, then you should have no problem understanding the concept of Delegates. <br /> <br />Delegates are basically pointers to methods that have the exact same signature (<em>or “shape”</em>) as the method they point to.  They are strongly-typed, and can be invoked (<em>or “called”</em>) at any time.  Delegates can point to 1 method, or multiple methods, and can be invoked either synchronously or asynchronously. <br /> <br />In the .NET Framework, there are many place where Delegates are used.  Examples include generic lists (System.Collections.Generic.List(Of Type)) which have Sort and Find methods that use them, every Event uses a Delegate (for example, a “button_click()” event), and the new LINQ architecture uses them extensively. <br /> <br />There are three pieces of information that are maintained by a Delegate, and they are:  The <u>address</u> (or name) of the method they are pointing to, the <u>arguments</u> that are passed to the method, and the <u>return type</u> of the method (if there is one). <br /> <br />To create a Delegate, you must declare it at the Member (class) level, using the Delegate Keyword.  Additionally, you must specify whether the Delegate is going to point to a Sub Procedure or a Function.  Just like any variable, you can name the Delegate whatever you want. And as mentioned, you must define the signature of the Delegate (including parameters and return type). <br /> <br />Here’s an introductory example of creating a Delegate that will point to a Sub Procedure with no parameters:</p> <p> </p> <blockquote> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dc82dead-4f16-43fb-bed6-caa7ea075a8a" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Sub</span> PrintHelloWorldDelegate()
</p>
</div>
</div>
</div> <p> <br />As mentioned, this Delegate can be used to point to any Sub Procedure that has no arguments.  Here is an example:</p> </blockquote> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9d1b371b-547b-4f16-b4f7-e0cc97a5eb1e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> PrintHelloWorld()<br> <br> Console.WriteLine(<span style="color:#a31515">"Hello World!"</span>)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> </p> <p><em>As a note, the method that the delegate is pointing to does not have to have the same (or similar) name as the delegate, and the delegate can point to <u>any</u> method that has the exact same signature as the delegate (which is a Sub Procedure with no arguments in this case).</em> <br /> <br />To use a Delegate, you have to create a variable that is of the delegate type, which in this case is the “PrintHelloWorldDelegate” delegate type, and tell it what method it is going to “point to”.  To demonstrate this, we will add a new method called “Print”, which will be called to perform the printing.</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:86220c4d-cde4-4273-b70c-8b6f0eebb4f6" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This sub will be called to print "Hello World!"<br> </span><span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> Print()<br> <br> <span style="color:#008000">'Declare the "printDelegate" variable as the </span><br> <span style="color:#008000">' PrintHelloWorldDelegate type.</span><br> <span style="color:#008000">' This means that the printDelegate variable </span><br> <span style="color:#008000">' will point to a Sub Procedure that has no </span><br> <span style="color:#008000">' arguments, no return type</span><br> <span style="color:#0000ff">Dim</span> printDelegate <span style="color:#0000ff">As</span> PrintHelloWorldDelegate<br> <br> <span style="color:#008000">'Create a new instance of the Delegate, and</span><br> <span style="color:#008000">' assign it the address of the </span><br> <span style="color:#008000">' "PrintHelloWorld" Sub Procedure.</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' Basically, we are telling the "printDelegate" </span><br> <span style="color:#008000">' variable to call the "PrintHelloWorld" Sub</span><br> <span style="color:#008000">' Procedure when it is invoked.</span><br> printDelegate = <span style="color:#0000ff">New</span> PrintHelloWorldDelegate( _<br> <span style="color:#0000ff">AddressOf</span> PrintHelloWorld)<br> <br> <span style="color:#008000">'Now, we can invoke (call) the "PrintHelloWorld"</span><br> <span style="color:#008000">' Sub Procedure that the delegate points to.</span><br> printDelegate()<br> <br> <span style="color:#008000">'Invoking the delegate produces the exact same</span><br> <span style="color:#008000">' result as if we called the Sub Procedure</span><br> <span style="color:#008000">' explicitly.</span><br> PrintHelloWorld()<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> </p> <p></p> <p>The complete class now looks like this:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:36c62b2a-3477-4e29-a2f3-dd7e8e7ede1b" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> WorkingWithDelegates<br> <br> <span style="color:#008000">'Declare a Delegate at the member (class) level</span><br> <span style="color:#008000">' that will point to a Sub Procedure,</span><br> <span style="color:#008000">' and that has no parameters, no return type</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Sub</span> PrintHelloWorldDelegate()<br> <br> <span style="color:#008000">'This is the Sub Procedure that the Delegate</span><br> <span style="color:#008000">' will point to (it doesn't point to it yet)</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> PrintHelloWorld()<br> <br> <span style="color:#008000">'Print to the Output Window</span><br> Console.WriteLine(<span style="color:#a31515">"Hello World!"</span>)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This sub will be called to print "Hello World!"</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> Print()<br> <br> <span style="color:#008000">'Declare the "printDelegate" variable as </span><br> <span style="color:#008000">' the PrintHelloWorldDelegate type.</span><br> <span style="color:#008000">' This means that the printDelegate </span><br> <span style="color:#008000">' variable will point to a Sub Procedure</span><br> <span style="color:#008000">' that has no arguments, no return type</span><br> <span style="color:#0000ff">Dim</span> printDelegate <span style="color:#0000ff">As</span> PrintHelloWorldDelegate<br> <br> <span style="color:#008000">'Create a new instance of the Delegate, </span><br> <span style="color:#008000">' and assign it the address of the </span><br> <span style="color:#008000">' "PrintHelloWorld" Sub Procedure.</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' Basically, we are telling the </span><br> <span style="color:#008000">' "printDelegate" variable to call the </span><br> <span style="color:#008000">' "PrintHelloWorld" Sub Procedure when it</span><br> <span style="color:#008000">' is invoked.</span><br> printDelegate = _<br> <span style="color:#0000ff">New</span> PrintHelloWorldDelegate( _<br> <span style="color:#0000ff">AddressOf</span> PrintHelloWorld)<br> <br> <span style="color:#008000">'Now we can invoke (call) the </span><br> <span style="color:#008000">' "PrintHelloWorld" Sub Procedure that</span><br> <span style="color:#008000">' the delegate points to.</span><br> printDelegate()<br> <br> <span style="color:#008000">'Invoking the delegate produces the exact</span><br> <span style="color:#008000">' same result as if we called the Sub</span><br> <span style="color:#008000">' Procedure explicitly.</span><br> PrintHelloWorld()<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub<br> <br> End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Delegates with Parameters</h4> <p> </p> <p>As mentioned, Delegates can point to methods that have parameters.  But in order for Delegates to be able to point to methods that have parameters, they must be declared with the exact same list of parameters that the method they are going to point to has. </p> <p> </p> <p>As an example, here is a delegate that will point to a Sub Procedure that has 1 String parameter:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dcdf26d3-1403-488e-8a09-6ef5ed1b36c6" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a Delegate that will point to a Sub <br> ' Procedure that has 1 String parameter.<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Sub</span> _<br> PrintStringDelegate(<span style="color:#0000ff">ByVal</span> text <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <span style="color:#008000">'The PrintStringDelegate above can be used <br> ' to point to a Sub Procedure like this:<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> PrintString(<span style="color:#0000ff">ByVal</span> text <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <span style="color:#008000">'Print to Output Window</span><br> Console.WriteLine(text)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> </p> <p>To use PrintStringDelegate in the example above, we need to create a variable of the PrintStringDelegate type, and assign it the address of the PrintString Sub Procedure, then invoke (call) it.</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8eb4e901-58ee-4630-826c-ccab7ce5781b" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new instance of the PrintStringDelegate<br> ' and tell it to "point to" the PrintString <br> ' Sub Procedure<br> </span><span style="color:#0000ff">Dim</span> printStrDelegate <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> PrintStringDelegate(<span style="color:#0000ff">AddressOf</span> PrintString)<br> <br> <span style="color:#008000">'Invoke (call) the "PrintString" Sub Procedure<br> ' that the delegate points to.</span><br> printStrDelegate(<span style="color:#a31515">"Hello World!"</span>)
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Here is another example of a delegate that will point to a Sub Procedure that has 1 Integer parameter:</p> <p> </p> <p></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:89eb2bdd-57a0-4433-9707-8a819fa7a02f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a Delegate that will point to a Sub<br> ' Procedure that has 1 Integer parameter<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Sub</span> _<br> PrintNumberDelegate(<span style="color:#0000ff">ByVal</span> number <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>)<br> <br> <span style="color:#008000">'The PrintNumberDelegate above can be used to point <br> ' to a Sub Procedure like this:<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> PrintNumber(<span style="color:#0000ff">ByVal</span> number <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>)<br> <br> <span style="color:#008000">'Print to Output Window</span><br> Console.WriteLine(number)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p></p> <p></p> <p></p> <p> </p> <p>And again, an example of how to invoke (call) it:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e3ae1d17-3782-4ce7-8079-1073f68a774c" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new instance of the printIntDelegate<br> ' and tell it to "point to" the PrintNumber <br> ' Sub Procedure<br> </span><span style="color:#0000ff">Dim</span> printIntDelegate <span style="color:#0000ff">As</span> _<br> <span style="color:#0000ff">New</span> PrintStringDelegate(<span style="color:#0000ff">AddressOf</span> PrintNumber)<br> <br> <span style="color:#008000">'Invoke (call) the "PrintString" Sub Procedure<br> ' that the delegate points to.</span><br> printIntDelegate(123) </p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Remember that Delegates can take any number of parameters, they are not just limited to 1.  So let’s take a look at a Delegate that has multiple parameters: </p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ac7bbfc0-744b-4908-a0a3-65bd3de1ed8e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a Delegate that will point to a Sub<br> ' Procedure with 3 arguments<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Sub</span> PrintNameDelegate( _<br> <span style="color:#0000ff">ByVal</span> firstName <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>, _<br> <span style="color:#0000ff">ByVal</span> lastName <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>, _<br> <span style="color:#0000ff">ByVal</span> website <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <br> <span style="color:#008000">'The PrintNameDelegate above can be used to point<br> ' to a Sub like this:<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> PrintName(<span style="color:#0000ff">ByVal</span> firstName <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>, _<br> <span style="color:#0000ff">ByVal</span> lastName <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>, _<br> <span style="color:#0000ff">ByVal</span> website <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <span style="color:#008000">'Print to Output Window</span><br> Console.WriteLine(<span style="color:#a31515">"{0} {1}"</span>, _<br> firstName, lastName)<br> <br> Console.WriteLine(<span style="color:#a31515">"blog: {0}"</span>, website)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> </p> <p>And again, here’s an example of how to invoke (call) it:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2bfcec0a-469d-4a69-ab26-749e81dda9ea" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new instance of the PrintNameDelegate<br> ' and tell it to "point to" the PrintName <br> ' Sub Procedure<br> </span><span style="color:#0000ff">Dim</span> printDelegate <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> _<br> PrintNameDelegate(<span style="color:#0000ff">AddressOf</span> PrintName)<br> <br> <span style="color:#008000">'Invoke (call) the PrintName Sub Procedure that<br> ' the printDelegate is pointing to.</span><br> printDelegate(<span style="color:#a31515">"Gary"</span>, <span style="color:#a31515">"Lima"</span>, _<br> <span style="color:#a31515">"http://garylima.blogspot.com/"</span>)
</p>
</div>
</div>
</div> <p></p> <p> </p> <p>So all that is pretty simple?  Ok, let’s take a look at working with Delegates that have return types.</p> <p> </p> <p> </p> <h4>Delegates with Parameters and Return Types</h4> <p> </p> <p>So far we’ve been working with Delegates that do not have Return Types.  These Delegates have been declared using the “Sub” keyword.  To create a Delegate that has a Return Type, use the “Function” keyword instead.  And, just like a function, add the Return Type at the end of the declaration.</p> <p> </p> <p>Here’s an example of a delegate that will point to a Function that will add 2 Integers together and return an Integer as a result:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:10203f22-869e-4093-b979-cb5c0e0c03d6" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a Delegate that will point to a Function<br> ' that takes 2 Integer arguments, and returns<br> ' an Integer<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Function</span> AddDelegate( _<br> <span style="color:#0000ff">ByVal</span> x <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>, <span style="color:#0000ff">ByVal</span> y <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>) _<br> <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer<br> <br> </span><span style="color:#008000">'The AddDelegate above can be used to point to<br> ' a Function like this:<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Function</span> Add(<span style="color:#0000ff">ByVal</span> x <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>, _<br> <span style="color:#0000ff">ByVal</span> y <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>) <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span><br> <br> <span style="color:#008000">'Add x + y and return the value</span><br> <span style="color:#0000ff">Return</span> x + y<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span>
</p>
</div>
</div>
</div> <p> </p> <p>And here’s an example of how to invoke it:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:99b7d92e-86ce-4445-bc53-ba02a8ed427b" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new instance of the AddDelegate<br> ' and tell it to "point to" the Add Function<br> </span><span style="color:#0000ff">Dim</span> adDelegate <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> AddDelegate(<span style="color:#0000ff">AddressOf</span> Add)<br> <br> <span style="color:#008000">'Invoke the Add Function that the AddDelegate<br> ' points to, and get the result<br> </span><span style="color:#0000ff">Dim</span> result <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span><br> result = adDelegate(2, 2)<br> <br> <span style="color:#008000">'Print to Output Window</span><br> Console.WriteLine(<span style="color:#a31515">"The result is {0}"</span>, result)
</p>
</div>
</div>
</div> <p> </p> <p><em>Remember that a Function Delegate does not have to have parameters, but it does have to have a Return Type.  The parameters do not have to be of the same type as each other, or as the Return Type.</em></p> <p> </p> <p>Ok, so now that we’ve had a chance to look at Delegates, including their parameters and return types, let’s take a look at some examples of using Delegates.</p> <p> </p> <p> </p> <h4>Event Handling with Delegates</h4> <p> </p> <p>The .NET Framework has a generic collection list class called “List(Of Type)” that can be used to store any type of object.  Although the list is <em>generic</em>, it is a <u>strongly-typed</u> list that will only store objects of the declared type.  So, if you declare your list as “List(Of String)” the list will only store Strings, if you declare you list as “List(Of Integer)” the list will only store Integers, and so on.</p> <p> </p> <p>Because this type of collection list is so useful for storing objects, it makes it a perfect candidate for inheritance.  A derived class can be created, and programmed with a Delegate to provide “call back” event notification to let the caller receive feedback on the status of items that have been added to the list.</p> <p> </p> <p>The concept of a “call back” delegate is pretty simple.  In the easiest since, think of when you send someone an email.  When you send the email to them, your email address is included in the email.  Then, when they have read the email, (at their convenience) they reply and use the email address to send an email message back to you.</p> <p> </p> <p>Another example, think of the Button.Click event (which we’ll see an example of later).  When the button is clicked, something needs to tell the compiler what “call back” method is supposed to be called (e.g. the “Button1_Click” Sub Procedure): That something is a Delegate.</p> <p> </p> <p>So here’s an example where the “List(Of Type)” class is inherited by the “MyList(Of T)” class.  We will add a Delegate to the class to provide call back event notification when a new item is added to the list:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c751450c-9163-4ede-a761-c9d85c65c5fd" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a New List Class that Inherits the <br> ' List(Of T) class (The "T" stands for the<br> ' Type to be specified when the list is <br> ' declared)<br> </span><span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> MyList(<span style="color:#0000ff">Of</span> T)<br> <span style="color:#0000ff">Inherits</span> List(<span style="color:#0000ff">Of</span> T)<br> <br> <span style="color:#008000">'Create a "Call Back" Delegate to provide </span><br> <span style="color:#008000">' feedback when an item has been aded to</span><br> <span style="color:#008000">' the list</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Sub</span> _<br> ItemAddedDelegate(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <br> <span style="color:#008000">'Create a private, internal variable that </span><br> <span style="color:#008000">' will store a reference to the </span><br> <span style="color:#008000">' "Call Back" ItemAddedDelegate</span><br> <span style="color:#0000ff">Private</span> AddedDelegate <span style="color:#0000ff">As</span> ItemAddedDelegate<br> <br> <br> <span style="color:#008000">'This method is used by the Caller to set </span><br> <span style="color:#008000">' the "Call Back" Delegate that will be </span><br> <span style="color:#008000">' Invoked when a new item is added to the </span><br> <span style="color:#008000">' list</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> OnItemAdded( _<br> <span style="color:#0000ff">ByVal</span> method <span style="color:#0000ff">As</span> ItemAddedDelegate)<br> <br> <span style="color:#008000">'Set the "Call Back" delegate with the </span><br> <span style="color:#008000">' delegate passed in</span><br> AddedDelegate = method<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This is the method being called to add </span><br> <span style="color:#008000">' items to the list</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Shadows</span> <span style="color:#0000ff">Sub</span> Add(<span style="color:#0000ff">ByVal</span> item <span style="color:#0000ff">As</span> T)<br> <br> <span style="color:#008000">'Check to see if the item is already</span><br> <span style="color:#008000">' in the list</span><br> <span style="color:#0000ff">If</span> <span style="color:#0000ff">Me</span>.Contains(item) <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'It's in the list, so invoke the </span><br> <span style="color:#008000">' "Call Back" Delegate and pass </span><br> <span style="color:#008000">' the response</span><br> AddedDelegate(item.ToString() & _<br> <span style="color:#a31515">" not added, because it's"</span> & _<br> <span style="color:#a31515">" already in the list"</span>)<br> <br> <span style="color:#0000ff">Else</span><br> <br> <span style="color:#008000">'It's not in the list, so add the</span><br> <span style="color:#008000">' item to the base class list</span><br> <span style="color:#008000">' (this prevents a recursive call</span><br> <span style="color:#008000">' the this Add method)</span><br> <span style="color:#0000ff">MyBase</span>.Add(item)<br> <br> <span style="color:#008000">' Then invoke the "Call Back" </span><br> <span style="color:#008000">' Delegate and pass the response.</span><br> AddedDelegate(item.ToString() & _<br> <span style="color:#a31515">" added to list"</span>)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub<br> <br> End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> </p> <p>So, having looked at all of that, let’s see how it works from the caller’s end:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:805b702f-1013-49a6-8713-a21f612ef79b" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Form1<br> <br> <span style="color:#008000">'This is the "call back" method that gets</span><br> <span style="color:#008000">' called when the button is clicked.</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button1.Click<br> <br> <br> <span style="color:#008000">'Create a new instance of our list</span><br> <span style="color:#008000">' and set the Type (T) to Integer</span><br> <span style="color:#0000ff">Dim</span> list <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> MyList(<span style="color:#0000ff">Of</span> <span style="color:#0000ff">Integer</span>)<br> <br> <span style="color:#008000">'Use "AddressOf" to create a new delegate</span><br> <span style="color:#008000">' that points to the "OnItemAdded" method.</span><br> list.OnItemAdded(<span style="color:#0000ff">AddressOf</span> OnItemAdded)<br> <br> <span style="color:#008000">'Add items to the list</span><br> list.Add(1)<br> list.Add(2)<br> list.Add(3)<br> list.Add(3)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This is the "Call Back" method that is being</span><br> <span style="color:#008000">' called when the delegate is invoked.</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> OnItemAdded(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <span style="color:#008000">'Print the response to the Output Window</span><br> Console.WriteLine(msg)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub<br> <br> End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> </p> <p><em>Hopefully that’s easy to understand!  If it doesn’t make since, then create a new Windows Forms project, add a Button to Form1, then go to the Form1 code window, highlight all of the code and delete it.  Then, copy the code for the Form1 class from the example above and paste it into the code window.  Finally, copy the code from the “MyList(Of T)” class and paste it after the Form1’s “End Class” keywords.  Run the project and click the button to see the results.  If you can set a breakpoint on the “list.Add(1)” line of code, then click the button, program execution will be halted at that line, then you can “step-into” (F11 in VS 10) the method and see how the delegate works.</em></p> <p> </p> <p>And if you made it through that example ok, then you’re ready for some more advanced examples…</p> <p> </p> <p> </p> <h4>Examples of using Delegates in .NET</h4> <p> </p> <p>There are many classes in the .NET framework that use Delegates.  However, it may not always be obvious that a Delegate is being used.  </p> <p> </p> <p>One plain give-away that a delegate is being used is that the “<u>AddressOf</u>” keyword is used.  When used in a Delegate constructor, the “AddressOf” <em>operator </em>assigns the specified method address to the Delegate.  When the “AddressOf” <em>statement</em> is used in context, the type of the delegate is determined by the compiler, and an instance of a delegate is created for you.</p> <p> </p> <p>Having said that, let’s take a look at the generic List(Of Type) class that is located in System.Collections.Generic namespace.  There are 2 methods that we can look at:  The <u>Sort</u> method, which takes a System.Comparison(Of Type) delegate; and the <u>Find</u> method, which takes a System.Predicate(Of Type) delegate.</p> <p> </p> <p>Because the List(Of Type) is a generic list, it literally can hold anything, once the Type has been specified.  For example, a List(Of String) can store a list of strings, a List(Of Integer) can store a list of integers, a List(Of TextBox) can store a list of TextBoxes, a List(Of Form) can store a list of Forms, and so on.  Because the list can store any type, the list wouldn’t have the ability to sort the items in the list, or search for items in the list, because it wouldn’t know how.  Therefore, methods such as the Sort and Find method must be programmatically defined.  And that’s where delegates come in!</p> <p> </p> <p>Here’s a Sorting Delegate Example:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:42aeb897-dfd0-44b9-ab35-0c6b64dbe2f3" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new list of Integers<br> </span><span style="color:#0000ff">Dim</span> list <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> List(<span style="color:#0000ff">Of</span> <span style="color:#0000ff">Integer</span>)<br> <br> <span style="color:#008000">'Add 10 numbers to the list in reverse order <br> ' (10, 9, 8...)<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 10 <span style="color:#0000ff">To</span> 1 <span style="color:#0000ff">Step</span> -1<br> list.Add(i) : <span style="color:#0000ff">Next<br> <br> <br> </span><span style="color:#008000">'Create a System.Comparison delegate<br> </span><span style="color:#0000ff">Dim</span> sortListDelegate <span style="color:#0000ff">As</span> _<br> System.Comparison(<span style="color:#0000ff">Of</span> <span style="color:#0000ff">Integer</span>)<br> <br> <span style="color:#008000">'Use "AddressOf" to create the delegate and <br> ' assign the address of the SortList method</span><br> sortListDelegate = <span style="color:#0000ff">AddressOf</span> SortList<br> <br> <span style="color:#008000">'Call the Sort method of the list and pass <br> ' the sortListDelegate to it. The "SortList"<br> ' Function will be used to sort the <br> ' Integers in the list.</span><br> list.Sort(sortListDelegate)<br> <br> <span style="color:#008000">'Now that the list is sorted, print the <br> ' contents of the list to the Output Window<br> ' for verification<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> list.Count - 1<br> Console.WriteLine(list(i)) : <span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> </p> <p>Here’s the “SortList” method being called by the “sortListDelegate” delegate:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:983bccfa-ded1-48d6-811d-fbc035c983af" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This method is being used to sort the list.<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Function</span> SortList(<span style="color:#0000ff">ByVal</span> x <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>, _<br> <span style="color:#0000ff">ByVal</span> y <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>) <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span><br> <br> <span style="color:#0000ff">Return</span> x.CompareTo(y)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>Here’s a Find Delegate Example:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5fa975c9-85b9-4e7e-81fd-3bcc83c2be82" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new list of Integers<br> </span><span style="color:#0000ff">Dim</span> list <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> List(<span style="color:#0000ff">Of</span> <span style="color:#0000ff">Integer</span>)<br> <br> <span style="color:#008000">'Add 10 numbers to the list <br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 1 <span style="color:#0000ff">To</span> 10<br> list.Add(i) : <span style="color:#0000ff">Next<br> <br> <br> </span><span style="color:#008000">'Create a System.Predicate(Of Type) delegate<br> </span><span style="color:#0000ff">Dim</span> findDelegate <span style="color:#0000ff">As</span> System.Predicate(<span style="color:#0000ff">Of</span> <span style="color:#0000ff">Integer</span>)<br> <br> <span style="color:#008000">'Use "AddressOf" to create the delegate and <br> ' assign the address of the FindInList method.</span><br> findDelegate = <span style="color:#0000ff">AddressOf</span> FindInList<br> <br> <span style="color:#008000">'Call the Find method of the list and pass<br> ' the findDelegate to it. The "FindInList"<br> ' Function will be used to search the list.<br> </span><span style="color:#0000ff">Dim</span> index <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = _<br> list.Find(findDelegate)<br> <br> <span style="color:#008000">'Print to Output Window</span><br> Console.WriteLine(list(index - 1)) </p>
</div>
</div>
</div> <p> </p> <p>And here’s the “FindInList” method that is being called by the “findDelegate”:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6fc821b1-f85f-459f-b389-441363db4753" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'This method is being used to search the list<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Function</span> FindInList(<span style="color:#0000ff">ByVal</span> x <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span>) _<br> <span style="color:#0000ff">As</span> <span style="color:#0000ff">Boolean</span><br> <br> <span style="color:#008000">'Search the list for the number 5</span><br> <span style="color:#0000ff">Return</span> x = 5<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <p>As mentioned previously, every Event uses a Delegate.  An event that you are very familiar with is the Button.Click event.  This event too uses a Delegate.  Here’s an example, notice the use of “AddressOf” to create the Delegate:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8d36806a-f5f1-4437-93fd-c42a894d0f8f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new Button<br> </span><span style="color:#0000ff">Dim</span> btn <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> Button()<br> <br> <span style="color:#008000">'Use "AddressOf" to create a delegate and <br> ' assign the address of the "Button_Click"<br> ' method to it. .Net Creates an EventHandler<br> ' based off of the delegate.<br> </span><span style="color:#0000ff">AddHandler</span> btn.Click, <span style="color:#0000ff">AddressOf</span> Button_Click<br> <br> <span style="color:#008000">'Click the button. Under the hood the delegate<br> ' is invoked.</span><br> btn.PerformClick() </p>
</div>
</div>
</div> <p> </p> <p>Here’s the Button_Click method that is being invoked by the delegate:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4a9e84e0-2f9d-4b2d-9e2c-0bf8083e4e19" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs)<br> <br> MessageBox.Show(<span style="color:#a31515">"The button was clicked!"</span>)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Multicasting Delegates</h4> <p> </p> <p>Up to this point we’ve learned that a Delegate has the ability to “point to” a method.  When the Delegate is invoked, the method that it “points to” is called.  Something we haven’t really discussed is the fact that a Delegate can actually “point to” more than one method at a time, and when it is invoked, all of the methods that it “points to” are called.  This is called “multicasting”.</p> <p> </p> <p>As we’ve already seen, a Delegate must have the same signature (“shape”) as the method that it is point to.  This rule stays exactly the same when a Delegate “points to” multiple methods:  the Delegate has the have the same signature as every method that it points to.</p> <p> </p> <p>In order to enable a Delegate to “point to” multiple methods, the System.Delegate.Combine method must be called.  The Combine method creates a new Delegate with an invocation list that concatenates the invocation lists of the delegates that are added, in the same order that they were added.</p> <p> </p> <p>Here’s an initial example that demonstrates Delegate Multicasting:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d43b1eb3-474f-4edb-be2f-1cfe15355eb3" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a Delegate for displaying a message.<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Sub</span> _<br> MessageDelegate(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> <span style="color:#0000ff">Object</span>, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button2.Click<br> <br> <span style="color:#008000">'Create 3 instances of the MessageDelegate</span><br> <span style="color:#008000">' that point to different methods</span><br> <span style="color:#0000ff">Dim</span> d1 <span style="color:#0000ff">As</span> MessageDelegate = _<br> <span style="color:#0000ff">AddressOf</span> DisplayMessage1<br> <span style="color:#0000ff">Dim</span> d2 <span style="color:#0000ff">As</span> MessageDelegate = _<br> <span style="color:#0000ff">AddressOf</span> DisplayMessage2<br> <span style="color:#0000ff">Dim</span> d3 <span style="color:#0000ff">As</span> MessageDelegate = _<br> <span style="color:#0000ff">AddressOf</span> DisplayMessage3<br> <br> <br> <span style="color:#008000">'Delegates will be concatenated in the same </span><br> <span style="color:#008000">' order that they are added to the list</span><br> <span style="color:#008000">' which in this case is "d1", "d2", "d3"</span><br> <span style="color:#0000ff">Dim</span> d <span style="color:#0000ff">As</span> MessageDelegate = _<br> System.Delegate.Combine(d1, d2, d3)<br> <br> <br> <span style="color:#008000">'Invoking this delegate actually invokes</span><br> <span style="color:#008000">' all 3 delegates in the same order they</span><br> <span style="color:#008000">' were added.</span><br> d(<span style="color:#a31515">"Hello World of Delegate Multicasting!"</span>)<br> <br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub<br> <br> <br> </span><span style="color:#008000">'This method will be called by "d1" delegate<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> DisplayMessage1(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> Console.WriteLine(<span style="color:#a31515">"DisplayMessage1: "</span> & msg)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub<br> <br> <br> </span><span style="color:#008000">'This method will be called by "d2" delegate<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> DisplayMessage2(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> Console.WriteLine(<span style="color:#a31515">"DisplayMessage2: "</span> & msg)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub<br> <br> <br> </span><span style="color:#008000">'This method will be called by "d3" delegate<br> </span><span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> DisplayMessage3(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> Console.WriteLine(<span style="color:#a31515">"DisplayMessage3: "</span> & msg)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> </p> <p><em>Notice that the “d1”, “d2” and “d3” delegates all pointed to methods with the same exact signature (ByVal msg As String):  DisplayMessage1, DisplayMessage2, DisplayMessage3.</em></p> <p> </p> <p>The Output from the above example looks like this:</p> <p> </p> <p><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/Sox2J6iVdgI/AAAAAAAAALY/i-2KVFbwv6s/s1600-h/multicasting%5B9%5D.jpg"><img style="border-right-width: 0px; width: 451px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="multicasting" border="0" alt="multicasting" align="left" src="http://lh4.ggpht.com/_dhkDWtu14Jc/Sox2KQFid0I/AAAAAAAAALc/kOO5-CA5rYE/multicasting_thumb%5B7%5D.jpg?imgmax=800" width="451" height="113" /></a> </p> <p> </p> <p> </p> <p><strong>A more sophisticated example</strong> could expand upon the “Event Handling with Delegates” example above, and change the way the “MyList(Of T)” class sets the “call back” delegate in the “OnItemAdded” method.  Also, we can add an “OnItemRemoved” method that can be used by the caller to set a “call back” delegate that can be invoked when an item has been removed from the list.</p> <p> </p> <p>By enabling multicasting in the “OnItemAdded” delegate event, and in a new “OnItemRemoved” delegate event, we allow the caller to set multiple call back delegates that can be invoked.  Then the caller can create different methods to respond when items are added, removed, and when the list changes.  </p> <p> </p> <p><em>Quite a few things have changed in this example, so if you saw the previous example in the “Event Handling with Delegates” section, make sure you take the time to notice the differences.</em></p> <p> </p> <p>Here’s the example:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f4cbc22a-0a90-4d00-ad51-ff0c7e18aa7d" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a New List Class that Inherits the <br> ' List(Of T) class (The "T" stands for the<br> ' Type to be specified when the list is <br> ' declared)<br> </span><span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> MyList(<span style="color:#0000ff">Of</span> T)<br> <span style="color:#0000ff">Inherits</span> List(<span style="color:#0000ff">Of</span> T)<br> <br> <span style="color:#008000">'Create a "Call Back" Delegate to provide </span><br> <span style="color:#008000">' feedback when this list has changed</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Delegate</span> <span style="color:#0000ff">Sub</span> _<br> ListChangedDelegate(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <br> <br> <span style="color:#008000">'Create a private, internal variable that </span><br> <span style="color:#008000">' will store a reference to the </span><br> <span style="color:#008000">' "Call Back" ListChangedDelegate</span><br> <span style="color:#008000">' that will be invoked when an item has</span><br> <span style="color:#008000">' been added to the list.</span><br> <span style="color:#0000ff">Private</span> AddedDelegate <span style="color:#0000ff">As</span> ListChangedDelegate<br> <br> <br> <span style="color:#008000">'This method is used by the Caller to set </span><br> <span style="color:#008000">' the "Call Back" Delegate that will be </span><br> <span style="color:#008000">' Invoked when a new item is added to the </span><br> <span style="color:#008000">' list </span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> OnItemAdded( _<br> <span style="color:#0000ff">ByVal</span> method <span style="color:#0000ff">As</span> ListChangedDelegate)<br> <br> <span style="color:#008000">'Multicasting:</span><br> <span style="color:#008000">'Set the "Call Back" delegate with the </span><br> <span style="color:#008000">' delegate passed in</span><br> AddedDelegate = _<br> System.Delegate.Combine(AddedDelegate, _<br> method)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This is the method being called to add </span><br> <span style="color:#008000">' items to the list</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Shadows</span> <span style="color:#0000ff">Sub</span> Add(<span style="color:#0000ff">ByVal</span> item <span style="color:#0000ff">As</span> T)<br> <br> <span style="color:#008000">'Check to see if the item is already</span><br> <span style="color:#008000">' in the list</span><br> <span style="color:#0000ff">If</span> <span style="color:#0000ff">Me</span>.Contains(item) <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'It's in the list, so invoke the </span><br> <span style="color:#008000">' "Call Back" Delegate and pass </span><br> <span style="color:#008000">' the response</span><br> AddedDelegate(item.ToString() & _<br> <span style="color:#a31515">" not added, because it's"</span> & _<br> <span style="color:#a31515">" already in the list"</span>)<br> <br> <span style="color:#0000ff">Else</span><br> <br> <span style="color:#008000">'It's not in the list, so add the</span><br> <span style="color:#008000">' item to the base class list</span><br> <span style="color:#008000">' (this prevents a recursive call</span><br> <span style="color:#008000">' the this Add method)</span><br> <span style="color:#0000ff">MyBase</span>.Add(item)<br> <br> <span style="color:#008000">'Then invoke the "Call Back" </span><br> <span style="color:#008000">' Delegate and pass the response.</span><br> AddedDelegate(item.ToString() & _<br> <span style="color:#a31515">" added to list"</span>)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <br> <span style="color:#008000">'Create a private, internal variable that </span><br> <span style="color:#008000">' will store a reference to the </span><br> <span style="color:#008000">' "Call Back" ListChangedDelegate</span><br> <span style="color:#008000">' that will be invoked when an item has</span><br> <span style="color:#008000">' been removed from the list.</span><br> <span style="color:#0000ff">Private</span> RemovedDelegate <span style="color:#0000ff">As</span> ListChangedDelegate<br> <br> <br> <span style="color:#008000">'This method is used by the Caller to set </span><br> <span style="color:#008000">' the "Call Back" Delegate that will be </span><br> <span style="color:#008000">' Invoked when an item is removed from</span><br> <span style="color:#008000">' the list</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Sub</span> OnItemRemoved( _<br> <span style="color:#0000ff">ByVal</span> method <span style="color:#0000ff">As</span> ListChangedDelegate)<br> <br> <span style="color:#008000">'Multicasting:</span><br> <span style="color:#008000">'Set the "Call Back" delegate with the </span><br> <span style="color:#008000">' delegate passed in</span><br> RemovedDelegate = _<br> System.Delegate.Combine(RemovedDelegate, _<br> method)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This is the method being called to remove </span><br> <span style="color:#008000">' items from the list</span><br> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Shadows</span> <span style="color:#0000ff">Function</span> Remove( _<br> <span style="color:#0000ff">ByVal</span> item <span style="color:#0000ff">As</span> T) <span style="color:#0000ff">As</span> <span style="color:#0000ff">Boolean</span><br> <br> <span style="color:#008000">'Check to see if the item is in</span><br> <span style="color:#008000">' the list</span><br> <span style="color:#0000ff">If</span> <span style="color:#0000ff">Me</span>.Contains(item) <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'It's in the list, so remove</span><br> <span style="color:#008000">' the item from the base class</span><br> <span style="color:#008000">' list.</span><br> <span style="color:#0000ff">MyBase</span>.Remove(item)<br> <br> <span style="color:#008000">'Then invoke the "Call Back"</span><br> <span style="color:#008000">' Delegate and pass the response.</span><br> RemovedDelegate(item.ToString() & _<br> <span style="color:#a31515">" removed from list"</span>)<br> <br> <span style="color:#0000ff">Return</span> <span style="color:#0000ff">True</span><br> <br> <span style="color:#0000ff">Else</span><br> <br> <span style="color:#008000">'It's not in the list, so invoke </span><br> <span style="color:#008000">' the "Call Back" Delegate and</span><br> <span style="color:#008000">' pass the response</span><br> RemovedDelegate(item.ToString() & _<br> <span style="color:#a31515">" not removed, because it's"</span> & _<br> <span style="color:#a31515">" not in the list."</span>)<br> <br> <span style="color:#0000ff">Return</span> <span style="color:#0000ff">False</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If</span><br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function<br> <br> End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> </p> <p>Ok, so now that we have our multicast enabled “MyList(Of T)” class, let’s take a look at how to use it:</p> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ff65360b-7ffe-46a3-ae30-339ce241677e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Public</span> <span style="color:#0000ff">Class</span> Form1<br> <br> <span style="color:#008000">'This is the "call back" method that </span><br> <span style="color:#008000">' gets called when the button is clicked.</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> Button1_Click( _<br> <span style="color:#0000ff">ByVal</span> sender <span style="color:#0000ff">As</span> System.Object, _<br> <span style="color:#0000ff">ByVal</span> e <span style="color:#0000ff">As</span> System.EventArgs) _<br> <span style="color:#0000ff">Handles</span> Button1.Click<br> <br> <br> <span style="color:#008000">'Create a new instance of our list</span><br> <span style="color:#008000">' and set the Type (T) to Integer</span><br> <span style="color:#0000ff">Dim</span> list <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> MyList(<span style="color:#0000ff">Of</span> <span style="color:#0000ff">Integer</span>)<br> <br> <span style="color:#008000">'Multicasting of AddedDelegate</span><br> list.OnItemAdded(<span style="color:#0000ff">AddressOf</span> _<br> OnItemAdded)<br> list.OnItemAdded(<span style="color:#0000ff">AddressOf</span> _<br> OnListChanged)<br> <br> <span style="color:#008000">'Multicasting of RemovedDelegate</span><br> list.OnItemRemoved(<span style="color:#0000ff">AddressOf</span> _<br> OnItemRemoved)<br> list.OnItemRemoved(<span style="color:#0000ff">AddressOf</span> _<br> OnListChanged)<br> <br> <span style="color:#008000">'Add items to the list</span><br> list.Add(1)<br> list.Add(2)<br> list.Add(3)<br> list.Add(3)<br> <br> <span style="color:#008000">'Remove items from the list</span><br> list.Remove(1)<br> list.Remove(3)<br> list.Remove(3)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This is the "Call Back" method that is being</span><br> <span style="color:#008000">' called when the AddedDelegate delegate is </span><br> <span style="color:#008000">' invoked.</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> OnItemAdded(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> <span style="color:#008000">'Print the response to the Output Window</span><br> Console.WriteLine(<span style="color:#a31515">"OnItemAdded: "</span> & msg)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This is the "Call Back" method that is being</span><br> <span style="color:#008000">' called when the AddedDelegate delegate or </span><br> <span style="color:#008000">' RemovedDelegate delegate is invoked</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> OnListChanged(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> Console.WriteLine(<span style="color:#a31515">"OnListChanged: "</span> & msg)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span><br> <br> <br> <span style="color:#008000">'This is the "Call Back" method that is being</span><br> <span style="color:#008000">' called when the RemovedDelegate delegate is</span><br> <span style="color:#008000">' invoked</span><br> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> OnItemRemoved(<span style="color:#0000ff">ByVal</span> msg <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span>)<br> <br> Console.WriteLine(<span style="color:#a31515">"OnItemRemoved: "</span> & msg)<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub<br> <br> End</span> <span style="color:#0000ff">Class</span>
</p>
</div>
</div>
</div> <p> </p> <p> </p> <h4>Summary</h4> <p>So we learned that Delegates are basically pointers to methods that can be invoked at any time.  We also learned that Delegates are strongly-typed, and must have a signature that identically matches the signature of the method that they point to.  We also learned that a Delegate intrinsically support multicasting, so that a Delegate can point to multiple methods, not just one method.</p> <p> </p> <p>If you have a pretty solid understanding of Delegates, then you’re ready to dive into Events, which you’re going to love, because they are designed to lessen the burden of using Delegates in the raw.  </p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-90994227713715721812009-08-17T12:00:00.000-06:002009-08-17T12:34:23.161-06:00ADO.NET: DataTables, In-depth<p>DataTables are designed to store data.  Where the data comes from is not a concern of the DataTable, because it is completely autonomous, being independent of, and disconnected from it’s data source.  So, whether the data is coming from MS Access, SQL Server, Oracle, Csv Files, or some other data source, it doesn’t matter:  A DataTable is going to perform the same. <br /> <br />DataTables are very similar to tables in any other standard database, such as MS Access, SQL Server, Oracle, etc., because they all have Columns, and store rows of data.  <br /> <br /></p> <h4> <br />DataTable <br /></h4> <p> <br />Before we look at the commonly used properties of a DataTable, let’s look at two of the most important ones: <br /> <br /><strong>Columns</strong>:  This is a collection of DataColumns that are added to the DataTable. <br /> <br /></p> <p><strong>Rows</strong>:  This is a collection of the DataRows that are added to the DataTable. <br />  <br /></p> <h4> <br />DataColumn <br /></h4> <p> <br />Columns are not designed to store data, but to define the data that is stored in them.  For example, is the data going to a string?  If so, how long can the string be?  Is the data going to be a number?  If so, how big will the number be?  Will the number contain decimals?  Is the data going to be a date?  Is the data required?  What if the user doesn’t enter a value, what will be the default value?  <br /> <br />Here’s a look at the commonly used properties that we can configure when we create a DataColumn for a DataTable:  <br /> <br /> <br /><strong><u>DataColumn Properties</u>:</strong> <br /> <br /></p> <p><strong>Allow DB Null</strong>:  This is a True or False property that indicates whether a column is allowed to store a null value in it.  If a column is not allowed to store a null value, then a value must be provided by the user, the DefaultValue property, or programmatically. <br /> <br /><strong>AutoIncrement</strong>:  This is a True of False property that indicates whether the numeric value of the field will increment automatically for each new record that is added.  This is especially useful for an ID column, or a column that will serve as they key value for new rows.  If this property is set to True, the DataType will automatically be set to Integer (Int32). <br /> <br /><strong>AutoIncrementSeed</strong>:  This is a numeric property that indicates the number to be used to begin automatic incrementing at.  For example, if the value is “0”, then the auto increment pattern will be “0, 1, 2, 3…”  If the value is set to “100”, then the auto increment pattern will be “100, 101, 102, 103…” <br /> <br /><strong>AutoIncrementStep</strong>:  This is a numeric property that indicates the numeric pattern to use when automatically incrementing values.  For example, if the value is “1”, then incrementation will be by 1:  “0, 1, 2, 3…”  If the value is “2”, then incrementation will be by 2:  “0, 2, 4, 6…”  If the value is “-1”, then the incrementation will be by –1:  “0, –1, –2, –3…” <br /> <br /><strong>Caption</strong>:  This is a String property that stores the default text that will be displayed by user interface controls that display column header information. <br /> <br /><strong>DataType</strong>:  This property defines what type of data can be stored in this column, and can be any valid data type, such as String, Integer, DateTime, Boolean, etc.  The default data type is String.  <br /> <br /><em>Surprisingly,  although the DataSet designer limits the data types that can be entered, any data type can be specified programmatically. <br /></em> <br /><strong>DateTimeMode</strong>:  This property controls the serialization DateTime format. <br /> <br /><strong>DefaultValue</strong>:  This property indicates the default value that will be used to populate this column in a new row.  This value can be anything as long as it corresponds to the selected DataType.  DBNull (null) is the standard default value. <br /> <br /><strong>Expression</strong>:  This property allows you to enter an expression that can be used to filter rows, calculate column values, or aggregate related data.  For example, if we had a table with 2 integer columns, “A” and “B”, we could add a new column “C” and set the Expression to insert the Sum of columns “A” and “B” into column “C”: <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8b74e64e-c864-45c1-8212-a2a1c24d8889" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>
<span style="color:#008000">'Create a new DataTable</span><br><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> <span style="color:#2b91af">DataTable</span>()<br><br><span style="color:#008000">'Add 2 Integer columns, "A" and "B"</span><br>table.Columns.Add(<span style="color:#a31515">"A"</span>, <span style="color:#0000ff">GetType</span>(<span style="color:#0000ff">Integer</span>))<br>table.Columns.Add(<span style="color:#a31515">"B"</span>, <span style="color:#0000ff">GetType</span>(<span style="color:#0000ff">Integer</span>))<br><br><span style="color:#008000">'Create an expression that adds columns</span><br><span style="color:#008000">' A And B</span><br><span style="color:#0000ff">With</span> table.Columns.Add(<span style="color:#a31515">"C"</span>, <span style="color:#0000ff">GetType</span>(<span style="color:#0000ff">Integer</span>))<br> .Expression = <span style="color:#a31515">"A+B"</span> : <span style="color:#0000ff">End</span> <span style="color:#0000ff">With</span><br><br><span style="color:#008000">'Add 5 rows of data</span><br><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 1 <span style="color:#0000ff">To</span> 5<br><br> <span style="color:#008000">'Add i to both columns "A" and "B"</span><br> <span style="color:#008000">' Add Nothing to Column "C", because</span><br> <span style="color:#008000">' column("C") will use the expression</span><br> <span style="color:#008000">' to calculate the Sum</span><br> table.Rows.Add(i, i, <span style="color:#0000ff">Nothing</span>) : <span style="color:#0000ff">Next</span><br><br><br><span style="color:#008000">'View results in the Output Window</span><br><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> table.Rows.Count - 1<br><br> <span style="color:#008000">'Write the Sum stored in column "C" to </span><br> <span style="color:#2b91af">Debug</span>.WriteLine(table.Rows(i).Item(<span style="color:#a31515">"C"</span>)) : <span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p></p> <p> <br />More on Expressions to come later… <br /> <br /><strong>ExtendedProperties</strong>:  This property is a collection (HashTable) that can be used to store custom information of any data type.  However, if the table is going to be written to XML, any data that is not of the String data type will not be persisted. <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0b4b5cc4-c19b-446f-a7a6-ccdd7f74b89a" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table.Columns.Add(<span style="color:#a31515">"A"</span>)<br> <br> <span style="color:#008000">'Add a "Date" ExtendedProperty<br> ' "Date" is the key, "Today" is the date</span><br> table.Columns(<span style="color:#a31515">"A"</span>).ExtendedProperties _<br> .Add(<span style="color:#a31515">"Date"</span>, Today.ToShortDateString())<br> <br> <span style="color:#008000">'Write the "Date" to the Output Window</span><br> Debug.WriteLine(table.Columns(<span style="color:#a31515">"A"</span>) _<br> .ExtendedProperties(<span style="color:#a31515">"Date"</span>))
</p>
</div>
</div>
</div> <p></p> <p><strong> <br />MaxLength</strong>:  This is an Integer property that allows you to define the maximum length of the data that can be stored in this column.  A value of “-1” indicates there is no maximum, while any positive number limits the length of the data.  An attempt to add data to the column that is longer than the MaxLength property results in an Error.  <br /> <br /><strong>Name</strong>:  This is a String property that sets the name of the DataColumn.  This property is used to retrieve the DataColumn from the DataTable’s Columns collection. <br /> <br /><strong>NullValue</strong>:  This property indicates what value will be returned if the column is null:  Empty, Nothing and Throw Exception. <br /> <br /><strong>ReadOnly</strong>:  This is a True of False property that indicates whether changes can be made to the data in the column after it’s row has been added to the DataTable. <br /> <br /><strong>Unique</strong>:  This is a True of False property that indicates whether the column should allow duplicates (False) or not (True). <br /> <br /> <br /><strong>Example <br /></strong>So now that we’ve looked at the standard properties of a DataColumn, let’s look at some examples of how to use them: <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:71953d17-97fc-4552-aa28-cba733dd9f67" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>
<span style="color:#008000">'Create a new DataTable named "Employees"</span><br><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> <span style="color:#2b91af">DataTable</span>(<span style="color:#a31515">"Employees"</span>)<br><br><span style="color:#008000">'Add a new EmployeeId column</span><br><span style="color:#0000ff">With</span> table.Columns.Add()<br><br> <span style="color:#008000">'Set the name of the column</span><br> .ColumnName = <span style="color:#a31515">"EmployeeId"</span><br><br> <span style="color:#008000">'Set the text that will appear in</span><br> <span style="color:#008000">' user interface controls</span><br> .Caption = <span style="color:#a31515">"Employee Id"</span><br><br> <span style="color:#008000">'The EmployeeId is required, so</span><br> <span style="color:#008000">' do not allow this value to be empty</span><br> .AllowDBNull = <span style="color:#0000ff">False</span><br><br> <span style="color:#008000">'Allow this column to automatically</span><br> <span style="color:#008000">' increment the value for new rows</span><br> .AutoIncrement = <span style="color:#0000ff">True</span><br><br> <span style="color:#008000">'Start the incrementation at 1</span><br> .AutoIncrementSeed = 1<br><br> <span style="color:#008000">'Set the numeric pattern to be</span><br> <span style="color:#008000">' used to increment the value of </span><br> <span style="color:#008000">' new rows</span><br> .AutoIncrementStep = 1<br><br> <span style="color:#008000">'Because this is column will automatically</span><br> <span style="color:#008000">' increment it's value for new rows, the</span><br> <span style="color:#008000">' data type must be numeric, and large</span><br> <span style="color:#008000">' enough to support the possible range of </span><br> <span style="color:#008000">' numbers</span><br> .DataType = <span style="color:#0000ff">GetType</span>(<span style="color:#0000ff">Integer</span>)<br><br> <span style="color:#008000">'Each value of this column will be unique,</span><br> <span style="color:#008000">' and no duplicates will be allowed.</span><br> .Unique = <span style="color:#0000ff">True</span><br><br><span style="color:#0000ff">End</span> <span style="color:#0000ff">With</span><br><br><br><span style="color:#008000">'Add a column to store first names</span><br><span style="color:#008000">' The Name property is set when the </span><br><span style="color:#008000">' Add("FirstName") method is called</span><br><span style="color:#0000ff">With</span> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br><br> <span style="color:#008000">'Set the display text</span><br> .Caption = <span style="color:#a31515">"First Name"</span><br><br> <span style="color:#008000">'The first name must be provided</span><br> .AllowDBNull = <span style="color:#0000ff">False</span><br><br> <span style="color:#008000">'Allow a first name up to 40 letters</span><br> .MaxLength = 40<br><br><span style="color:#0000ff">End</span> <span style="color:#0000ff">With</span><br><br><br><span style="color:#008000">'Add a column to store last names</span><br><span style="color:#0000ff">With</span> table.Columns.Add(<span style="color:#a31515">"LastName"</span>)<br><br> <span style="color:#008000">'Set the display text</span><br> .Caption = <span style="color:#a31515">"Last Name"</span><br><br> <span style="color:#008000">'The last name must be provided</span><br> .AllowDBNull = <span style="color:#0000ff">False</span><br><br> <span style="color:#008000">'Allow a first name up to 40 letters</span><br> .MaxLength = 40<br><br><span style="color:#0000ff">End</span> <span style="color:#0000ff">With</span><br><br><br><span style="color:#008000">'Add a column to store the full name</span><br><span style="color:#008000">' of the employee</span><br><span style="color:#0000ff">With</span> table.Columns.Add(<span style="color:#a31515">"FullName"</span>)<br><br> <span style="color:#008000">'Set the display text</span><br> .Caption = <span style="color:#a31515">"Full Name"</span><br><br> <span style="color:#008000">'This expression will automatically </span><br> <span style="color:#008000">' create and insert the full name of </span><br> <span style="color:#008000">' the Employee by concatenating the </span><br> <span style="color:#008000">' FirstName and LastName fields</span><br> .Expression = <span style="color:#a31515">"FirstName + ' ' + LastName"</span><br><br><span style="color:#0000ff">End</span> <span style="color:#0000ff">With</span><br><br><br><span style="color:#008000">'Add a column to store the hire date</span><br><span style="color:#0000ff">With</span> table.Columns.Add(<span style="color:#a31515">"HireDate"</span>)<br><br> <span style="color:#008000">'Set the display text</span><br> .Caption = <span style="color:#a31515">"Hire Date"</span><br><br> <span style="color:#008000">'Set the DataType to Date</span><br> .DataType = <span style="color:#0000ff">GetType</span>(<span style="color:#0000ff">Date</span>)<br><br> <span style="color:#008000">'Set the default value to Today's date</span><br> .DefaultValue = Today<br><br><span style="color:#0000ff">End</span> <span style="color:#0000ff">With</span>
</p>
</div>
</div>
</div> <p></p> <p> <br />Now that we have an example of working with DataColumns in the Employee DataTable, let’s look at working with DataRows. </p> <p> </p> <p> </p> <h4>DataRow</h4> <p> <br />Rows are designed to actually store the data that gets entered into a DataTable.  Rows can be added to a DataTable, retrieved from a DataTable, be evaluated, updated and even removed from a DataTable. <br /> <br />The structure of a row is defined by the DataTable that it belongs.  For example, a row that belongs to the Employee table, that we created in the DataColumn section above, will have an EmployeeId column, and FirstName, LastName, FullName and HireDate columns as well. </p> <p> <br />To start with, let’s look at the commonly used properties of a DataRow. <br /> <br /> <br /><strong><u>DataRow Properties</u></strong>: </p> <p><strong> <br />HasErrors</strong>:  This is a True or False property that indicates whether there are any errors in the row.  <br /> <br /><em>A DataRow does not automatically identify errors, but rows can be programmatically evaluated, and errors can be set and cleared when necessary. <br /> <br /></em><strong>Item</strong>:  This property provides access to the content of each of the DataColumns in the row.  The values in the columns can be both retrieved and set using this property. <br /> <br /><strong>ItemArray</strong>:  This property provides access to the array of content of each of the DataColumns in the row.  The values of all of the columns can be retrieved as an array, and set as an array. <br /> <br /><strong>RowError</strong>:  This String property is used to set or clear an error for a row. <br /> <br /><em>A RowError applies to the whole row itself, which means that it is not column specific.  The SetColumnError method can be used to set an error that is specific to a column in the row, while the GetColumnError method can be used to retrieve errors that are specific to a column in a row.  The GetColumnsInError method can be used to retrieve all of the DataColumns in the row that have errors. <br /> <br /></em><strong>RowState</strong>:  This property is <em>read-only, </em>and indicates the current state of the Row.  A DataRow can have one of the following DataRowStates:  <u>Detached</u>, which is the state of a new row that has been created, but has not actually been added to the DataTable; <u>New</u>, which is the state of a new row that has been created and added to the DataTable; <u>Unchanged</u>, which is the state of the row after any pending changes have been committed; <u>Modified</u>, which is the state of a row that has been modified; and <u>Deleted</u>, which is the state of a row that has been deleted (because rows are not actually removed from the DataTable when they are deleted). <br /> <br /><em>If thinking about the RowState confuses you, don’t despair.  As we take a deeper look at how DataTables handle rows, the RowState will begin to make a lot more sense. <br /> <br /></em><strong>Table</strong>:  This property returns a reference to the DataTable that the DataRow belongs to. <br /> <br /> <br /><strong>Examples</strong> <br />Now that we have looked at the standard properties of a DataRow, let’s take a look at how to work with them. <br /> <br />These examples will use the Employees table that we created in the DataColumn section above. <br /> <br /><strong><u>Example 1</u></strong> <br />Add a new row to the table, set the column values using the Item property, while examining the auto-calculated columns, default values, and the RowState. <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0d99c117-9887-4b6b-911d-71e2d21530df" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'First, declare a row as a DataRow<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow<br> <br> <span style="color:#008000">'To actually create a new row, call<br> ' the NewRow() method of the DataTable.<br> ' This method not only creates a new<br> ' row, but it also adds all<br> ' of the columns to it automatically.</span><br> row = table.NewRow()<br> <br> <span style="color:#008000">' Creating a new row will also set<br> ' the RowState to "Detached", because<br> ' although the row has been created, it <br> ' hasn't been added to the table yet.<br> ' <br> ' Look at the Output window for <br> ' verification:</span><br> Debug.WriteLine(row.RowState)<br> <br> <br> <span style="color:#008000">'Use the "Item" property to access the<br> ' content of the FirstName and LastName<br> ' columns and to set their values.</span><br> row.Item(<span style="color:#a31515">"FirstName"</span>) = <span style="color:#a31515">"Gary"</span><br> row.Item(<span style="color:#a31515">"LastName"</span>) = <span style="color:#a31515">"Lima"<br> </span><span style="color:#008000">'<br> 'Note that we don't need to set the<br> ' values for all of the columns,<br> ' because:<br> '<br> ' The EmployeeId column is an <br> ' auto-incrementing column, so it's <br> ' value is calculated and populated<br> ' by the DataTable.<br> '<br> ' The FullName column is a column<br> ' that has an Expression that <br> ' automatically creates and inserts<br> ' the full name of the employee<br> ' using the FirstName and LastName<br> ' columns.<br> '<br> ' The HireDate has a DefaultValue<br> ' of Today's date, which automatically<br> ' gets inserted as well.<br> <br> 'At this point, we can verify that the<br> ' auto-incrementing EmployeeId column<br> ' and the HireDate's DefaultValue have<br> ' already been set.</span><br> Debug.WriteLine(row.Item(<span style="color:#a31515">"EmployeeId"</span>))<br> Debug.WriteLine(row.Item(<span style="color:#a31515">"HireDate"</span>))<br> <span style="color:#008000">'<br> 'However, the FullName column's Expression<br> ' has not calculated the value yet.<br> ' This will not happen until the row <br> ' has been added to the table.</span><br> Debug.WriteLine(row.Item(<span style="color:#a31515">"FullName"</span>))<br> <span style="color:#008000">'<br> 'View the Output Window to see the results.<br> <br> 'Now we can actually add the row to the table:</span><br> table.Rows.Add(row)<br> <br> <span style="color:#008000">'You can verify that the FullName<br> ' has now been calculated:</span><br> Debug.WriteLine(row.Item(<span style="color:#a31515">"FullName"</span>))<br> <br> <span style="color:#008000">'Adding the row to the table causes the <br> ' RowState to be changed to "Added". You <br> ' can verify this by viewing the Output Window</span><br> Debug.WriteLine(row.RowState)<br> <br> </p>
</div>
</div>
</div> <p></p> <p> <br /><strong><u>Example 2 <br /></u></strong>Add a new row to the table, set the column values using the ItemArray property. <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f81c1f86-9b6c-48ab-82b2-36d1352963af" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'First, declare a row as a DataRow<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow<br> <br> <span style="color:#008000">'Create a new row by calling the<br> ' NewRow() method of the DataTable</span><br> row = table.NewRow()<br> <br> <span style="color:#008000">'Use the "ItemArray" property to access<br> ' an array of all of the content the <br> ' columns in the row. <br> '<br> ' All of the columns will be in the same<br> ' order as they were added to the table.<br> '<br> ' When populating the ItemArray, create an<br> ' Object array and pass all of the values<br> ' you want to load into the row in the same<br> ' order as the columns.<br> '<br> ' Pass "Nothing" to columns that perform<br> ' calculations or have DefaultValues set.<br> ' If you don't want to use the DefaultValue<br> ' then pass a value.</span><br> row.ItemArray = _<br> <span style="color:#0000ff">New</span> <span style="color:#0000ff">Object</span>() {<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Gary"</span>, <span style="color:#a31515">"Lima"</span>, _<br> <span style="color:#0000ff">Nothing</span>, <span style="color:#0000ff">CDate</span>(<span style="color:#a31515">"08/11/2009"</span>)}<br> <br> <span style="color:#008000">'Reviewing the row's ItemArray:<br> '<br> ' EmployeeId = Nothing<br> ' FirstName = "Gary"<br> ' LastName = "Lima"<br> ' FullName = Nothing<br> ' HireDate = 08/11/2009<br> <br> <br> 'Add the row to the table</span><br> table.Rows.Add(row)<br> <br> <br> <span style="color:#008000">'Now that the row has been added, let's<br> ' loop through every column in the row<br> ' and analyze it's content:<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> table.Columns.Count - 1<br> Debug.WriteLine(row.Item(i)) : <span style="color:#0000ff">Next<br> <br> </span><span style="color:#008000">'View the Output Window<br> <br> 'The output will be:<br> '<br> ' 1<br> ' Gary<br> ' Lima<br> ' Gary Lima<br> ' 8/11/2009 12:00:00 AM<br> <br> 'As you can see, the EmployeeId column <br> ' correctly calculated the auto-incrementing<br> ' value, the FullName column correctly<br> ' calculated the value, and the HireDate<br> ' column was set to the value we passed<br> ' in, not the DefaultValue<br> <br> </span>
</p>
</div>
</div>
</div> <p></p> <p> <br /><strong><u>Example 3</u> <br /></strong>Add a new row to the table, commit changes to the new row, retrieve the row from the table’s Rows collection, and modify the row, while analyzing the different states of the RowState property. <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:94917a28-8cde-490c-bede-9e15dd999c02" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Add a new row to the DataTable, passing in<br> ' all of the values for each of the columns<br> ' in the same order that the columns are in.<br> ' <br> ' Pass "Nothing" for columns that calculate<br> ' their values or have DefaultValues set.<br> '<br> ' Accept the changes when added (True),<br> ' changing the RowState to "Unchanged"</span><br> table.LoadDataRow( _<br> <span style="color:#0000ff">New</span> <span style="color:#0000ff">Object</span>() {<span style="color:#0000ff">Nothing</span>, <span style="color:#a31515">"Gary"</span>, <span style="color:#a31515">"Lima"</span>, _<br> <span style="color:#0000ff">Nothing</span>, <span style="color:#0000ff">CDate</span>(<span style="color:#a31515">"08/11/2009"</span>)}, <span style="color:#0000ff">True</span>)<br> <br> <span style="color:#008000">'To obtain a reference to a row that has<br> ' been added to a DataTable, use the row's<br> ' index in the DataTable's Rows collection.<br> '<br> ' In this case, the very first row in the <br> ' Rows collection is at index 0.<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow = table.Rows(0)<br> <br> <span style="color:#008000">'Verify that the RowState is "Unchanged"<br> ' See Output Window.</span><br> Debug.WriteLine(row.RowState)<br> <br> <span style="color:#008000">'Using the Item property of the DataRow<br> ' we can change the content stored in a column.</span><br> row.Item(<span style="color:#a31515">"HireDate"</span>) = <span style="color:#0000ff">CDate</span>(<span style="color:#a31515">"01/01/2009"</span>)<br> <br> <span style="color:#008000">'Now that the content of a column has changed,<br> ' the RowState of the row has changed to <br> ' Modified. See the Output Window for <br> ' verification.</span><br> Debug.WriteLine(row.RowState) </p>
</div>
</div>
</div> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p> <br />Now that we have learned about the properties of a DataRow, let’s take a look at the methods of a DataRow. <br /> <br /> <br /><strong><u>DataRow Methods: <br /> <br /></u>AcceptChanges</strong>:  Commits all pending changes stored in the DataRow and sets the RowState to “Unchanged”. <br /> <br /><strong>BeginEdit</strong>:  Begins the editing process for a DataRow.  Once the editing process begins, it can be commited by calling <em>EndEdit</em>, or cancelled by calling <em>CancelEdit</em>. <br /> <br /><strong>CancelEdit</strong>:  Cancels all changes that were made since the <em>BeginEdit</em> method was called, restoring the row to its original state. <br /> <br /><strong>ClearErrors</strong>:  Clears the row of all errors. This includes errors set with the DataRow’s <em>RowError </em>property and the <em>SetColumnError</em> method. <br /> <br /><strong>Delete</strong>:  Sets the RowState property to “Deleted”.  <br /> <br /><em>The Delete method does not actually remove the row from the table, it only sets the RowState to “Deleted”.  This is necessary, because when a database (such as MS Access, SQL, etc.) needs to be updated with the changes, it needs to know which rows to remove from its table. <br /> <br /></em><strong>EndEdit</strong>:  Commits all changes that were made since the <em>BeginEdit</em> method was call. <br /> <br /><strong>GetChildRows</strong>:  Retrieves an array of all of the child rows, for the current row, from a related table using the respective DataRelation. <br /> <br /><strong>GetColumnError</strong>:  Retrieves all of the error information for the specified column. <br /> <br /><strong>GetColumnsInError</strong>:  Retrieves an array of all of the columns that have errors. <br /> <br /><strong>GetParentRow</strong>:  Retrieves the parent row, for the current row, from a related table using the respective DataRelation. <br /> <br /><strong>GetParentRows</strong>:  Retrieves the parent rows, for the current row, from a related table using the respective DataRelation. <br /> <br /><strong>HasVersion</strong>:  A True or False value that indicates whether the row is able to return a version of data.  The available DataRowVersions are:  Current, Default, Original and Proposed. <br /> <br /></p> <p></p> <p><strong>IsNull</strong>:  A True or False value that indicates whether the value of a column in a row is null (DBNull) or not. <br /> <br /><strong>RejectChanges</strong>:  Rejects all pending changes stored in the DataRow and restores the RowState to its former state.  RejectChanges can be executed after changes have been made, but before <em>AcceptChanges</em> is called. <br /> <br /><strong>SetAdded</strong>:  Changes the DataRow’s RowState to “Added”. <br /> <br /><strong>SetColumnError</strong>:  Sets error text for a particular column. <br /> <br /><strong>SetModified</strong>:  Changes the DataRow’s RowState to “Modified”. <br /> <br /><strong>SetParentRow</strong>:  Changes the parent row, for the curent row, from a related table using the respective DataRelation. <br /> <br /> <br /><strong>Examples</strong></p> <p>Ok, so now we’ve had a chance to see various methods for the DataRow.  Let’s actually take a look at how to use some of the methods (we’re not going to examine working with parent or child rows in this article, because those include working with DataRelations, which we haven’t covered). <br /> <br /><u>DataRow Versions</u> <br />Let’s begin by looking at the <strong>HasVersion</strong> method.  This is an excellent place to begin, because in order to fully understand what the other methods are doing, we need to fully understand how row versioning works. <br /> <br />A DataRow can have up to 4 copies of it existing at the same time.  Each copy of the row is a complete copy of the entire row, including all columns and their respective data.  A DataRow does not always have 4 copies, that’s just the maximum number of copies that can exist at one time.  Each copy of the row is not necessarily exactly the same as the other copies of the row, but rather is a copy of the row respective to the types of actions that have been performed on the row. <br /> <br />As mentioned above, the four possible row versions are Current, Default, Original and Proposed.  Let’s look at them, but in a different order than listed:</p> <p> <br /><u>Original</u>:  This version of the row contains the original values of each column.  This version is created or updated after <em>AcceptChanges</em> is called.  This version does not exist when a new row has been created, and added to the table, but <em>AcceptChanges </em>has not been called. <br /> <br /><u>Current</u>:  This version of the row contains the current values of each column, and always exists. <br /> <br /><u>Proposed</u>:  This version of the row contains proposed values of each column, and only exists between the time that <em>BeginEdit</em> and either <em>EndEdit</em> or <em>CancelEdit</em> are called. <br /> <br /><u>Default</u>:  This version of the row depends on the <em>RowState</em> of the row:  if the RowState is Added, Modified, Deleted or Unchanged, then the default version is the same as the <em>Current</em> version; however, if the RowState is <em>detached</em>, then the default version is the same as the <em>Proposed</em> version. <br /> <br />Here’s an example of a row with 4 different versions: <br /> <br /><a href="http://lh4.ggpht.com/_dhkDWtu14Jc/SoSOXPRfQtI/AAAAAAAAAKk/e4zyEAwvlFg/s1600-h/rowversion%5B4%5D.jpg"><img style="border-right-width: 0px; width: 212px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="rowversion" border="0" alt="rowversion" align="left" src="http://lh3.ggpht.com/_dhkDWtu14Jc/SoSOXlbYDBI/AAAAAAAAAKo/oclG4CgVRHs/rowversion_thumb%5B2%5D.jpg?imgmax=800" width="212" height="147" /></a> <br /> <br /></p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /><em> <br />Although you could think of each version of the row as a separate row, I hesitate to actually present it that way, because it could become confusing. <br /></em> <br /><strong><u>Example 1</u></strong> <br />Now let’s take a look at a programming example that demonstrates row versions: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cfffc1bc-61a4-458e-8982-5fe462e16ec5" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Add a "FirstName" column</span><br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> <br> <span style="color:#008000">'Add a new row, passing "True" to Accept Changes<br> ' (Accepting Changes adds the new row and<br> ' sets it's RowState to "Unchanged")</span><br> table.LoadDataRow(<span style="color:#0000ff">New</span> <span style="color:#0000ff">Object</span>() {<span style="color:#a31515">"Gary"</span>}, <span style="color:#0000ff">True</span>)<br> <br> <span style="color:#008000">'Get a reference to the row we just added<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow = table.Rows(0)<br> <br> <span style="color:#008000">'Now we've only added 1 row.<br> '<br> ' So let's look to see how many versions <br> ' there are.</span><br> <br> ShowRowVersions(row)<br> <br> <span style="color:#008000">'The Output from this example is:<br> <br> ' Original? : True<br> ' Gary<br> ' Current? : True<br> ' Gary<br> ' Proposed? : False<br> ' Default? : True<br> ' Gary</span>
</p>
</div>
</div>
</div> <p> <br />Here is the ShowRowVersions method that is being called from the code above: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fc76ce9d-301e-4896-bcbe-b4d95da18ad3" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Sub</span> ShowRowVersions(<span style="color:#0000ff">ByVal</span> row <span style="color:#0000ff">As</span> DataRow)<br> <br> <span style="color:#008000">'*** View the Output Window for results ***<br> <br> 'Does this row have an Original Row Version?</span><br> Debug.WriteLine(<span style="color:#a31515">"Original? : "</span> & _<br> row.HasVersion(DataRowVersion.Original))<br> <br> <span style="color:#008000">'If this row does have an Original Row Version,<br> ' what is it?<br> </span><span style="color:#0000ff">If</span> row.HasVersion(DataRowVersion.Original) <span style="color:#0000ff">Then</span> _<br> Debug.WriteLine(row.Item(<span style="color:#a31515">"FirstName"</span>, _<br> DataRowVersion.Original))<br> <br> <br> <span style="color:#008000">'Does this row have a Current Row Version?</span><br> Debug.WriteLine(<span style="color:#a31515">"Current? : "</span> & _<br> row.HasVersion(DataRowVersion.Current))<br> <br> <span style="color:#008000">'If this row does have a Current Row Version,<br> ' what is it?<br> </span><span style="color:#0000ff">If</span> row.HasVersion(DataRowVersion.Current) <span style="color:#0000ff">Then</span> _<br> Debug.WriteLine(row.Item(<span style="color:#a31515">"FirstName"</span>, _<br> DataRowVersion.Current))<br> <br> <br> <span style="color:#008000">'Does this row have a Proposed Row Version?</span><br> Debug.WriteLine(<span style="color:#a31515">"Proposed? : "</span> & _<br> row.HasVersion(DataRowVersion.Proposed))<br> <br> <span style="color:#008000">'If this row does have a Proposed Row Version,<br> ' what is it?<br> </span><span style="color:#0000ff">If</span> row.HasVersion(DataRowVersion.Proposed) <span style="color:#0000ff">Then</span> _<br> Debug.WriteLine(row.Item(<span style="color:#a31515">"FirstName"</span>, _<br> DataRowVersion.Proposed))<br> <br> <br> <span style="color:#008000">'Does this row have a Default Row Version?</span><br> Debug.WriteLine(<span style="color:#a31515">"Default? : "</span> & _<br> row.HasVersion(DataRowVersion.Default))<br> <br> <span style="color:#008000">'If this row does have a Default Row Version,<br> ' what is it?<br> </span><span style="color:#0000ff">If</span> row.HasVersion(DataRowVersion.Default) <span style="color:#0000ff">Then</span> _<br> Debug.WriteLine(row.Item(<span style="color:#a31515">"FirstName"</span>, _<br> DataRowVersion.Default))<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span>
</p>
</div>
</div>
</div> <p> <br />Looking at the example above, you will notice that there is no Proposed row version.  This is because the row has been added, <em>AcceptChanges</em> has been called on the row, but there have been no modifications to the row.  To create a Proposed row version, all we need to do is modify the contents of an existing row.  <br /> <br /><strong><u>Example 2</u></strong> <br />This is a great point to briefly talk about <strong>BeginEdit</strong><em>,</em> <strong>EndEdit</strong><em>, and</em> <strong>CancelEdit</strong>.  Although these methods are not required when modifying data to a row, they do provide an ability to “roll back” changes that have been made to a DataRow, which discards all pending changes, or the ability to commit changes once they have been finished.  <br /> <br />The <em>BeginEdit</em> method begins the editing process, creating the <em>Proposed</em> version of the row, where all changes to the row are temporarily stored in a pending state (awaiting to be committed or discarded).  The <em>CancelEdit</em> method discards those pending changes, while the <em>EndEdit</em> method commits them. <br /> <br />Now that we understand that, let’s look at an example of editing a row: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e0df059b-5e9a-4531-81d0-e3ab5b60166f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Begin the editing process<br> ' (Proprosed row version is created<br> ' and populated with the change<br> ' we make below)</span><br> row.BeginEdit()<br> <br> <span style="color:#008000">'Change the FirstName</span><br> row.Item(<span style="color:#a31515">"FirstName"</span>) = <span style="color:#a31515">"VBRocks"<br> <br> <br> </span><span style="color:#008000">'Call the ShowRowVersions method above</span><br> ShowRowVersions(row)<br> <br> <span style="color:#008000">'The Output from this example is:<br> <br> ' Original? : True<br> ' Gary<br> ' Current? : True<br> ' Gary<br> ' Proposed? : True<br> ' VBRocks<br> ' Default? : True<br> ' VBRocks<br> <br> <br> 'Show a MessageBox, prompting to accept changes<br> </span><span style="color:#0000ff">Dim</span> result <span style="color:#0000ff">As</span> DialogResult = _<br> MessageBox.Show(<span style="color:#a31515">"Would you like to accept "</span> & _<br> <span style="color:#a31515">"these changes?"</span>, <span style="color:#a31515">"Accept Changes?"</span>, _<br> MessageBoxButtons.YesNo)<br> <br> <span style="color:#0000ff">If</span> result = Windows.Forms.DialogResult.Yes <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'Commit the pending changes to the row</span><br> row.EndEdit()<br> <span style="color:#0000ff">Else</span><br> <span style="color:#008000">'Cancel the pending changes to the row</span><br> row.CancelEdit()<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If<br> <br> <br> </span><span style="color:#008000">'Call the ShowRowVersions method above</span><br> ShowRowVersions(row)<br> <br> <span style="color:#008000">'The Output from this example is<br> ' (If "Yes" was clicked)<br> ' (changes comitted):<br> <br> ' Original? : True<br> ' Gary<br> ' Current? : True<br> ' VBRocks<br> ' Proposed? : False<br> ' Default? : True<br> ' VBRocks<br> <br> 'The Output from this example is<br> ' (If "No" was clicked)<br> ' (changes cancelled):<br> <br> ' Original? : True<br> ' Gary<br> ' Current? : True<br> ' Gary<br> ' Proposed? : False<br> ' Default? : True<br> ' Gary</span>
</p>
</div>
</div>
</div> <p> <br /><strong><u>Example 3</u></strong> <br />Since we have a table with a row in it that contains changes, and is now in a “Modified” RowState, it’s a perfect time to talk about <strong>AcceptChanges</strong> and <strong>RejectChanges</strong><em>:</em>  <br /> <br />Calling <em>AcceptChanges</em> on a DataRow completely commits the changes, copying the values from the Current row version to the Original row version, and then changing the RowState of the Current row version from “Modified” to “Unchanged”. <br /> <br />Calling <em>RejectChanges</em> on a DataRow completely discards the changes, rolling them back by copying the values from the Original row version to the Current row version, and then changing the RowState of the Current row version from “Modified” to “Unchanged”. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9cce6bc4-9982-4906-88cb-155f266fc83a" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Begin the editing process<br> ' (Proprosed row version is created<br> ' and populated with the change<br> ' we make below)</span><br> row.BeginEdit()<br> <br> <span style="color:#008000">'Change the FirstName</span><br> row.Item(<span style="color:#a31515">"FirstName"</span>) = <span style="color:#a31515">"VBRocks"<br> <br> </span><span style="color:#008000">'Commit the changes to the row<br> ' (copies the values from the<br> ' Proposed row version to the <br> ' Current row version)</span><br> row.EndEdit()<br> <br> <br> <span style="color:#008000">'Call the ShowRowVersions method above</span><br> ShowRowVersions(row)<br> <br> <span style="color:#008000">' Original? : True<br> ' Gary<br> ' Current? : True<br> ' VBRocks<br> ' Proposed? : False<br> ' Default? : True<br> ' VBRocks<br> <br> <br> 'Now, Reject the changes, and roll<br> ' back the Current row version <br> ' to the Original row version.</span><br> row.RejectChanges()<br> <br> <br> <span style="color:#008000">'Call the ShowRowVersions method above</span><br> ShowRowVersions(row)<br> <br> <span style="color:#008000">' Original? : True<br> ' Gary<br> ' Current? : True<br> ' Gary<br> ' Proposed? : False<br> ' Default? : True<br> ' Gary</span>
</p>
</div>
</div>
</div> <p> <br /><strong><u>Example 4</u></strong> <br />Rows can be added, then edited without calling <em>BeginEdit </em>or <em>EndEdit</em>, all we have to do is add the row, then change the row’s <em>Item</em> property.  When the value of a column in a row is changed using the <em>Item </em>property, the changes are committed, and the Current row version is automatically updated (although they can still be discarded if <em>RejectChanges</em> is called). <br /> <br />A DataRow also has a <strong>Delete</strong> method that can be called.  The <em>Delete</em> method does not actually remove the row from the table, but rather changes the RowState to “Deleted”, and and removes all versions of the row.  <br /> <br /><em>The reason the row is not removed from the table, is because, if the row came from a database, then the database needs to be notified that the row has been deleted.  If the row had been completely removed from the table when the delete method was called, the database would have no way of knowing the row was deleted, and should be removed from the database.  <br /> <br />** We haven’t discussed how to work with databases at all, that will be covered in a separate blog later, when DataAdapters are discussed. **</em> <br /> <br />Here’s an example: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bb25d665-8761-40bd-a4df-0732850dc751" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Add a new row to the table,with <br> ' FirstName being set to "Gary"</span><br> table.Rows.Add(<span style="color:#a31515">"Gary"</span>)<br> <br> <span style="color:#008000">'Get a reference to the row we just added<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow = table.Rows(0)<br> <br> <span style="color:#008000">'Change the FirstName<br> ' (BeginEdit and EndEdit are not called)</span><br> row.Item(<span style="color:#a31515">"FirstName"</span>) = <span style="color:#a31515">"VBRocks"<br> <br> </span><span style="color:#008000">'Call the delete method on the row</span><br> row.Delete()<br> <br> <br> ShowRowVersions(row)<br> <br> <span style="color:#008000">'The Output from this example is:<br> <br> ' Original? : False<br> ' Current? : False<br> ' Proposed? : False<br> ' Default? : False</span>
</p>
</div>
</div>
</div> <p> <br /><strong><u>Example 5</u></strong> <br /><u>DataRow Column Errors</u> <br />A DataRow not only has the ability to store row specific error information in the DataRow’s <em>RowError</em> property, but it also has the ability to store information about errors that occur in particular columns.  The error information can be set, retrieved and even cleared using the <strong>SetColumnError</strong>, <strong>GetColumnError</strong>, and <strong>ClearErrors</strong> methods, and the actual array of the columns containing errors can be retrieved using the <strong>GetColumnsInError</strong> method. <br /> <br />Here’s an example of working with column errors, and working with the <strong>IsNull</strong> method of the DataRow: <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2b04cdde-5cc5-4f02-bb31-a1eb8000de5d" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Add a columns</span><br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> table.Columns.Add(<span style="color:#a31515">"LastName"</span>)<br> <br> <span style="color:#008000">'Add a new row to the table, with <br> ' FirstName being set to "Gary"<br> ' LastName being set to Nothing</span><br> table.Rows.Add(<span style="color:#a31515">"Gary"</span>, <span style="color:#0000ff">Nothing</span>)<br> <br> <span style="color:#008000">'Get a reference to the row we just added<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow = table.Rows(0)<br> <br> <span style="color:#008000">'We just added a new row that has a <br> ' FirstName, but no LastName.<br> ' We will test for this, and set<br> ' an error if this is true.<br> </span><span style="color:#0000ff">If</span> row.IsNull(<span style="color:#a31515">"LastName"</span>) <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'Pass the name of the column to set</span><br> <span style="color:#008000">' the error in, and the error </span><br> <span style="color:#008000">' message.</span><br> row.SetColumnError(<span style="color:#a31515">"LastName"</span>, _<br> <span style="color:#a31515">"LastName is required!"</span>)<br> <br> <span style="color:#0000ff">Else</span><br> <span style="color:#008000">'Set the error to "", which in effect</span><br> <span style="color:#008000">' clears the errors for this column.</span><br> row.SetColumnError(<span style="color:#a31515">"LastName"</span>, <span style="color:#a31515">""</span>)<br> <br> <span style="color:#008000">'As a note, this Else block of the </span><br> <span style="color:#008000">' If row.IsNull structure will clear</span><br> <span style="color:#008000">' previous errors, if there were any.</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' So, if an error was already set,</span><br> <span style="color:#008000">' because the LastName was missing,</span><br> <span style="color:#008000">' then the problem was corrected, and </span><br> <span style="color:#008000">' then this code was executed again,</span><br> <span style="color:#008000">' the error would be cleared.<br> </span><span style="color:#0000ff">End</span> <span style="color:#0000ff">If<br> <br> <br> </span><span style="color:#008000">'Now we can see if the row has any errors<br> ' and if so, report them<br> </span><span style="color:#0000ff">If</span> row.HasErrors = <span style="color:#0000ff">True</span> <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'Get an array of the columns with errors</span><br> <span style="color:#0000ff">Dim</span> errorColumns() <span style="color:#0000ff">As</span> DataColumn<br> errorColumns = row.GetColumnsInError()<br> <br> <span style="color:#008000">'Loop through each of the columns that</span><br> <span style="color:#008000">' have errors and report the error</span><br> <span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> col <span style="color:#0000ff">As</span> DataColumn <span style="color:#0000ff">In</span> errorColumns<br> <br> <span style="color:#008000">'Get the error message from the column.</span><br> <span style="color:#0000ff">Dim</span> errorMessage <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span><br> errorMessage = row.GetColumnError(col)<br> <br> MessageBox.Show(errorMessage)<br> <br> <span style="color:#0000ff">Next<br> <br> End</span> <span style="color:#0000ff">If<br> <br> <br> </span><span style="color:#008000">'To clear all of the errors from the row<br> ' including all errors set using the <br> ' DataRow's RowError property and the <br> ' SetColumnError method:</span><br> row.ClearErrors() </p>
</div>
</div>
</div> <p> <br /><strong><u>Example 6 <br /></u></strong>After a DataRow has beed added to a table, and <em>AcceptChanges</em> has been called, setting the RowState to “Unmodified”, the RowState can be programmatically changed to either Added or Modified. <br /> <br /><em>A simple example of why this would be useful is, if you are moving data from one database to another:  As soon as you fill the DataTable using a DataAdapter, you can loop through each row in the table and change its RowState to “Added”, then change the DataAdapter’s connection string, and call it’s Update method to insert the records into the destination database. <br /> <br />We haven’t covered DataAdapters in this article, so I’m being very brief in this example.  But hopefully you’ll get an idea of why it would be useful to be able to programmatically change the RowState.</em></p> <p> </p> <p>Having said, that, here’s an example: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cdcfd3bc-c600-4241-84fa-c52229e67cf5" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Add a column</span><br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> <br> <span style="color:#008000">'Add a row to the table and accept changes</span><br> table.LoadDataRow( _<br> <span style="color:#0000ff">New</span> <span style="color:#0000ff">Object</span>() {<span style="color:#a31515">"Gary"</span>}, <span style="color:#0000ff">True</span>)<br> <br> <span style="color:#008000">'Get a reference to the row we added<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow = table.Rows(0)<br> <br> <span style="color:#008000">'Write out the RowState (Unchanged)<br> ' (View Output Window)</span><br> Debug.WriteLine(<span style="color:#a31515">"RowState: "</span> & _<br> row.RowState.ToString())<br> <br> <span style="color:#008000">'Change the RowState to Added</span><br> row.SetAdded()<br> <br> <span style="color:#008000">'Write out the RowState (Added)</span><br> Debug.WriteLine(<span style="color:#a31515">"RowState: "</span> & _<br> row.RowState.ToString())<br> <br> <span style="color:#008000">'Accept Changes to change RowState back<br> ' to "Unmodified", otherwise an error<br> ' will occur if we attempt to change <br> ' the RowState</span><br> row.AcceptChanges()<br> <br> <span style="color:#008000">'Change the RowState to Modified</span><br> row.SetModified()<br> <br> <span style="color:#008000">'Write out the RowState (Modified)</span><br> Debug.WriteLine(<span style="color:#a31515">"RowState: "</span> & _<br> row.RowState.ToString()) </p>
</div>
</div>
</div> <p> </p> <p> <br /></p> <h4><u>DataTable</u></h4> <p> </p> <p>As of this point, we have pretty thoroughly covered the DataColumn and the DataRow, and are now ready to dive into the DataTable. <br /> <br />There are 2 types of DataTables:  The “Typed” DataTable that gets added to a “Typed” DataSet that you add to your project and configure in a Designer (in an open project:  Project Menu | Add New Item… | DataSet), and the “UnTyped” DataTable that you create and configure programmatically. So far, we have only been working with “UnTyped” DataTables.  <br /> <br />Whether we work with a “Typed” or “UnTyped” DataTable, the properties, methods and events remain the same.  Let’s start with looking at the properties.  <br /> <br /> <br /><strong><u>DataTable Properties</u></strong>: <br /> <br /><strong>CaseSensitive</strong>:  A True or False value that indicates whether string comparisons within the table are case sensitive.  <br /> <br /><em>An example of this is the DataTable has a <u>Find</u> method (we’ll cover later) that searches for a specified key.  If CaseSensitive is True and you are searching for “GARY”, and you enter “gary”, then it will not be found.</em> <br /> <br /><strong>ChildRelations</strong>:  Retrieves a collection of the child relations for the table.</p> <p> </p> <p><strong>Columns</strong>:  Retrieves a collection of the table’s DataColumns. <br /> <br /><strong>Constraints</strong>:  Retrieves a collection of the constraints for the table. <br /> <br /><strong>DataSet</strong>:  Returns the DataSet that the table belongs to.  If the table doesn’t belong to a DataSet, then Nothing is returned. <br /> <br /><strong>DefaultView</strong>:  Returns the Default DataView for the table. <br /> <br /><em>A DataView is simply a “view” of the data that can be sorted, filtered, and even bound to the controls of a user interface.</em> <br /> <br /><strong>DesignMode</strong>:  True or False value that indicates whether the DataTable is in design more or not.  (This will always be False for a “UnTyped” DataTable). <br /> <br /><strong>ExtendedProperties</strong>:  This property is a collection (HashTable) that can be used to store custom information of any data type.  However, if the table is going to be written to XML, any data that is not of the String data type will not be persisted. <br /> <br /><em>The ExtendedProperties property of the DataTable works the exact same as the ExtendedProperties property of the DataColumn, except it applies to the table and not to columns.  See the ExtendedProperties property of the DataColumn for an example.</em> <br /> <br /><strong>HasErrors</strong>:  True or False value that indicates whether there are errors in any of the rows that are in the table. <br /> <br /><strong>IsInitialized</strong>:  True or False value that indicates whether the DataTable is initialized. <br /> <br /><strong>Locale</strong>:  This property returns the CultureInfo information that is used to compare strings within the table. <br /> <br /><strong>MinimumCapacity</strong>:  An Integer value that indicates how many rows the table will allocate memory for before it is filled with data.  The default value is 50. <br /> <br /><em>This property can increase the performance of a DataTable being filled with large amounts of rows from a database, if it is set to the approximate number of rows before being filled.  If the data filling the table has more rows than the MinimumCapacity, then ADO.NET will automatically request more memory for the table.</em> <br /> <br /><strong>Namespace</strong>:  This property contains the namespace that will be used when the contents of the DataTable are written to XML (as with the <em>WriteXml </em>method), or loaded from XML into the DataTable. <br /> <br /><strong>ParentRelations</strong>:  Retrieves a collection of the parent relations for the table. <br /><strong>Prefix</strong>:  This property contains the prefix for the namespace that will be used when the contents of the DataTable are written to XML, or loaded from XML into the DataTable.  The DataTable Prefix applies to the DataTable only, while the DataColumn Prefix applies to the DataColumn only. <br /> <br /><strong>PrimaryKey</strong>:  An array of DataColumns that are used as primary keys for the DataTable. <br /> <br /><strong>RemotingFormat</strong>:  The serialization format that indicates whether the DataTable is remoted to Binary or Xml format.  The default is XML. <br /> <br /><strong>Rows</strong>:  Retrieves a collection of the table’s DataRows. <br /> <br /><strong>TableName</strong>:  The name of the table. <br /> <br /> <br /><strong><u>Examples</u></strong>:</p> <p> <br />Now that we are familiar with the common properties of the DataTable, we can begin to look at how to use them. <br /> <br /><strong><u>Example 1 <br /></u></strong>Since we’ve already looked at the DataColumn and the DataRow above, we’ll demonstrate adding <strong>Columns</strong> and <strong>Rows</strong>, then looping through them to access information. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:15eb954b-3c51-43ed-b3f4-f77cd3df4a5a" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> table.Columns.Add(<span style="color:#a31515">"LastName"</span>)<br> <br> <span style="color:#008000">'Add rows:</span><br> table.Rows.Add(<span style="color:#a31515">"MICHAEL"</span>, <span style="color:#a31515">"LAVERGNE"</span>)<br> table.Rows.Add(<span style="color:#a31515">"GARY"</span>, <span style="color:#a31515">"LIMA"</span>)<br> table.Rows.Add(<span style="color:#a31515">"TOM"</span>, <span style="color:#a31515">"MESSNER"</span>)<br> table.Rows.Add(<span style="color:#a31515">"CASEY"</span>, <span style="color:#a31515">"KNOWLES"</span>)<br> table.Rows.Add(<span style="color:#a31515">"RICK"</span>, <span style="color:#a31515">"SAUER"</span>)<br> <br> <span style="color:#008000">'Loop through the columns in the table:<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> col <span style="color:#0000ff">As</span> DataColumn <span style="color:#0000ff">In</span> table.Columns<br> <br> Debug.WriteLine(col.ColumnName) : <span style="color:#0000ff">Next<br> <br> <br> </span><span style="color:#008000">'Loop through each row in the table and<br> ' output the FirstName and LastName:<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> row <span style="color:#0000ff">As</span> DataRow <span style="color:#0000ff">In</span> table.Rows<br> <br> Debug.WriteLine(row.Item(<span style="color:#a31515">"FirstName"</span>) & _<br> <span style="color:#a31515">" "</span> & row.Item(<span style="color:#a31515">"LastName"</span>))<br> <br> <span style="color:#0000ff">Next<br> <br> </span><span style="color:#008000">'View the Output Window to see results</span>
</p>
</div>
</div>
</div> <p> <br /><strong><u>Example 2</u></strong> <br />A <strong>PrimaryKey</strong> is a special “key” for a DataTable that is used to identify rows in a table.  When a table has a PrimaryKey, each row in the table has a unique key.  Because this key is unique, no other row can have the same exact key. <br /> <br />Many times developers choose to use AutoIncrementing numbers as the PrimaryKey for a table, but anything can be used, as long as it’s unique.  For example, you may choose to use First Names, Last Names, Phone Numbers, Social Security Numbers, etc. in a table containing employee information. <br /> <br />However, sometimes First Names are not unique enough, because you may have several people in your table that have the same name.  Therefore, you may consider using a combination of First Names and Last Names. <br /> <br />PrimaryKey Combinations of First Names and Last Names are possible because the PrimaryKey can be set to one or more DataColumns within the table. <br /> <br />Here’s an example of working with PrimaryKeys: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d98e25d7-e5ad-40ff-b771-49a9a55cd497" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> table.Columns.Add(<span style="color:#a31515">"LastName"</span>)<br> <br> <br> <span style="color:#008000">'Set 1 column as the PrimaryKey<br> <br> 'Get a reference to the FirstName Column<br> </span><span style="color:#0000ff">Dim</span> colFirstName <span style="color:#0000ff">As</span> DataColumn<br> colFirstName = table.Columns(<span style="color:#a31515">"FirstName"</span>)<br> <br> <span style="color:#008000">'Set the FirstName col as the PrimaryKey</span><br> table.PrimaryKey = _<br> <span style="color:#0000ff">New</span> DataColumn() {colFirstName}<br> <br> <br> <span style="color:#008000">'Set 2 columns as the PrimaryKey<br> <br> 'Get a reference to the LastName Column<br> </span><span style="color:#0000ff">Dim</span> colLastName <span style="color:#0000ff">As</span> DataColumn<br> colLastName = table.Columns(<span style="color:#a31515">"LastName"</span>)<br> <br> <span style="color:#008000">'Set the FirstName and LastName columns<br> ' as the PrimaryKey</span><br> table.PrimaryKey = _<br> <span style="color:#0000ff">New</span> DataColumn() {colFirstName, colLastName}<br> <br> </p>
</div>
</div>
</div> <p> <br /><strong><u>Example 3</u></strong> <br />The <strong>CaseSensitive</strong> property is False by default, which is the best of the two possibilities for standard string comparisons that are performed within the DataTable, because it lends itself to more flexibility, and more expected results.  It is possible, however, to set this property to True, if you desire string comparisons to perform an exact match. <br /> <br />If CaseSensitive is False, then a search for a FirstName of “gary” will be a direct match for a row containing a FirstName of “GARY”.  Which is pretty much what you would expect. <br /> <br />If CaseSensitive is True, then a search for a FirstName of  “gary” will return no results, even if there is a row containing a FirstName of “GARY”. <br /> <br /><em>This example will use the <strong>Find</strong> method of the DataTable to demonstrate CaseSensitive String Comparisons within the DataTable.  In order to use the Find method of the DataTable, the table must have a PrimaryKey configured. <br />  <br /></em></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:433735c9-d89d-4488-beb1-9dad29f17173" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> <br> <span style="color:#008000">'Get a reference to the FirstName Column<br> </span><span style="color:#0000ff">Dim</span> colFirstName <span style="color:#0000ff">As</span> DataColumn<br> colFirstName = table.Columns(<span style="color:#a31515">"FirstName"</span>)<br> <br> <span style="color:#008000">'Set the FirstName col as the PrimaryKey</span><br> table.PrimaryKey = _<br> <span style="color:#0000ff">New</span> DataColumn() {colFirstName}<br> <br> <br> <span style="color:#008000">'Add rows:</span><br> table.Rows.Add(<span style="color:#a31515">"MICHAEL"</span>)<br> table.Rows.Add(<span style="color:#a31515">"GARY"</span>)<br> table.Rows.Add(<span style="color:#a31515">"TOM"</span>)<br> table.Rows.Add(<span style="color:#a31515">"CASEY"</span>)<br> table.Rows.Add(<span style="color:#a31515">"RICK"</span>)<br> <br> <br> <span style="color:#008000">'CaseSensitive is False by default<br> 'table.CaseSensitive = False<br> <br> 'Stores any matching row<br> </span><span style="color:#0000ff">Dim</span> foundRow <span style="color:#0000ff">As</span> DataRow<br> <br> <span style="color:#008000">'Attempt to find a row that has<br> ' the value "gary" in the FirstName<br> ' column</span><br> foundRow = table.Rows.Find(<span style="color:#a31515">"gary"</span>)<br> <br> <span style="color:#008000">'Test for search results<br> </span><span style="color:#0000ff">If</span> foundRow <span style="color:#0000ff">Is</span> <span style="color:#0000ff">Nothing</span> <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'"gary" was not found</span><br> MessageBox.Show(<span style="color:#a31515">"No Match"</span>)<br> <span style="color:#0000ff">Else</span><br> <span style="color:#008000">'"gary was found</span><br> MessageBox.Show(<span style="color:#a31515">"Match"</span>)<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If<br> <br> <br> </span><span style="color:#008000">'Set CaseSensitive to True</span><br> table.CaseSensitive = <span style="color:#0000ff">True<br> <br> </span><span style="color:#008000">'Attempt to find a row that has<br> ' the value "gary" in the FirstName<br> ' column</span><br> foundRow = table.Rows.Find(<span style="color:#a31515">"gary"</span>)<br> <br> <span style="color:#008000">'Test for search results<br> </span><span style="color:#0000ff">If</span> foundRow <span style="color:#0000ff">Is</span> <span style="color:#0000ff">Nothing</span> <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'"gary" was not found</span><br> MessageBox.Show(<span style="color:#a31515">"No Match"</span>)<br> <span style="color:#0000ff">Else</span><br> <span style="color:#008000">'"gary was found</span><br> MessageBox.Show(<span style="color:#a31515">"Match"</span>)<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If</span>
</p>
</div>
</div>
</div> <p><em> <br /></em></p> <p><strong><u>Example 4</u></strong> <br />The <strong>Locale</strong> property of the DataTable provides access to the culture info that is used when performing string comparisons within the DataTable.  By default, the culture info will be the same as your system’s.  However, you may desire to change this.  <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:63b069cd-f4cf-467d-9731-d641b6a41c6e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Change the Culture to Australian English</span><br> table.Locale = _<br> <span style="color:#0000ff">New</span> System.Globalization.CultureInfo(<span style="color:#a31515">"en-AU"</span>)<br> <br> Debug.WriteLine(table.Locale.DisplayName)<br> <br> <span style="color:#008000">'View Output Window</span>
</p>
</div>
</div>
</div> <p> <br /><strong><u>Example 5 <br /></u></strong>Although we have not covered DataSets in this article, the DataTable has a DataSet property that returns a reference to the DataSet that the DataTable belongs to, if any, or it returns Nothing if it does not belong to a DataSet. <br /> <br />In brief, a DataSet is conceptually similar to a database, in that it is the “container” that contains DataTables and DataRelations, etc.  We’ll cover DataSets in a separate article. <br /> <br />For now, we’ll give a brief example of the <strong>DataSet</strong> property of the DataTable, and the <strong>TableName</strong> property of the DataTable: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:24d856d8-6303-4e03-8e61-e5d5a63b6b9b" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Set the name of the table</span><br> table.TableName = <span style="color:#a31515">"Employee"<br> <br> </span><span style="color:#008000">'Add columns</span><br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> table.Columns.Add(<span style="color:#a31515">"LastName"</span>)<br> <br> <span style="color:#008000">'Create a new DataSet and add the table<br> </span><span style="color:#0000ff">Dim</span> ds <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataSet(<span style="color:#a31515">"DataSet1"</span>)<br> ds.Tables.Add(table)<br> <br> <span style="color:#008000">'Access the table's DataSet property<br> ' and write out the DataSetName</span><br> Debug.WriteLine(table.DataSet.DataSetName)<br> <br> <span style="color:#008000">'View the Output Window for results</span>
</p>
</div>
</div>
</div> <p> <br /></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p></p> <p><strong><u>Example 6</u></strong> <br />The <strong>DefaultView</strong> property of the DataTable returns a DataView, which is a manipulative “view” of the data that can be searched, sorted, and filtered by expression or RowState.  We will not embark on a thorough analysis of the DataView here, but will briefly demonstrate accessing it an using some of it’s features. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:47c812ec-ff87-4ab9-bb8c-1776bc1773a0" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> <br> <span style="color:#008000">'Add rows:</span><br> table.Rows.Add(<span style="color:#a31515">"MICHAEL"</span>)<br> table.Rows.Add(<span style="color:#a31515">"GARY"</span>)<br> table.Rows.Add(<span style="color:#a31515">"TOM"</span>)<br> table.Rows.Add(<span style="color:#a31515">"CASEY"</span>)<br> table.Rows.Add(<span style="color:#a31515">"RICK"</span>)<br> <br> <span style="color:#0000ff">Dim</span> output <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = <span style="color:#0000ff">String</span>.Empty<br> <br> <span style="color:#008000">'Get a reference to the DataView<br> ' of the DataTable<br> </span><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> DataView = table.DefaultView<br> <br> <span style="color:#008000">'Loop through both the DataView and <br> ' the DataTable to view it's contents<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> view.Count - 1<br> <br> output = <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"{0,-10}{1}"</span>, _<br> view(i).Item(<span style="color:#a31515">"FirstName"</span>), _<br> table.Rows(i).Item(<span style="color:#a31515">"FirstName"</span>))<br> <br> Debug.WriteLine(output)<br> <br> <span style="color:#0000ff">Next<br> <br> <br> </span><span style="color:#008000">'Sort the View, then loop through both<br> ' of them again</span><br> view.Sort = <span style="color:#a31515">"FirstName ASC"<br> <br> </span><span style="color:#008000">'Loop through both the DataView and <br> ' the DataTable to view it's contents<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> view.Count - 1<br> <br> output = <span style="color:#0000ff">String</span>.Format(<span style="color:#a31515">"{0,-10}{1}"</span>, _<br> view(i).Item(<span style="color:#a31515">"FirstName"</span>), _<br> table.Rows(i).Item(<span style="color:#a31515">"FirstName"</span>))<br> <br> Debug.WriteLine(output)<br> <br> <span style="color:#0000ff">Next<br> <br> <br> </span><span style="color:#008000">'Filter the View for all FirstNames with<br> ' an "a" in them, and then loop through it</span><br> view.RowFilter = <span style="color:#a31515">"FirstName LIKE '%a%'"<br> </span><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> view.Count - 1<br> <br> Debug.WriteLine(view(i).Item(<span style="color:#a31515">"FirstName"</span>))<br> <br> <span style="color:#0000ff">Next<br> <br> </span><span style="color:#008000">'View the Output Window for results</span>
</p>
</div>
</div>
</div> <p> <br /><strong><u>Example 7</u></strong> <br />The <strong>Namespace</strong> and <strong>Prefix</strong> properties can be used to set an XML namespace and prefix for your DataTable.  This namespace and prefix will be used when the contents of the DataTable are written to XML.</p> <p> <br /><em>As a note, Namespaces are often URI’s.  These URI’s look like they point to a location on the web, but they do not.  The purpose of the Namespace is not to point to a location on the web, but to give the namespace a unique name.  The URI’s are not even used to look up information.  Organizations may use their website url as a namespace, but essentially, it can be anything. <br /> <br />The Prefix is kind of like a variable that points to the Namespace, and allows the Namespace to be easily referenced in the XML document.  However, the DataTable has it’s own Prefix, and each DataColumn in the table has it’s own Prefix.</em> <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:711ea928-e76c-4515-9afd-2a75906e0630" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable(<span style="color:#a31515">"Employee"</span>)<br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> <br> <span style="color:#008000">'Add a row of data</span><br> table.Rows.Add(<span style="color:#a31515">"Gary"</span>)<br> <br> <span style="color:#008000">'Set the Namespace and Prefix</span><br> table.Namespace = _<br> <span style="color:#a31515">"http://www.garylima.blogspot.com"</span><br> <br> table.Prefix = <span style="color:#a31515">"vb"<br> <br> </span><span style="color:#008000">'Write the data to an XML file:</span><br> table.WriteXml(<span style="color:#a31515">"data.xml"</span>)
</p>
</div>
</div>
</div> <p> <br />The XML output file “data.xml” looks like this: <br /><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/SoXX53iZg6I/AAAAAAAAAKs/52NBDIdJ6EA/s1600-h/xml%20file%5B6%5D.jpg"><img style="border-right-width: 0px; width: 445px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="xml file" border="0" alt="xml file" align="left" src="http://lh5.ggpht.com/_dhkDWtu14Jc/SoXX6cXSOzI/AAAAAAAAAKw/l9ZbyRo8hO8/xml%20file_thumb%5B4%5D.jpg?imgmax=800" width="445" height="89" /></a> <br /> <br /> <br /> <br /> <br /></p> <p> <br /> <br /> <br />Notice:  xmlns:v=”http://www.garylima.blogspot.com” <br /> <br />Also notice how the “v” prefixes the table name:  “<v:Employee>” <br />And how the “v” prefixes the column name:  “<v:FirstName>” <br /> <br /><strong><u>Example 8</u></strong> <br />The example above included in it’s demonstration an example of writing the contents of the DataTable out to an XML file.  Not only can the contents of a DataTable be written out in XML format, they can also be written out in a compact binary format.  To make this happen, just change the RemotingFormat property to binary, then use a FileStream and BinaryFormatter to write the data out to a file. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9e6c4df0-e34a-4507-94ba-d94339a7da1f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a new Employee DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable(<span style="color:#a31515">"Employee"</span>)<br> table.Columns.Add(<span style="color:#a31515">"FirstName"</span>)<br> <br> <span style="color:#008000">'Add a row of data</span><br> table.Rows.Add(<span style="color:#a31515">"Gary"</span>)<br> <br> <span style="color:#008000">'Change the RemotingFormat to binary</span><br> table.RemotingFormat = SerializationFormat.Binary<br> <br> <span style="color:#008000">'Create a new file<br> </span><span style="color:#0000ff">Dim</span> fs <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> _<br> IO.FileStream(<span style="color:#a31515">"data.bin"</span>, IO.FileMode.Create)<br> <br> <span style="color:#008000">'Create a new instance of a BinaryFormatter<br> </span><span style="color:#0000ff">Dim</span> formatter <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> System.Runtime.Serialization _<br> .Formatters.Binary.BinaryFormatter()<br> <br> <span style="color:#008000">'Serialize the table to the file</span><br> formatter.Serialize(fs, table)<br> <br> <span style="color:#008000">'Close the file</span><br> fs.Close()<br> <br> <br> <span style="color:#008000">'Load the data from the file:</span><br> fs = <span style="color:#0000ff">New</span> IO.FileStream(<span style="color:#a31515">"data.bin"</span>, IO.FileMode.Open)<br> <br> <span style="color:#008000">'Deserialize the table<br> </span><span style="color:#0000ff">Dim</span> table2 <span style="color:#0000ff">As</span> DataTable = _<br> <span style="color:#0000ff">DirectCast</span>(formatter.Deserialize(fs), DataTable)<br> <br> fs.Close()<br> <br> <span style="color:#008000">'Write to Output Window</span><br> Debug.WriteLine(table2.Rows(0).Item(<span style="color:#a31515">"FirstName"</span>))
</p>
</div>
</div>
</div> <p> <br />The binary output file “data.bin” looks like this: <br /> <br /></p> <p><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/SoXX6j0-GiI/AAAAAAAAAK0/swpgmASKnyE/s1600-h/binary%20file%5B5%5D.jpg"><img style="border-right-width: 0px; width: 451px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="binary file" border="0" alt="binary file" align="left" src="http://lh6.ggpht.com/_dhkDWtu14Jc/SoXX7DwAo6I/AAAAAAAAAK4/oSKE3wgkFEw/binary%20file_thumb%5B3%5D.jpg?imgmax=800" width="451" height="68" /></a>  <br /></p> <p> <br /></p> <strong><u></u></strong> <p><strong><u>DataTable Methods</u></strong> <br /> <br />Here is a list of the commonly used DataTable methods: <br /> <br /><strong>AcceptChanges</strong>:  Commits all pending changes withing a DataTable. <br /> <br /><strong>BeginLoadData</strong>:  Turns off error notifications, index maintenance and constraints while loading. <br /> <br /><strong>Clear</strong>:  Removes all rows from the DataTable, while leaving all columns in place. <br /> <br /><strong>Clone</strong>:  Copies the structure of the DataTable, including schema info and constraints, but not the data. <br /> <br /><strong>Compute</strong>:  Calculates the provided expression on the current rows that meet the filter criteria. <br /> <br /><strong>Copy</strong>:  Copies the structure and data of the DataTable. <br /> <br /><strong>CreateDataReader</strong>:  Creates a read-only, forward-only DataTableReader for the DataTable, which contains the current version all of the data in the table, except for deleted rows. <br /> <br /><strong>EndLoadData</strong>:  Turns on error notifications, index maintenance and constraints while loading.  <br /> <br /><strong>GetChanges</strong>:  Retrieves a copy of the DataTable containing all changes made to it since <em>AcceptChanges</em> was called. <br /> <br /><strong>GetErrors</strong>:  Retrieves an array of DataRows that have errors. <br /> <br /><strong>ImportRow</strong>:  Copies a DataRow into the DataTable, including original and current values, while preserving any property settings. <br /> <br /><strong>Load</strong>:  Fills the DataTable with data from a DataReader. <br /> <br /><strong>LoadDataRow</strong>:  Finds and updates a specific row, or creates a new row if now row was found. <br /> <br /><strong>NewRow</strong>:  Creates a new DataRow that has the same schema (<em>columns</em>) as the DataTable. <br /> <br /><strong>ReadXml</strong>:  Reads XML schema and data from an XML stream into the DataTable. <br /> <br /><strong>ReadXmlSchema</strong>:  Reads XML schema only (no data) from an XML stream into the DataTable. <br /> <br /><strong>RejectChanges</strong>:  Rolls back all pending changes that have been made to the data in the table since <em>AcceptChanges</em> was called. <br /> <br /><strong>Reset</strong>:  Resets the DataTable to it’s original state. If you programmatically created the DataTable, then it will remove all columns and rows from the table. <br /> <br /><strong>Select</strong>:  Retrieves an array of DataRows that match the filter criteria. <br /> <br /><strong>WriteXml</strong>:  Writes the contents of the DataTable to an XML stream. <br /> <br /><strong>WriteXmlSchema</strong>:  Write the DataTable’s structure as an XML schema to an XML stream. <br /> <br /></p> <p><strong>Examples</strong> <br />So now that we’ve had a chance to learn about the methods of the DataTable, let’s take a look at how to use them. <br /> <br /> <br /><strong><u>Example 1 <br /></u></strong>To begin with, the DataTable has a <strong>BeginLoadData</strong> and a <strong>EndLoadData</strong> methods.  As indicated above, they turn Off and On (respectively) error notifications, index maintenance and constraints.  <br /> <br /><em>Note:  this table will be used for all examples below, unless specified.</em> <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4e509018-a9c9-4ed6-9fa7-e8b80b68b10e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Connecting to AdventureWorksDB located at:<br> ' http://www.codeplex.com/MSFTDBProdSamples/<br> ' Release/ProjectReleases.aspx?ReleaseId=4004<br> <br> 'SQL Server connection string<br> </span><span style="color:#0000ff">Dim</span> cnString <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = _<br> <span style="color:#a31515">"Data Source=localhost;"</span> & _<br> <span style="color:#a31515">"Initial Catalog='ADVENTUREWORKS_DATA';"</span> & _<br> <span style="color:#a31515">"Integrated Security=True"<br> <br> </span><span style="color:#008000">'Select all persons from contact table<br> </span><span style="color:#0000ff">Dim</span> SQL <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span> = <span style="color:#a31515">"SELECT * FROM Person.Contact"<br> <br> </span><span style="color:#008000">'Create a new DataTable<br> </span><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> <br> <span style="color:#008000">'Turn OFF error notification, index maintenance<br> ' and constraints</span><br> table.BeginLoadData()<br> <br> <span style="color:#008000">'Fill the table with data from the database<br> ' Note: DataAdapters will be covered in a <br> ' separate section<br> </span><span style="color:#0000ff">Using</span> adapter <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> System.Data _<br> .SqlClient.SqlDataAdapter(SQL, cnString)<br> <br> adapter.Fill(table) : <span style="color:#0000ff">End</span> <span style="color:#0000ff">Using<br> <br> <br> </span><span style="color:#008000">'Turn ON error notification, index maintenance<br> ' and constraints</span><br> table.EndLoadData() </p>
</div>
</div>
</div> <p> <br /><strong><u>Example 2</u></strong> <br />The Clone method of the DataTable copies the structure, schema info and constraints, but not the data. <br /> <br />Here’s an example of using the <strong>Clone</strong> method, the <strong>ImportRow</strong> method, the <strong>Select</strong> method, and the <strong>Clear</strong> method: </p> <p> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:62b4cca0-d899-4d4e-954e-68f6bd78895d" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Use the DataTables's Select method<br> ' to return an array of DataRows<br> ' matching the Criteria.<br> '<br> ' In this case, only 1 row will be<br> ' returned.<br> </span><span style="color:#0000ff">Dim</span> rows() <span style="color:#0000ff">As</span> DataRow = _<br> table.Select(<span style="color:#a31515">"ContactID=1"</span>)<br> <br> <span style="color:#008000">'Clone the table<br> ' This copies the structure of the<br> ' table without the data<br> </span><span style="color:#0000ff">Dim</span> clonedTable <span style="color:#0000ff">As</span> DataTable<br> clonedTable = table.Clone()<br> <br> <br> <span style="color:#008000">'Import 1 row to our Cloned table</span><br> clonedTable.ImportRow(rows(0))<br> <br> <br> <span style="color:#008000">'Output the clonedTable row count</span><br> Debug.WriteLine(<span style="color:#a31515">"Rows in clonedTable: "</span> & _<br> clonedTable.Rows.Count)<br> <br> <br> <span style="color:#008000">'Loop through each row in the clonedTable<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> row <span style="color:#0000ff">As</span> DataRow <span style="color:#0000ff">In</span> clonedTable.Rows<br> <br> <span style="color:#008000">'Loop through each column in the clonedTable</span><br> <span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> col <span style="color:#0000ff">As</span> DataColumn <span style="color:#0000ff">In</span> _<br> clonedTable.Columns<br> <br> <span style="color:#008000">'Output the contents of the row's column</span><br> Debug.WriteLine(row.Item(col).ToString())<br> <br> <span style="color:#0000ff">Next<br> <br> Next<br> <br> <br> </span><span style="color:#008000">'Remove all rows from the table</span><br> clonedTable.Clear() </p>
</div>
</div>
</div> <p> </p> <p></p> <p></p> <p></p> <p><strong><u>Example 3</u></strong> <br />The Copy method can be used to create a copy of the DataTable, including the structure of the table, and all rows of data. <br /> <br />Also, the Compute method can be used to perform an aggregate calculation for a single column on rows of data based off of the provided expression. <br /> <br />This example demonstrates the <strong>Copy</strong> method, <strong>Compute</strong> method and the <strong>Reset</strong> method: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:869d1628-d051-4440-992a-b70cfe4069c4" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a copy of the DataTable,<br> ' including columns and data.<br> </span><span style="color:#0000ff">Dim</span> copyTable <span style="color:#0000ff">As</span> DataTable = _<br> table.Copy()<br> <br> <span style="color:#0000ff">Dim</span> iNumberOfRows <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span><br> iNumberOfRows = table.Compute(<span style="color:#a31515">"COUNT(ContactID)"</span>, _<br> <span style="color:#a31515">"ContactID < 10"</span>)<br> <br> <span style="color:#008000">'Output the number of rows with a ConactID < 10</span><br> Debug.WriteLine(<span style="color:#a31515">"Rows with a ContactID < 10: "</span> & _<br> iNumberOfRows)<br> <br> <br> <span style="color:#008000">'Resets the table to it's original state.<br> ' Since this is an UnTyped table, it <br> ' Clears the DataTable of all Columns and Rows</span><br> copyTable.Reset() </p>
</div>
</div>
</div> <p> <br /><strong><u>Example 4 <br /></u></strong>A DataTable also has the ability to create a DataReader, which is a read-only, forward-only copy of the data.  Many times DataReaders provide better performance than a DataTable, because DataReaders move quickly through the data, discarding each row after it has passed it.  A DataTable can also use a DataReader to load all of the data. <br /> <br />Here’s an example of using the <strong>CreateDataReader</strong> method and the <strong>Load</strong> method: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:30b1eba8-0437-478a-a1c0-f65df674f02c" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a DataReader for this DataTable<br> </span><span style="color:#0000ff">Dim</span> reader <span style="color:#0000ff">As</span> DataTableReader = _<br> table.CreateDataReader()<br> <br> <span style="color:#008000">'Create a new DataTable and use the<br> ' DataReader to load the DataTable<br> </span><span style="color:#0000ff">Dim</span> table2 <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table2.Load(reader)<br> <br> <span style="color:#008000">'Output the number of rows that have<br> ' been loaded into table2</span><br> Debug.WriteLine(<span style="color:#a31515">"Rows"</span> & table2.Rows.Count)
</p>
</div>
</div>
</div> <p> <br /></p> <p></p> <p><strong><u>Example 5 <br /></u></strong>The DataTable’s <strong>GetErrors</strong> method can be used to retrieve all of the rows in the table that have errors (including row errors and column errors), then each error can be analyzed and processed as desired. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f57b7b24-497f-4989-90f9-f907f850d474" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Get the first row at index 0<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow = table.Rows(0)<br> <br> <span style="color:#008000">'Modify the FirstName and LastName</span><br> row.Item(<span style="color:#a31515">"FirstName"</span>) = <span style="color:#a31515">"Gary"</span><br> row.Item(<span style="color:#a31515">"LastName"</span>) = <span style="color:#a31515">""<br> <br> </span><span style="color:#008000">'Perform some validation<br> ' If the LastName column is empty, then<br> ' set the column error<br> </span><span style="color:#0000ff">If</span> row.Item(<span style="color:#a31515">"LastName"</span>) = <span style="color:#a31515">""</span> <span style="color:#0000ff">Then</span> _<br> row.SetColumnError(<span style="color:#a31515">"LastName"</span>, _<br> <span style="color:#a31515">"LastName required!"</span>)<br> <br> <span style="color:#008000">'Loop through each row that has errors<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> errorRow <span style="color:#0000ff">As</span> DataRow <span style="color:#0000ff">In</span> table.GetErrors()<br> <br> <span style="color:#008000">'Get a DataColumn array of the columns that</span><br> <span style="color:#008000">' have errors.</span><br> <span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> col <span style="color:#0000ff">As</span> DataColumn <span style="color:#0000ff">In</span> _<br> errorRow.GetColumnsInError()<br> <br> <span style="color:#008000">'Output the error for the column</span><br> Debug.WriteLine( _<br> errorRow.GetColumnError(col))<br> <br> <span style="color:#0000ff">Next<br> <br> Next</span>
</p>
</div>
</div>
</div> <p></p> <p> <br /><strong><u>Example 6</u></strong> <br />When changes occur in a DataTable, the GetChanges method can be used to retrieve an array of rows containing those changes.  These changes can be looped through, analyzed and processed, or they can be submitted to a database for updates, such as when there is a hierarchical structure in place and updates need to be made in a particular order. <br /> <br />Here’s an example of how to use the <strong>GetChanges</strong> method to retrieve all of the rows in the DataTable that have been modified, plus the <strong>AcceptChanges</strong> and <strong>RejectChanges</strong> methods: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a4b70d63-81e6-4222-a078-584f06cef252" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Get the first row at index 0<br> </span><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> DataRow = table.Rows(0)<br> <br> <span style="color:#008000">'Modify the FirstName and LastName</span><br> row.Item(<span style="color:#a31515">"FirstName"</span>) = <span style="color:#a31515">"Gary"</span><br> row.Item(<span style="color:#a31515">"LastName"</span>) = <span style="color:#a31515">"Lima"<br> <br> </span><span style="color:#008000">'Create a new table and load with<br> ' all of the rows that have changed.<br> </span><span style="color:#0000ff">Dim</span> changesTable <span style="color:#0000ff">As</span> DataTable = _<br> table.GetChanges(DataRowState.Modified)<br> <br> <span style="color:#008000">'Loop through each changed row<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> changedRow <span style="color:#0000ff">As</span> DataRow <span style="color:#0000ff">In</span> _<br> changesTable.Rows<br> <br> <span style="color:#008000">'Output the changes</span><br> Debug.WriteLine(changedRow.Item(<span style="color:#a31515">"FirstName"</span>))<br> <br> <span style="color:#0000ff">Next<br> <br> <br> </span><span style="color:#008000">'Prompt to accept changes<br> </span><span style="color:#0000ff">Dim</span> result <span style="color:#0000ff">As</span> DialogResult = _<br> MessageBox.Show(<span style="color:#a31515">"Changes have occured! "</span> & _<br> <span style="color:#a31515">"Would you like to Accept these change?"</span>, _<br> <span style="color:#a31515">"Accept Changes"</span>, MessageBoxButtons.YesNo)<br> <br> <span style="color:#008000">'Test result<br> </span><span style="color:#0000ff">If</span> result = Windows.Forms.DialogResult.Yes <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'Accept the changes</span><br> table.AcceptChanges()<br> <span style="color:#0000ff">Else</span><br> <span style="color:#008000">'Reject the changes</span><br> table.RejectChanges()<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If</span>
</p>
</div>
</div>
</div> <p> <br /><strong><u>Example 7 <br /></u></strong>The final methods to look at are methods that support the DataTable’s abilities to read and write from XML stream.  Those methods are:  <strong>ReadXml</strong>, <strong>ReadXmlSchema</strong>, <strong>WriteXml</strong>, and <strong>WriteXmlSchema</strong>. <br /> <br /><em>These are some of my favorite aspects of a DataTable!  If you have a DataTable, and you want to output its contents to a file to save to hard-disk, or to send to someone else, it can be accomplished with 1 line of code!</em> <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3417c2d0-db38-40fa-81e8-dc284acc6957" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Write and Read Xml (all columns and data)<br> <br> 'The TableName must be set before the <br> ' WriteXml and WriteXmlSchema<br> ' methods can be used.<br> </span><span style="color:#0000ff">If</span> table.TableName = <span style="color:#a31515">""</span> <span style="color:#0000ff">Then</span> _<br> table.TableName = <span style="color:#a31515">"Contacts"<br> <br> </span><span style="color:#008000">'Write out the table, including all columns,<br> ' and it's data.</span><br> table.WriteXml(<span style="color:#a31515">"MyTableData.xml"</span>)<br> <br> <span style="color:#008000">'Create a new DataTable to read in the table<br> </span><span style="color:#0000ff">Dim</span> table2 <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> table2.ReadXml(<span style="color:#a31515">"MyTableData.xml"</span>)<br> <br> <span style="color:#008000">'Write out the number of rows in the table</span><br> Debug.WriteLine(<span style="color:#a31515">"Table2 Rows: "</span> & _<br> table2.Rows.Count)<br> <br> <br> <br> <span style="color:#008000">'Write and Read Schema, no data<br> <br> 'Write out just the table's schema, no data.</span><br> table.WriteXmlSchema(<span style="color:#a31515">"MyTableSchema.xml"</span>)<br> <br> <span style="color:#008000">'Read the Schema only, no data<br> </span><span style="color:#0000ff">Dim</span> schemaTable <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> DataTable()<br> schemaTable.ReadXmlSchema(<span style="color:#a31515">"MyTableSchema.xml"</span>)<br> <br> <span style="color:#008000">'Write out the number of rows in the table<br> ' Note: There will be 0 rows, because only<br> ' the schema was read, no data.</span><br> Debug.WriteLine(<span style="color:#a31515">"schemaTable Rows: "</span> & _<br> schemaTable.Rows.Count) </p>
</div>
</div>
</div> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-33900718090335066222009-08-12T12:49:00.001-06:002009-08-14T16:07:51.468-06:00Calculating a Bar Graph Scale<p>I’m not sure if anyone will ever have an need for this, but just to share something interesting… <br /> <br />This morning I was tasked with coming up with a formula for calculating a bar graph scale, based off of the bar graph data.  The scale had to include 3 to 4 numbers that indicate even portions of a maximum number.  For example, if the maximum number in the bar graph is 95, then I had to come up with 25, 50, 75 and 100 in the scale; if the maximum number in the bar graph is 145, the I had to come up with 50, 100 and 150 in the scale, etc. <br /> <br />Here’s an example of a bar graph with 100 as the maximum number in the scale.  The 4 number scale (not including 0) is on the left side:</p> <p> <br /><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/SoMOvEK1S8I/AAAAAAAAAKU/7WEfzXMLU5E/s1600-h/bargraph1%5B6%5D.jpg"><img style="border-right-width: 0px; width: 255px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="bargraph1" border="0" alt="bargraph1" align="left" src="http://lh4.ggpht.com/_dhkDWtu14Jc/SoMOvSQHfCI/AAAAAAAAAKY/Z4Lb2T0W-Ss/bargraph1_thumb%5B4%5D.jpg?imgmax=800" width="255" height="146" /></a> </p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />Here’s an example of a bar graph with 150 as the maximum number in the scale.  The 3 number scale (not including 0) is on the left side:</p> <p> <br /><a href="http://lh3.ggpht.com/_dhkDWtu14Jc/SoMOvo-5tAI/AAAAAAAAAKc/BPxk1pYqAWM/s1600-h/bargraph2%5B4%5D.jpg"><img style="border-right-width: 0px; width: 255px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="bargraph2" border="0" alt="bargraph2" align="left" src="http://lh4.ggpht.com/_dhkDWtu14Jc/SoMOwD_8J1I/AAAAAAAAAKg/MPOSmu2B_3I/bargraph2_thumb%5B2%5D.jpg?imgmax=800" width="255" height="148" /></a> <br /></p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />The first thing I needed to do was compile a list of numbers.  Since my numbers were coming from thousands of records of data, I’ll fabricate some numbers to use for this demonstration. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6cfe831b-48f2-4fac-8c8b-fc51194cde50" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a list of Decimals<br> </span><span style="color:#0000ff">Dim</span> list <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> List(<span style="color:#0000ff">Of</span> <span style="color:#0000ff">Decimal</span>)<br> list.Add(94.2)<br> list.Add(64.8)<br> list.Add(45.4)<br> list.Add(20.1) </p>
</div>
</div>
</div> <p> </p> After I had the list of numbers, I created a scaleList to store a list of the numbers that would be added to my scale. <br /> <p> </p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6da203fc-e3bc-4bb3-af90-dd6e99c45cc3" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Create a list of Integers to store our scale<br> </span><span style="color:#0000ff">Dim</span> scaleList <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> List(<span style="color:#0000ff">Of</span> <span style="color:#0000ff">Integer</span>)
</p>
</div>
</div>
</div> <p> <br />The next thing I needed to do was figure out what the maximum number in the list was.  So, I added a project reference to the System.Core.dll, then I was able to use LINQ’s Max() generic list extension to get it. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:05c568b2-f9a6-4913-bc95-9129f6b1c4d1" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Get the Max number in the list (using LINQ)<br> </span><span style="color:#0000ff">Dim</span> max <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = <span style="color:#0000ff">CInt</span>(list.Max())
</p>
</div>
</div>
</div> <p></p> <p> <br />Then, I had to get the number that is in the “ones” position of the max number. <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e4315fc6-39d4-49d9-871b-6b4618ba7335" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'The ones variable will store the digit in the ones<br> ' position of the integer<br> '<br> ' Example: 12345 ("5" is in the ones position)<br> </span><span style="color:#0000ff">Dim</span> ones <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0<br> <br> <span style="color:#008000">'Extract number in the ones position<br> </span><span style="color:#0000ff">With</span> max.ToString()<br> ones = <span style="color:#0000ff">CInt</span>(.Substring(.Length - 1, 1))<br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">With</span>
</p>
</div>
</div>
</div> <p> <br />Once I had the maximum number, and the number from the “ones” position of the maximum number, I was able to calculate the ceiling for the numbers in the scale. <br /> <br /></p> <p></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6f756ec9-c61c-4edb-80da-18ff21a8d4b1" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Calculate the ceiling by subtracting ones from max<br> ' and adding 10<br> '<br> ' Example: 33 <br> ' (33 - 3) + 10 = 40 (40 is the ceiling) <br> </span><span style="color:#0000ff">Dim</span> ceiling <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = (max - ones) + 10
</p>
</div>
</div>
</div> <p> <br />The final thing to do was to figure out if the ceiling that I had was evenly divisible for 4 or 3.  If it was, then I could calculate the numbers of the scale, but if it was not, then I needed to adjust my ceiling, and try again. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4d80b16a-9e77-46d7-8b68-fc3d6d27574e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'The quotient stores the result of dividing <br> ' the ceiling by 3 or 4<br> </span><span style="color:#0000ff">Dim</span> quotient <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0<br> <br> <span style="color:#008000">'Begin looping until we have a ceiling that<br> ' is evenly divisible by 4 or 3,then create<br> ' a scale list of integer.<br> </span><span style="color:#0000ff">Do</span><br> <span style="color:#0000ff">If</span> ceiling <span style="color:#0000ff">Mod</span> 4 = 0 <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'Example: If the ceiling is 100, </span><br> <span style="color:#008000">' the(quotient = 25)</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' quotient = 100 / 4</span><br> quotient = <span style="color:#0000ff">CInt</span>(ceiling / 4)<br> <br> <span style="color:#008000">'Add numbers to the scale </span><br> <span style="color:#008000">' (not adding 0, which is the min)</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' Example: 25, 50, 75, 100</span><br> scaleList.Add(quotient)<br> scaleList.Add(quotient * 2)<br> scaleList.Add(quotient * 3)<br> scaleList.Add(quotient * 4)<br> <br> <span style="color:#0000ff">Exit</span> <span style="color:#0000ff">Do</span><br> <br> <span style="color:#0000ff">ElseIf</span> ceiling <span style="color:#0000ff">Mod</span> 3 = 0 <span style="color:#0000ff">Then</span><br> <br> <span style="color:#008000">'Example: If the ceiling is 150, </span><br> <span style="color:#008000">' the(quotient = 50)</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' quotient = 150 / 3</span><br> quotient = <span style="color:#0000ff">CInt</span>(ceiling / 3)<br> <br> <span style="color:#008000">'Add numbers to the scale (not </span><br> <span style="color:#008000">' adding 0, which is the min)</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' Example: 50, 100, 150</span><br> scaleList.Add(quotient)<br> scaleList.Add(quotient * 2)<br> scaleList.Add(quotient * 3)<br> <br> <span style="color:#0000ff">Exit</span> <span style="color:#0000ff">Do</span><br> <br> <span style="color:#0000ff">Else</span><br> <span style="color:#008000">'If the number is not evenly divisible</span><br> <span style="color:#008000">' by 4 or 3 then add 10 to it.</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' Example: 70</span><br> <span style="color:#008000">' 70 / 4 = 17.5</span><br> <span style="color:#008000">' 70 / 3 = 23.333333...</span><br> <span style="color:#008000">' 70 + 10 = 80 (add 10, because 70</span><br> <span style="color:#008000">' is not evenly divisible by 4 or 3)</span><br> <span style="color:#008000">'</span><br> <span style="color:#008000">' 80 / 4 = 20 <- 80 is the number we </span><br> <span style="color:#008000">' want, because 20 is evenly </span><br> <span style="color:#008000">' divisible by 4</span><br> <br> ceiling += 10<br> <br> <span style="color:#0000ff">End</span> <span style="color:#0000ff">If<br> <br> Loop</span>
</p>
</div>
</div>
</div> <p> <br />Now we have our list.  To view the list, write it to the Output Window: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0d60f0ed-e5c6-4a46-8947-08cfa006aff2" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p> <span style="color:#008000">'Loop through each number in the list and write it<br> ' to the Output Window<br> </span><span style="color:#0000ff">For</span> <span style="color:#0000ff">Each</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> <span style="color:#0000ff">In</span> scaleList<br> Debug.WriteLine(i) : <span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> <br />And there it is!  Calculating a Bar Graph scale made easy!</p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.comtag:blogger.com,1999:blog-5132210102253096166.post-78857465958192302692009-08-07T09:47:00.001-06:002009-08-14T16:06:40.385-06:00ADO.NET: DataTables, An Introduction<p align="left">One of my favorite classes in the .NET Framework is the System.Data.DataTable class.  Out of the box, this class is so rich in features, that it is hard to figure out why someone would choose any other class for working with data. <br /> <br />Some of the built-in features include iteration support, data-binding support, error information support, reading to and writing from xml files, and serialization support.  Additionally, the DataTable’s Default DataView supports sorting, searching and filtering! <br /> <br />To begin with, an easy way to think about a DataTable is to think  about an Excel SpreadSheet.  An Excel SpreadSheet can have as many columns as you want, and as many rows as you want – it’s up to you!  The columns run from Left-to-Right, while the rows run from Top-to-Bottom. <br /> <br /><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/SnxMe_XuDkI/AAAAAAAAAJI/37WGwD-V70g/s1600-h/ExcelExample%5B18%5D.jpg"><img style="border-right-width: 0px; width: 212px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ExcelExample" border="0" alt="ExcelExample" align="left" src="http://lh3.ggpht.com/_dhkDWtu14Jc/SnxMfSQlKvI/AAAAAAAAAJM/Ap1qHvI_0Y8/ExcelExample_thumb%5B18%5D.jpg?imgmax=800" width="212" height="194" /></a> </p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />Looking at the Excel SpreadSheet, you’ll notice the following:  <br /> <br />     -  The Columns are named “A”, “B”, “C”, etc.  <br />     -  The Rows are numbered “1”, “2”, “3”, etc.  <br />     -  The SpreadSheet is named “Employees”. <br /> <br />Some additional things you’ll notice is that column “A” is storing First Names, while column “B” is storing Last Names. <br /> <br />Using the DataTable class, we can create a table just like the Excel SpreadSheet above: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:69089f03-67d3-4ff2-baee-6280198e9713" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>
<span style="color:#008000">'Create a new DataTable, and name it "Employees"</span><br><span style="color:#0000ff">Dim</span> table <span style="color:#0000ff">As</span> <span style="color:#0000ff">New</span> <span style="color:#2b91af">DataTable</span>(<span style="color:#a31515">"Employees"</span>)<br><br><span style="color:#008000">'Add columns "A" and "B" to the table</span><br>table.Columns.Add(<span style="color:#a31515">"A"</span>)<br>table.Columns.Add(<span style="color:#a31515">"B"</span>)<br><br><span style="color:#008000">'Add rows to the table, and populate the data:</span><br><br><span style="color:#008000">'Declare a variable to store a reference to a</span><br><span style="color:#008000">' new row when created</span><br><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> <span style="color:#2b91af">DataRow</span><br><br><span style="color:#008000">'Use the NewRow method of the DataTable to create </span><br><span style="color:#008000">' a new row that has the same schema as the </span><br><span style="color:#008000">' DataTable (all of the columns that are in the </span><br><span style="color:#008000">' table will be in it)</span><br><span style="color:#008000">'</span><br><span style="color:#008000">' Note: Creating a new row does NOT add it to </span><br><span style="color:#008000">' the table automatically.</span><br><span style="color:#008000">'</span><br>row = table.NewRow()<br>row.Item(<span style="color:#a31515">"A"</span>) = <span style="color:#a31515">"Bob"</span><br>row.Item(<span style="color:#a31515">"B"</span>) = <span style="color:#a31515">"Jones"</span><br>table.Rows.Add(row)<br><br><span style="color:#008000">'Add a new row by passing an object array with </span><br><span style="color:#008000">' the values for each of the columns</span><br>table.Rows.Add(<span style="color:#0000ff">New</span> <span style="color:#0000ff">Object</span>() {<span style="color:#a31515">"Mike"</span>, <span style="color:#a31515">"Evans"</span>})<br><br><span style="color:#008000">'Add a new row by supplying an object array, </span><br><span style="color:#008000">' without specifying "New Object()", and pass</span><br><span style="color:#008000">' the values for each of the columns.</span><br>table.Rows.Add(<span style="color:#a31515">"Tom"</span>, <span style="color:#a31515">"Messner"</span>)<br><br><span style="color:#008000">'Add a new row using the DataTable's LoadDataRow </span><br><span style="color:#008000">' method.</span><br><span style="color:#008000">'</span><br><span style="color:#008000">' Note: The parameter of False here causes </span><br><span style="color:#008000">' RowState of the new row to be set to "Added", </span><br><span style="color:#008000">' just like when the Table.Rows.Add method is </span><br><span style="color:#008000">' used.</span><br>table.LoadDataRow(<span style="color:#0000ff">New</span> <span style="color:#0000ff">Object</span>() {<span style="color:#a31515">"Kim"</span>, <span style="color:#a31515">"Pham"</span>}, _<br> <span style="color:#0000ff">False</span>)<br><br><span style="color:#008000">'Add a new row using the DataTable's InsertAt </span><br><span style="color:#008000">' method and pass it the index to insert the </span><br><span style="color:#008000">' row at (in this case we are adding it to </span><br><span style="color:#008000">' the very end of the Rows collection).</span><br>row = table.NewRow()<br>row.ItemArray = {<span style="color:#a31515">"Gary"</span>, <span style="color:#a31515">"Lima"</span>}<br>table.Rows.InsertAt(row, table.Rows.Count)
</p>
</div>
</div>
</div> <p> <br /><em>Note:  The rows are automatically numbered (indexed) in a DataTable, just like they are in an Excel SpreadSheet, so we do not need to number the rows ourselves.</em> <br /> <br />At this point, we have a fully loaded table, like the Excel SpreadSheet.  All we need to do now is use a control to view the data in the table.  To do that, add a DataGridView to a Windows Form (named DataGridView1), then add the </p> <p align="left">following line of code just underneath the code above: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1bf3092c-7cae-445e-80fe-1d1eea5ce18f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>
DataGridView1.DataSource = table
</p>
</div>
</div>
</div> <p align="left"> <br /></p> <p align="left">If we performed the above step correctly, when we run our program, our DataGridView should look like the following: <br /> <br /><a href="http://lh6.ggpht.com/_dhkDWtu14Jc/SnxWS88uM8I/AAAAAAAAAJQ/41PbT9b2Nag/s1600-h/DataGridView1%5B6%5D.jpg"><img style="border-right-width: 0px; width: 215px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="DataGridView1" border="0" alt="DataGridView1" align="left" src="http://lh5.ggpht.com/_dhkDWtu14Jc/SnxWTZfnQ_I/AAAAAAAAAJc/YIfMU7e-Sto/DataGridView1_thumb%5B4%5D.jpg?imgmax=800" width="212" height="194" /></a> </p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /></p> <h4>Sorting</h4> <p align="left">One of the first questions you’re sure to ask is, How do you sort the data?  Although DataTable’s themselves do not support sorting, the DataTable has a DefaultView property, which returns a DataView that represents a view of the data, and it does!  And fortunately, a DataView can be used just like a DataTable, for the most-part: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7019afdf-0b06-48a3-81f3-d7ba55f04ec9" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>
<span style="color:#008000">'Create a variable and get the reference to the </span><br><span style="color:#008000">' table's Default DataView </span><br><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> <span style="color:#2b91af">DataView</span> = table.DefaultView<br><br><span style="color:#008000">'Sort the data by column "A", then column "B"</span><br><span style="color:#2b91af">view</span>.Sort = <span style="color:#a31515">"A ASC, B ASC"</span><br><br><span style="color:#008000">'Use the DataView just like the DataTable </span><br>DataGridView1.DataSource = view
</p>
</div>
</div>
</div> <p align="left"> <br />After sorting has been applied to the DataView, we will find the following results when we run our program: <br /> <br /><a href="http://lh5.ggpht.com/_dhkDWtu14Jc/SnxWTlRaJRI/AAAAAAAAAJg/2YaW3eSyc9w/s1600-h/DataGridView2%5B6%5D.jpg"><img style="border-right-width: 0px; width: 208px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="DataGridView2" border="0" alt="DataGridView2" align="left" src="http://lh6.ggpht.com/_dhkDWtu14Jc/SnxWUFYt68I/AAAAAAAAAJk/cMnqleAdzl4/DataGridView2_thumb%5B4%5D.jpg?imgmax=800" width="212" height="194" /></a> </p> <p></p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /></p> <h4>Filtering</h4> <p>Another very useful feature of the DataView is the ability to filter the data.  Filtering will hide all of the rows that do not meet the filter criteria, and show all of the rows that do.  So as an example, we can filter for an employee with the first name of “Gary” and the last name of “Lima”: <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e5b2ff89-9696-480b-9fef-3258dc317cc2" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>
<span style="color:#008000">'Create a variable and get the reference to the </span><br><span style="color:#008000">' table's Default DataView </span><br><span style="color:#0000ff">Dim</span> view <span style="color:#0000ff">As</span> <span style="color:#2b91af">DataView</span> = table.DefaultView<br><br><span style="color:#008000">'Filter the data for a first name of "Gary" and a </span><br><span style="color:#008000">' last name of "Lima" </span><br><span style="color:#2b91af">view</span>.RowFilter = <span style="color:#a31515">"A='Gary' AND B='Lima'"</span><br><br><span style="color:#008000">'Use the DataView just like the DataTable </span><br>DataGridView1.DataSource = view
</p>
</div>
</div>
</div> <p> <br />After filtering has been applied to the DataView, we will find the following results when we run our program: <br /> <br /><a href="http://lh4.ggpht.com/_dhkDWtu14Jc/SnxWUYSmT3I/AAAAAAAAAJo/6CUnseHzPUY/s1600-h/DataGridView3%5B6%5D.jpg"><img style="border-right-width: 0px; width: 214px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="DataGridView3" border="0" alt="DataGridView3" align="left" src="http://lh3.ggpht.com/_dhkDWtu14Jc/SnxWUsg0xJI/AAAAAAAAAJs/nHb2Yq_VQXo/DataGridView3_thumb%5B4%5D.jpg?imgmax=800" width="212" height="194" /></a> </p> <p> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /></p> <h4>Iteration</h4> <p>Iteration is looping through all of the rows in the DataTable’s or DataView’s Rows collection so you can analyze or process each row on an individual basis. <br /> <br />Here’s an example of how to iterate through the DataTable’s Rows collection.  As a note, even though our example above sorted the rows in the DataView, when we loop through the DataTable, the rows will not be sorted. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a436a729-8883-4459-8faa-51dbf2429651" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>
<span style="color:#008000">'Declare a variable to store a reference to each </span><br><span style="color:#008000">' row as we process it.</span><br><span style="color:#0000ff">Dim</span> row <span style="color:#0000ff">As</span> <span style="color:#2b91af">DataRow</span> = <span style="color:#0000ff">Nothing</span><br><br><span style="color:#008000">'Loop through the DataTable's Rows collection</span><br><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> table.Rows.Count - 1<br><br> <span style="color:#008000">'Get a reference to the current row</span><br> row = table.Rows(i)<br><br> <span style="color:#008000">'Write the data to the Output window</span><br> <span style="color:#2b91af">Debug</span>.WriteLine(<span style="color:#a31515">"{0} {1}"</span>, _<br> row.Item(<span style="color:#a31515">"A"</span>), row.Item(<span style="color:#a31515">"B"</span>))<br><br><span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> <br />Here’s an example of how to iterate through the DataView’s Rows collection.  As a note, because we sorted the DataView by columns “A” and “B”, when we loop through the DataView, all of the rows will be sorted. <br /> <br /></p> <div style="padding-bottom: 5px; padding-left: 5px; width: 439px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1cb1196f-ab4f-4c0f-aaad-d78378196c9c" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>
<span style="color:#008000">'Declare a variable to store a reference to each row</span><br><span style="color:#008000">' as we process it.</span><br><span style="color:#008000">'</span><br><span style="color:#008000">' NOTE: The DataRowView declaration </span><br><span style="color:#008000">' (Not DataRow as above)</span><br><span style="color:#0000ff">Dim</span> rowView <span style="color:#0000ff">As</span> <span style="color:#2b91af">DataRowView</span> = <span style="color:#0000ff">Nothing</span><br><br><span style="color:#008000">'Loop through the DataView's Rows collection</span><br><span style="color:#0000ff">For</span> i <span style="color:#0000ff">As</span> <span style="color:#0000ff">Integer</span> = 0 <span style="color:#0000ff">To</span> <span style="color:#2b91af">view</span>.Count - 1<br><br> <span style="color:#008000">'Get a reference to the current row</span><br> rowView = view(i)<br><br> <span style="color:#008000">'Write the data to the Output window</span><br> <span style="color:#2b91af">Debug</span>.WriteLine(<span style="color:#a31515">"{0} {1}"</span>, _<br> rowView.Item(<span style="color:#a31515">"A"</span>), rowView.Item(<span style="color:#a31515">"B"</span>))<br><br><span style="color:#0000ff">Next</span>
</p>
</div>
</div>
</div> <p> <br /></p> <h4>Conclusion</h4> <p align="left">This example demonstrated the simplicity of creating a DataTable, adding columns and rows of data; plus sorting and filtering a DataTable’s data using it's <em>Default</em> DataView, plus how to iterate through a DataTable and a DataView. <br /> <br /></p> <p align="left">I will endeavor to cover both the DataTable and the DataView in a more in-depth look to come… </p> VBRockshttp://www.blogger.com/profile/09640438321530555457noreply@blogger.com