<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DataBatrix</title>
	<atom:link href="http://www.databatrix.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.databatrix.com</link>
	<description>The workings of Eric Bridges</description>
	<lastBuildDate>Thu, 01 Dec 2011 23:47:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>Populate TreeView From Custom Object Using Serializer</title>
		<link>http://www.databatrix.com/2010/12/populate-treeview-from-custom-object-using-serializer/</link>
		<comments>http://www.databatrix.com/2010/12/populate-treeview-from-custom-object-using-serializer/#comments</comments>
		<pubDate>Tue, 21 Dec 2010 17:40:41 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[Serialize]]></category>
		<category><![CDATA[TreeView]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=321</guid>
		<description><![CDATA[From time to time I need to spit out the public properties of an object for various reasons.  A typical use would be to show user friendly results from a web service that returns a complex object.  There could be tons of other uses!  After doing this a few times, I finially decided to post [...]]]></description>
			<content:encoded><![CDATA[<p>From time to time I need to spit out the public properties of an object for various reasons.  A typical use would be to show user friendly results from a web service that returns a complex object.  There could be tons of other uses!  After doing this a few times, I finially decided to post this so I can always reference it.  Anytime I do any recursive methods, it always takes me a couple of tweaks before getting it right.</p>
<p>The idea is that I have a custom object that I need to spin through to populate a <span style="color: #0000ff;">TreeView</span>.  I created a couple of simple methods to do such.  I though about using <span style="color: #0000ff;">Reflection</span>, but my method starting getting larger and larger because I was having to put in special code to handle certain Types (i.e. <span style="color: #0000ff;">String</span>, <span style="color: #0000ff;">ICollection</span>, etc).  Since my typical Use Case was to spit out the results of a complex object returned from a ASMX or WCF service, I decided to go the Serialize route.  My DTO class was typically already decorated with the [<span style="color: #008080;">Serializable</span>] attribute, if not, it was simple enought to add.</p>
<p>So first we serialize the object into a string of XML, then stuff that into a XmlDocument.  Then you can loop through the elements while creating each <span style="color: #0000ff;">TreeViewNode</span>.  That&#8217;s it!</p>
<pre class="brush:csharp">        public void PopulateTreeView(object obj, TreeView tv)
        {
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
            System.Text.StringBuilder sb = new System.Text.StringBuilder();  // StringBuilder to hold the XML
            using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(sb))
            {
                serializer.Serialize(writer, obj); // Serialize the object to XML
                System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
                xDoc.LoadXml(sb.ToString());  // Shove it in a XmlDocument
                tv.Nodes.Add(PopulateNode(xDoc));  // Add the Nodes to the TreeView
            }
        }

        public TreeNode PopulateNode(System.Xml.XmlNode node)
        {
            TreeNode treenode = new TreeNode(node.Name);  // Add the Name to the Node
            if (node.ChildNodes.Count == 1) //Prevents ParentNode from displaying all of the InnerText
                treenode.Text += "=" + node.InnerText; // If only 1 ChildNode then add the InnerText

            for (int i = 0; i &lt; node.ChildNodes.Count; i++)
            {
                if (node.ChildNodes[i].HasChildNodes)
                {
                    treenode.ChildNodes.Add(PopulateNode(node.ChildNodes[i]));
                }
            }
            return treenode;
        }</pre>
<p>Then call the method to populate where &#8220;customObject&#8221; is the object you want displayed in your TreeView:</p>
<pre class="brush:csharp">            PopulateTreeView(customObject, TreeView1);</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2010/12/populate-treeview-from-custom-object-using-serializer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ceton InfiniTV 4 CableCARD Installation on Verizon FiOS</title>
		<link>http://www.databatrix.com/2010/12/ceton-infinitv-4-cablecard-installation-on-verizon-fios/</link>
		<comments>http://www.databatrix.com/2010/12/ceton-infinitv-4-cablecard-installation-on-verizon-fios/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 21:28:09 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CableCARD]]></category>
		<category><![CDATA[Ceton]]></category>
		<category><![CDATA[FiOS]]></category>
		<category><![CDATA[InfiniTV]]></category>
		<category><![CDATA[Media Center]]></category>
		<category><![CDATA[Verizon]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=304</guid>
		<description><![CDATA[The tech made it out this afternoon and completed the install in about 30 minutes. He could have left earlier since the InfiniTV Diagnostic Tool showed green check boxes on everything, but he stayed while I configured Windows Media Center tuner just to see it in action. It was his first Ceton install although he [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://lh4.ggpht.com/_eZ_9X1uBDHY/TQlZ2Diqa7I/AAAAAAAAdDA/g8JcjDPolHg/s800/IMG_2560.JPG"><img class="alignleft" style="margin-top: 1px; margin-bottom: 1px; margin-left: 20px; margin-right: 20px; border: 1px solid black;" title="Ceton InfiviTV 4" src="http://lh4.ggpht.com/_eZ_9X1uBDHY/TQlZ2Diqa7I/AAAAAAAAdDA/g8JcjDPolHg/s512/IMG_2560.JPG" alt="" width="230" height="307" /></a>The tech made it out this afternoon and completed the install in about 30 minutes. He could have left earlier since the InfiniTV Diagnostic Tool showed green check boxes on everything, but he stayed while I configured Windows Media Center tuner just to see it in action. It was his first Ceton install although he had done several CableCard installs on Tivos. The basic flow was:<br />
<strong>(Before tech arrived)</strong></p>
<ul>
<li>Installed Ceton card in computer and installed drivers/software as described in the install document.</li>
<li>I ran the Digital Cable Advisor from within Media Center<br />
Installed the firmware update for FiOS customers and did a full power down then reboot (not restart)</li>
<p><strong>(After tech arrived)</strong></p>
<li>Powered down the computer so he could put in the M-Card. (He was saying I didn&#8217;t have too, but this was also his first install into a computer?)</li>
<li>He installed the card and we restarted the machine.</li>
<li>He got the CableCARD ID, Host ID, and Data from http://192.168.200.1/get_cc_url?CableCARD///cp/auth (BTW, the 192.168.200.1 page only works for me in Firefox&#8230;it doesn&#8217;t work correctly in Chrome or IE 9 beta)</li>
<li>He put a USB dongle in the computer and ran an EXE that was on the thumb drive. He said it didn&#8217;t have to be ran from the same machine, but it had to be ran from a computer on my network.</li>
<li>He initiated the activation process from his laptop.</li>
<li>I had the Ceton InfiniTV Diagnostic Tool up the entire time (this also had the numbers he need as well). Note: the Diagnostic Tool refreshes itself, so some items would take a few minutes before they populated.</li>
<li>In about 5 minutes (the Diagnostic Tool says to wait 10 minutes before resending the signal) we got the last green light!</li>
<li>He tried the Check Channel Authorization and put in channel 4 and clicked the Tune Channel button. I responded with a success message.</li>
<li>I fired up Window Media Center and went to the tuner setup and walked through the wizard selected my cable provider, etc.</li>
<li>That whole process took about 5-10 minutes. Next I tried recording 4 channels and it worked wonderfully! (CPU was around 30%-35% while recording 4 channels on a AMD X4)</li>
<li>Fired up 3 XBox 360&#8242;s and turned them to different channels. CPU was fine, I think I saw a peek of around 75%. Right now it is at 32% with 1 Xbox extender and Media Center running on the computer tuned to a different channel.</li>
</ul>
<p>The tech did not think it was going to be able to do 4 channels at the same time&#8230;not sure if that was because the Tivos are only dual tuners or what? He thought the card was only capable of 2 channels&#8230;so he was surprised to see it recording all four! I also asked him about the Low Pass Filter. He said he didn&#8217;t think I wouldn&#8217;t need one because the CableCard ignores the MoCA frequency (these are his word&#8230;just repeating them). I tried some of the channels others mentioned to have problems with (631,717,746,789) and they were coming in fine. He said that he didn&#8217;t have a filters anyways&#8230;they were on order (for unrelated reasons). He also let me know that the card is tied to my account, not the device, so I should be about to pop it in other devices and it should work with any issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2010/12/ceton-infinitv-4-cablecard-installation-on-verizon-fios/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Automatically Add RequiredFieldValidator to TextBox Controls</title>
		<link>http://www.databatrix.com/2010/11/automatically-add-requiredfieldvalidator-to-textbox-controls/</link>
		<comments>http://www.databatrix.com/2010/11/automatically-add-requiredfieldvalidator-to-textbox-controls/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 14:56:55 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[RequiredFieldValidator]]></category>
		<category><![CDATA[ValidatorCalloutExtender]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=274</guid>
		<description><![CDATA[If you are like me, you hate having to create the required field validators for a bunch of TextBox controls.  Even more if you are adding Ajax ValidatorCallout controls to all of them.  Sure, you could create another server control to extent the Textbox to automatically include this&#8230;but here is a simple alternative. I created [...]]]></description>
			<content:encoded><![CDATA[<p>If you are like me, you hate having to create the required field validators for a bunch of TextBox controls.  Even more if you are adding Ajax ValidatorCallout controls to all of them.  Sure, you could create another server control to extent the Textbox to automatically include this&#8230;but here is a simple alternative.</p>
<p>I created a method that cycles through all of the controls and checks to see if it has the attribute &#8220;Required&#8221;, and if so, then add the RequiredFieldValidator and Ajax callout controls automatically. You could obviously expand on this to meet your specific needs.<br />
Here is how you would markup your TextBox control:<br />
&lt;asp:TextBox Required=&#8221;true&#8221; ValidationGroup=&#8221;valGroup&#8221; ID=&#8221;TextBox1&#8243; runat=&#8221;server&#8221; /&gt;<br />
<br />
Here is the method in the code behind:</p>
<pre class="brush:csharp">private void AddRequiredValidations(ControlCollection controls)
{
    List requiredValidators = new List();
    for (int i = 0; i &lt; controls.Count; i++)
    {
        if (controls[i] is TextBox)
        {
            TextBox tb = (TextBox)controls[i];
            if (tb.Attributes["Required"] != null &amp;&amp; Convert.ToBoolean(tb.Attributes["Required"]))
            {
                RequiredFieldValidator requiredValidator = new RequiredFieldValidator();
                requiredValidator.ErrorMessage = "Required";
                requiredValidator.ID = "required" + tb.ID;
                requiredValidator.Display = ValidatorDisplay.None;
                requiredValidator.ValidationGroup = tb.ValidationGroup;
                requiredValidator.ControlToValidate = tb.ID;
                // Add the RequiredFieldValidator to a list to be added later
                // Since we can't add them to the control as we are cycling through them
                requiredValidators.Add(requiredValidator); 

                tb.CausesValidation = true;
            }
        }

        if (controls[i].HasControls()) // If this control has child controls
        {
            AddRequiredValidations(controls[i].Controls); // Search the child controls too
        }
    }

    // Now we can actually add the RequiredFieldValidators since we are done cycling through the existing controls
    for (int i = 0; i &lt; requiredValidators.Count; i++)
    {

        AjaxControlToolkit.ValidatorCalloutExtender callout = new AjaxControlToolkit.ValidatorCalloutExtender();
        callout.TargetControlID = requiredValidators[i].ID;
        callout.ID = requiredValidators[i].ID + "Callout";
        controls.Add(requiredValidators[i]);
        controls.Add(callout);
    }
}</pre>
<p>Then all you have to do is call it in your Page_Load() method:</p>
<pre class="brush:csharp">AddRequiredValidations(this.Controls);</pre>
<p>
This will work not only for a singe TextBox control, but also for TextBox controls buried inside a GridView or Repeater!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2010/11/automatically-add-requiredfieldvalidator-to-textbox-controls/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>T-Mobile G2 Review</title>
		<link>http://www.databatrix.com/2010/11/t-mobile-g2-review/</link>
		<comments>http://www.databatrix.com/2010/11/t-mobile-g2-review/#comments</comments>
		<pubDate>Fri, 12 Nov 2010 14:24:58 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[G2]]></category>
		<category><![CDATA[T-Mobile]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=261</guid>
		<description><![CDATA[I recently upgraded to the T-Mobile G2 coming from the HTC myTouch.  Is has almost been a week of using the device and so far I am impressed! Added voice functionality This is courtesy of the latest version of Android (Froyo).  It is very useful to say things like &#8220;Call Papa-Johns&#8221; and have it call the [...]]]></description>
			<content:encoded><![CDATA[<p>I recently upgraded to the T-Mobile G2 coming from the HTC myTouch.  Is has almost been a week of using the device and so far I am impressed!</p>
<p>Added voice functionality<br />
This is courtesy of the latest version of Android (Froyo).  It is very useful to say things like &#8220;Call Papa-Johns&#8221; and have it call the closest Papa-Johns based on my current location.  Not that I am calling out for pizza that often&#8230;but you get the idea.  You also have the option to dictate by pressing the microphone icon on the soft keyboard.  It is surprisingly accurate in my opinion.  It works fine for a short sentence or note when you are in the car.</p>
<p>Swype<br />
When I first used this I though it was very awkward.  However, after a few days, it is starting to grow on me a little bit.  It is perfect for one-handed scenarios when you don&#8217;t want to take the time to use the full keyboard.</p>
<p>Speed<br />
The UI is much snappier than the myTouch, as you would expect.</p>
<p>Corporate calendar<br />
I sync with an Exchange server for work and previous versions of Android would not sync the calendar.  I had even loaded Froyo (Cyanogen) on the myTouch with no luck.  I am glad to see this working correctly on the G2!</p>
<p>Headphone Jack<br />
I love the fact that I do not need an adapter to use the headphones like I had to on the G1 and myTouch.  A standard 3.5mm jack is located on the top of the device.  It is a little odd that it is on top instead of bottom.  I suppose that works out great if you are placing it in your pocket while listening music/podcasts, but the wire may get in your way if you are holding it in your hand.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2010/11/t-mobile-g2-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ListSearchExtender not finding some numeric values</title>
		<link>http://www.databatrix.com/2010/11/listsearchextender-not-finding-some-numeric-values/</link>
		<comments>http://www.databatrix.com/2010/11/listsearchextender-not-finding-some-numeric-values/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 17:20:26 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[IsSorted]]></category>
		<category><![CDATA[ListSearchExtender]]></category>
		<category><![CDATA[numeric]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=265</guid>
		<description><![CDATA[I was working on a project when I noticed something strange with my ListSearchExtender.  This was happening on 2 different controls.  One ListSearchExtender was extending a ListBox and another was on a DropDown.  Both of these controls were populated with mostly numeric values (ID numbers) sorted in order ascending order.  The DropDown box was populated [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">I was working on a project when I noticed something strange with my ListSearchExtender.  This was happening on 2 different controls.  One ListSearchExtender was extending a ListBox and another was on a DropDown.  Both of these controls were populated with mostly numeric values (ID numbers) sorted in order ascending order.  The DropDown box was populated with about 1200 ID numbers while the ListBox was populated with about 600 ID numbers along with a small description of each item.  I was using the ListSearchExtender so that the user could easily jump to a specific item if they already knew the ID number.  The proplem I was having was that the ListSearchExtender did not find and jump to certain ID numbers even though they were in the list.  Particularly this seem to happen when the ID number started with the number one (1).  For example, let&#8217;s say the ListBox/DropDown contained these values:</div>
<div id="_mcePaste">23</div>
<div id="_mcePaste">45</div>
<div id="_mcePaste">89</div>
<div id="_mcePaste">101</div>
<div id="_mcePaste">109</div>
<div id="_mcePaste">111</div>
<div id="_mcePaste">140</div>
<div id="_mcePaste">204</div>
<div id="_mcePaste">226</div>
<div id="_mcePaste">1005</div>
<div id="_mcePaste">Using the ListSearchExtender extender, I would not find 101 or 109.  Below is the markup for the ListSearchExtender:</div>
<pre class="brush:html">&lt;ajax:ListSearchExtender ID="lseAjaxDdlFilter" runat="server" TargetControlID="ddlFilter" IsSorted="true" PromptPosition="Top" /&gt;</pre>
<div id="_mcePaste">I discovered that the root of my problem was <strong>IsSorted=&#8221;true&#8221;</strong>.  Since my data was already sorted I had set this value to true to increase the performance.  I am guessing the ListSearchExtender IsSorted property is assuming the sort is by text/string instead of treating them as integers.  The same list above sorted as text would be in this order: 1005, 101, 109, 111, 140, 204, 226, 23, 45, 89.  This would throw off the functionality.  So I set <strong>IsSorted=&#8221;false&#8221;</strong> and everything works as it should!</div>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2010/11/listsearchextender-not-finding-some-numeric-values/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IE: scrollTop Not Working As Expected</title>
		<link>http://www.databatrix.com/2010/08/ie-scrolltop-not-working-as-expected/</link>
		<comments>http://www.databatrix.com/2010/08/ie-scrolltop-not-working-as-expected/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 02:04:10 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[div]]></category>
		<category><![CDATA[overflow]]></category>
		<category><![CDATA[scrollTop]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=254</guid>
		<description><![CDATA[I banged my head on this one for a couple of days.  Still got a defect out of the deal, but finally got it working.  I had an ajax tabcontainer with several tabs.  In some of these tabs was GridView.  I had overflow set on a DIV that the GridView was placed in so that [...]]]></description>
			<content:encoded><![CDATA[<p>I banged my head on this one for a couple of days.  Still got a defect out of the deal, but finally got it working.  I had an ajax tabcontainer with several tabs.  In some of these tabs was GridView.  I had overflow set on a DIV that the GridView was placed in so that I would get vertical scrollbars within the page.  The issue was that I needed to keep the position of the DIV scroll on a postback.  Should not have been an issue since I have the exact same scenario on another page within the same website which work perfectly.  But for some reason, using the same code, it would not work on this particular page.  Both pages use MasterPages, tabcontainers, and a little javascript and cookies to save the scroll position.</p>
<p>When debugging the issue, I would find that it would save and get the correct scroll position from the cookie; however, when setting the scrollTop:</p>
<pre class="brush:javascript">document.getElementById('myDiv').scrollTop = scrollPosition;</pre>
<p>It would not set.  The DIV&#8217;s scrollTop would be 0 before and after the statement above even after verifying that scrollPosition had an actual value!</p>
<p>I will also mention that the grid did have a decent about of data.  Actually, enough to make the page size about 3.5 MBs by the time HTML was rendered&#8230;almost 1 MB taken up by ViewState alone!  Because of AJAX and the amount of data in the grid, there was a noticeable amount of lag when using the page&#8230;not a lot, but noticeable.</p>
<p>Work Around:</p>
<p>I started to wonder if the above javascript (which ran on window.onload) may be running too quickly&#8230;or rather, ran before IE could finish with the rest of the AJAX/javascript code on the page.  So I tried this line instead of the one above:</p>
<pre class="brush:javascript">setTimeout(function() { document.getElementById('myDiv').scrollTop = scrollPosition; }, 250);</pre>
<p>So basically, I wanted to wait 250 milliseconds before setting the scrollTop.  Much to my surprise, this worked!  By this point I was too exhausted to keep knocking down the delay to see how low it could go and still work.  I couldn&#8217;t really notice the 250 delay in setting the scroll position, so that is where I ended.</p>
<p>Your mileage may vary, but in case you have a similar issue&#8230;try a small delay when setting the scrollTop before attempting to re-engineer the whole page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2010/08/ie-scrolltop-not-working-as-expected/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Serialization: Binary, SOAP, and XML (VB)</title>
		<link>http://www.databatrix.com/2009/10/net-serialization-binary-soap-and-xml-vb/</link>
		<comments>http://www.databatrix.com/2009/10/net-serialization-binary-soap-and-xml-vb/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 23:43:50 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[ASP]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Binary]]></category>
		<category><![CDATA[Serialization]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=227</guid>
		<description><![CDATA[In .NET when you need to shrink an object into a more portable format you have 3 choices.  Binary, SOAP, or XML.  The process of shrinking and expanding the object is called serialization and deserialization.  Each option has it&#8217;s own advantages which I will explain. Binary You can serialize an object into binary format quite [...]]]></description>
			<content:encoded><![CDATA[<p>In .NET when you need to shrink an object into a more portable format you have 3 choices.  Binary, SOAP, or XML.  The process of shrinking and expanding the object is called serialization and deserialization.  Each option has it&#8217;s own advantages which I will explain.</p>
<h2>Binary</h2>
<p>You can serialize an object into binary format quite easily using the .NET Framework.  This is the quickest and smallest way to serialize; however, the binary format can only be deserialized using the same .NET Framework.  This may be a problem for interoperability.  It must be noted that this format will serialize Public and Private members (unlike XML serialization).</p>
<p>The example below shows how to serialize an object called &#8220;newCustomer&#8221;:</p>
<pre class="brush:vb">        Dim newCustomer As Contact = GetSampleContact()

        Using fs As New IO.FileStream(filePathandName &amp; ".bin", IO.FileMode.Create)
            Dim binFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            binFormatter.Serialize(fs, newCustomer)
        End Using</pre>
<p>And here is the reverse to deserialize:</p>
<pre class="brush:vb">        Dim readCustomer As Contact

        Using fs As New IO.FileStream(filePathandName &amp; ".bin", IO.FileMode.Open, IO.FileAccess.Read)
            Dim binFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            readCustomer = CType(binFormatter.Deserialize(fs), Contact)
        End Using</pre>
<h2>SOAP</h2>
<p>SOAP is another method.  This is similar to the binary method except the serialized data is stored in a standardized form (SOAP) which will easily allow interoperability.  Public and Private members are serialized using this method as well.<br />
To serialize:</p>
<pre class="brush:vb">        Dim newCustomer As Contact = GetSampleContact()
        Using fs As New IO.FileStream(filePathandName &amp; "SOAP.xml", IO.FileMode.Create)
            Dim soapFormattter As New Runtime.Serialization.Formatters.Soap.SoapFormatter()
            soapFormattter.Serialize(fs, newCustomer)
        End Using</pre>
<p>And to deserialize:</p>
<pre class="brush:vb">        Dim readCustomer As Contact
        Using fs As New IO.FileStream(filePathandName &amp; "SOAP.xml", IO.FileMode.Open, IO.FileAccess.Read)
            Dim soapFormattter As New Runtime.Serialization.Formatters.Soap.SoapFormatter()
            readCustomer = CType(soapFormattter.Deserialize(fs), Contact)
        End Using</pre>
<h2>XML</h2>
<p>A third choice is using the XMLSerializer class.  This method will only serialize Public properties and members and the object must be marked with the Serializable attribute and contain an empty constructor.  This method of serialization will be smaller in size than the SOAP method since less information is serialized.  Here is an example of such class:</p>
<pre class="brush:vb">     &lt;Serializable()&gt; Class Contact

        Private _FirstName As String
        Public Property FirstName() As String
            Get
                Return _FirstName
            End Get
            Set(ByVal value As String)
                _FirstName = value
            End Set
        End Property

        Private _LastName As String
        Public Property LastName() As String
            Get
                Return _LastName
            End Get
            Set(ByVal value As String)
                _LastName = value
            End Set
        End Property

        Private _MiddleI As String
        Public Property MiddleI() As String
            Get
                Return _MiddleI
            End Get
            Set(ByVal value As String)
                _MiddleI = value
            End Set
        End Property

        Private _PIN As String
        Public WriteOnly Property PIN() As String
            Set(ByVal value As String)
                _PIN = value
            End Set
        End Property

        Sub New()

        End Sub

        Sub New(ByVal fName As String, ByVal middleI As String, ByVal lName As String, ByVal p As String)
            _FirstName = fName
            _MiddleI = middleI
            _LastName = lName
            _PIN = p
        End Sub
    End Class</pre>
<p>Here is how you would serialize using the XMLSerializer:</p>
<pre class="brush:vb">        Dim newCustomer As Contact = GetSampleContact()
        Using fs As New IO.FileStream(filePathandName &amp; ".xml", IO.FileMode.Create)
            Dim xmlFormatter As New Xml.Serialization.XmlSerializer(GetType(Contact))
            xmlFormatter.Serialize(fs, newCustomer)
        End Using</pre>
<p>And to deserialize:</p>
<pre class="brush:vb">        Dim readCustomer As Contact
        Using fs As New IO.FileStream(filePathandName &amp; ".xml", IO.FileMode.Open, IO.FileAccess.Read)
            Dim xmlFormatter As New Xml.Serialization.XmlSerializer(GetType(Contact))
            readCustomer = CType(xmlFormatter.Deserialize(fs), Contact)
        End Using</pre>
<p><img class="alignnone size-full wp-image-232" title="Serialization Demo" src="http://www.databatrix.com/wp-content/uploads/2009/10/Serialization.JPG" alt="Serialization Demo" width="505" height="336" /></p>
<p>You can download a sample serialization demo project that I created to demonstrate: <a title="Serialization Demo Project.zip" href="http://www.databatrix.com/wp-content/uploads/2009/10/SerializationDemo.zip">SerializationDemoProject.zip</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2009/10/net-serialization-binary-soap-and-xml-vb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JobTime: Time Clock Web Application And Job Cost Tracking</title>
		<link>http://www.databatrix.com/2009/09/jobtime-time-clock-web-application-and-job-cost-tracking/</link>
		<comments>http://www.databatrix.com/2009/09/jobtime-time-clock-web-application-and-job-cost-tracking/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 13:18:06 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[Payroll]]></category>
		<category><![CDATA[Timeclock]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=214</guid>
		<description><![CDATA[Background The company needed to track time logged to particular jobs/projects.  The initial idea was to use a site like ClickTime.  However, for an employee to log time against a job, you would need to tell ClickTime all of your jobs (which would be tedious) or configure an integration app to automatically populate the available [...]]]></description>
			<content:encoded><![CDATA[<h3>Background</h3>
<p>The company needed to track time logged to particular jobs/projects.  The initial idea was to use a site like <a href="http://www.clicktime.com/" target="_blank">ClickTime</a>.  However, for an employee to log time against a job, you would need to tell ClickTime all of your jobs (which would be tedious) or configure an integration app to automatically populate the available jobs/projects.</p>
<h3>Solution</h3>
<p>I created a web application that would allow employees to log time against jobs/projects.  It would search instantly against their project management software for a list of available jobs.  The type of work was categorized for reporting.  Since we would have the employee&#8217;s hours, it would be used for payroll.  I implemented an export feature for preparing the payroll information for ADP and EDH.  Work time for each project was then entered into the project management software to be calculated as job cost.  As a bonus, you could use the gathered data to calculate each employees &#8220;utilization&#8221;.</p>
<table border="0">
<tbody>
<tr>
<td>
<p><div id="attachment_217" class="wp-caption alignnone" style="width: 160px"><a href="http://www.databatrix.com/wp-content/uploads/2009/09/MainScreen.JPG"><img class="size-thumbnail wp-image-217" title="MainScreen" src="http://www.databatrix.com/wp-content/uploads/2009/09/MainScreen-150x150.jpg" alt="Landing page." width="150" height="150" /></a><p class="wp-caption-text">Landing page.</p></div></td>
<td>
<p><div id="attachment_216" class="wp-caption alignnone" style="width: 160px"><a href="http://www.databatrix.com/wp-content/uploads/2009/09/EnterTime.JPG"><img class="size-thumbnail wp-image-216" title="EnterTime" src="http://www.databatrix.com/wp-content/uploads/2009/09/EnterTime-150x150.jpg" alt="Enter time for a particular project/job." width="150" height="150" /></a><p class="wp-caption-text">Enter time for a particular project/job.</p></div></td>
</tr>
<tr>
<td>
<p><div id="attachment_215" class="wp-caption alignnone" style="width: 160px"><a href="http://www.databatrix.com/wp-content/uploads/2009/09/ApplyJobCost.JPG"><img class="size-thumbnail wp-image-215" title="ApplyJobCost" src="http://www.databatrix.com/wp-content/uploads/2009/09/ApplyJobCost-150x150.jpg" alt="Apply costs to each job." width="150" height="150" /></a><p class="wp-caption-text">Apply costs to each job.</p></div></td>
<td>
<p><div id="attachment_218" class="wp-caption alignnone" style="width: 160px"><a href="http://www.databatrix.com/wp-content/uploads/2009/09/PayRoll.JPG"><img class="size-thumbnail wp-image-218" title="PayRoll" src="http://www.databatrix.com/wp-content/uploads/2009/09/PayRoll-150x150.jpg" alt="Payroll export options." width="150" height="150" /></a><p class="wp-caption-text">Payroll export options.</p></div></td>
</tr>
<tr>
<td>
<p><div id="attachment_219" class="wp-caption alignnone" style="width: 160px"><a href="http://www.databatrix.com/wp-content/uploads/2009/09/Utilization.JPG"><img class="size-thumbnail wp-image-219" title="Utilization" src="http://www.databatrix.com/wp-content/uploads/2009/09/Utilization-150x150.jpg" alt="Utilization" width="150" height="150" /></a><p class="wp-caption-text">Utilization</p></div></td>
<td> </td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2009/09/jobtime-time-clock-web-application-and-job-cost-tracking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cross-thread operation not valid: .NET Cross Threading To Update Form Control</title>
		<link>http://www.databatrix.com/2009/09/cross-thread-operation-not-valid-net-cross-threading-to-update-form-control/</link>
		<comments>http://www.databatrix.com/2009/09/cross-thread-operation-not-valid-net-cross-threading-to-update-form-control/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 13:18:45 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Cross-thread]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=204</guid>
		<description><![CDATA[So you get the &#8220;Cross-thread operation not valid&#8221; error because you are trying to update an object on your form from a thread. I am not going to try to &#8220;glamor&#8221; you (True Blood reference) with fundamentals of delegates, threading, etc. If that is what you are looking for, search Google and you will find [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_206" class="wp-caption alignleft" style="width: 466px"><a href="http://www.databatrix.com/wp-content/uploads/2009/09/CrossThread.JPG"><img class="size-full wp-image-206" title="Cross-thread operation not valid" src="http://www.databatrix.com/wp-content/uploads/2009/09/CrossThread.JPG" alt="Cross-thread operation not valid" width="456" height="256" /></a><p class="wp-caption-text">Cross-thread operation not valid</p></div>
<p>So you get the &#8220;Cross-thread operation not valid&#8221; error because you are trying to update an object on your form from a thread.  I am not going to try to &#8220;glamor&#8221; you (True Blood reference) with fundamentals of delegates, threading, etc.  If that is what you are looking for, search Google and you will find tons of references that are overly complicated using all of the proper terminology that typically makes my head hurt.  I WILL show you the few bits of code in Visual Basic that are needed to get around the error.  Or perhaps you just need to update a form control from a background process so the application does not hang.</p>
<p>In the example below, I am needing to update a ListBox control from a separate thread.  I need 2 items: a method to update the ListBox which takes a string as a parameter and a Delegate with a matching parameter signature.</p>
<p>Here is the Delegate:</p>
<pre class="brush: vb">Private Delegate Sub UpdateListboxDelegate(ByVal s As String)</pre>
<p>And here is the method that actually updates the ListBox:</p>
<pre class="brush: vb">Private Sub UpdateListbox(ByVal s As String)
   If Me.InvokeRequired Then
      Me.BeginInvoke(New UpdateListboxDelegate(AddressOf UpdateListbox), New Object() {s})
      Return
   End If
   ListBox1.Items.Add(s)
End Sub</pre>
<p>Here would be a sample of the main sub that is slow to process:</p>
<pre class="brush: vb">Public Sub LongProcess()
   For i As Integer = 0 To 100
      System.Threading.Thread.Sleep(5000)
      UpdateListbox("Currently on count: " &amp; i)
   Next
End Sub</pre>
<p>Now to kick off the thread:</p>
<pre class="brush: vb">ListBox1.Items.Clear()
Dim thread As New Threading.Thread(AddressOf LongProcess)
thread.Start()</pre>
<p>That&#8217;s it!  The easiest solution without getting overly complicated.</p>
<p><b>&#8230;and in case you are looking for C# (it&#8217;s growing on me too):</b></p>
<pre class="brush:csharp">
        private delegate void UpdateListboxDelegate(string s);

        private void UpdateListbox(string s)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new UpdateListboxDelegate(UpdateListbox), new object[] { s });
                return;
            }
            listBox1.Items.Add(s);
        }

        public void LongProcess()
        {
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(1000);
                UpdateListbox("Currently on count: " + i.ToString());
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            System.Threading.Thread thread = new System.Threading.Thread(LongProcess);
            thread.Start();
        }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2009/09/cross-thread-operation-not-valid-net-cross-threading-to-update-form-control/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatic Email Alerts From Any SQL Query</title>
		<link>http://www.databatrix.com/2009/09/automatic-email-alerts-from-any-sql-query/</link>
		<comments>http://www.databatrix.com/2009/09/automatic-email-alerts-from-any-sql-query/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 13:24:40 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[Desktop Applications]]></category>
		<category><![CDATA[MS SQL]]></category>

		<guid isPermaLink="false">http://www.databatrix.com/?p=188</guid>
		<description><![CDATA[Problem Reminder emails were needed to be sent out to remind sales staff to follow up on projects. Solution I developed a simple command line executable that takes 1 parameter which is an XML file.  The contents of the XML file would look something like: &#60;?xml version="1.0" encoding="utf-8" ?&#62; &#60;Settings&#62; &#60;ErrorEmail&#62; &#60;Email&#62;email@gmail.com&#60;/Email&#62; &#60;/ErrorEmail&#62; &#60;SummaryEmail&#62; &#60;Email&#62;email@gmail.com&#60;/Email&#62; [...]]]></description>
			<content:encoded><![CDATA[<h3>Problem</h3>
<p>Reminder emails were needed to be sent out to remind sales staff to follow up on projects.</p>
<h3>Solution</h3>
<p>I developed a simple command line executable that takes 1 parameter which is an XML file.  The contents of the XML file would look something like:</p>
<pre class="brush: xml">&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;Settings&gt;
	&lt;ErrorEmail&gt;
		&lt;Email&gt;email@gmail.com&lt;/Email&gt;
	&lt;/ErrorEmail&gt;
	&lt;SummaryEmail&gt;
		&lt;Email&gt;email@gmail.com&lt;/Email&gt;
	&lt;/SummaryEmail&gt;
	&lt;Query&gt;
		SELECT * FROM Projects
		WHERE Cancelled = 0 And Completed = 0 AND BookDate IS NULL
		AND FollowUpBy &lt;= getdate()
	&lt;/Query&gt;
	&lt;SQLConnectionString&gt;Server=SQLServer;Database=MainDatabase;Persist Security Info=True;Integrated Security=true&lt;/SQLConnectionString&gt;
	&lt;TemplateEmailFileName&gt;EmailTemplate.txt&lt;/TemplateEmailFileName&gt;
	&lt;EmailSubject&gt;Alert Email For Project#&lt;:ProjectID:&gt;&lt;/EmailSubject&gt;
	&lt;EmailDomain&gt;mycompany.com&lt;/EmailDomain&gt;
	&lt;ToAddressDatabaseField&gt;Salesperson&lt;/ToAddressDatabaseField&gt;
	&lt;ToAddressFieldIsEmail&gt;0&lt;/ToAddressFieldIsEmail&gt;
	&lt;SMTPSettings&gt;
		&lt;SMTPServer&gt;smtp.gmail.com&lt;/SMTPServer&gt;
		&lt;EnableSSL&gt;1&lt;/EnableSSL&gt;
		&lt;RequiresAuthentication&gt;1&lt;/RequiresAuthentication&gt;
		&lt;Username&gt;email@gmail.com&lt;/Username&gt;
		&lt;Password&gt;*******&lt;/Password&gt;
		&lt;Port&gt;587&lt;/Port&gt;
		&lt;FromAddress&gt;email@gmail.com&lt;/FromAddress&gt;
	&lt;/SMTPSettings&gt;
	&lt;LogFileDirectory&gt;Daily&lt;/LogFileDirectory&gt;
&lt;/Settings&gt;</pre>
<p>The command line executable would then run the query (&lt;Query&gt;) against the supplied database in the XML file.  For each row returned, the program will send out an email to the user.  Which user?  What email?  The recipients email address would need to be one of the fields returned from the query and noted in the XML file in the element &lt;ToAddressDatabaseField&gt;.  The template for the email body is supplied by the &lt;TemplateEmailFileName&gt; element.   To make the email custom, it is possible to insert fields returned from the database into the email template.  For example, lets say the query returned a field called &#8220;FirstName&#8221;.  In the email template text file, you could have:</p>
<pre>Hello &lt;:FirstName:&gt;,</pre>
<p>When the program ran, it would swap &#8220;&lt;:FirstName:&gt;&#8221; with the contents from the database.  This is similar to a mail merge for emails.  Since all of the values are configurable in the XML file, the usage possibilities are unlimited!  Let say you needed to run this once a week, no problem.  Set up a Windows Scheduled Task to run the executable at the specified interval.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.databatrix.com/2009/09/automatic-email-alerts-from-any-sql-query/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

