Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Sharing Data with Multiple Windows Forms

Posted by Keith Elder | Posted in .Net, Programming, Smart Clients | Posted on 13-03-2006

1

I see this question a lot on forums, discussion boards and mailing lists.  This question is typically asked in various ways.  Here are a few examples:

  • How do I access a varible in form2 from form1?
  • How do I update a textbox field when a user clicks on a button in form1 to form2?
  • How can form1 be updated with data from form2?
  • How can I share data between two different windows forms?

Whatever the question is the underlying problem is still the same, getting something from A to B or B back to A.  For a developer learning .Net and windows form programming the answer to these questions isn’t so obvious.   Let’s take a look at sharing data such as a strong typed DataSet of Customers between two forms.

To start out with let’s look at the code of a newly created windows form:

namespace KeithElder

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

    }

}

As we see code to a windows form is just an object.  That means if we add a variable in this form that we want to share with another form we would have to make it a public variable.  This is usually what developers try to do at first.  Let’s try this approach first and see where it gets us.

namespace KeithElder

{

    public partial class Form1 : Form

    {

  public CustomerDataSet Customers = new CustomerDataSet();

        public Form1()

        {

            InitializeComponent();

        }

    }

}

Above we added a variable called customers that is public.  This means it can be accessed outside of this form.  If we create another form called Form2 though, how do we easily reference Form1?  In other words we need to get the current running instance of Form1 so we can see the Customers public variable.  Here is one way we could do this:

Form1 myForm = Application.OpenForms[“Form1”] as Form1;

 

This will grab the current open form Form1 and assign it to a variable called myForm.  The first problem with this is we are boxing the Form1 object.  This is costly overhead that we want to avoid.  The other problem is, what if the user closed Form1? Or, what if they never opened Form1?  How do we know?  The answer is we could know, but that would cost us a lot of time developing that logic.  All we REALLY want is the Customers data.  We could care less about the form itself.

 

To solve this problem we can easily create a seperate object that both Form1 and Form2 can access.  This allows us to get data from one location and increase our code reuse factor.  You can call the object whatever you want and even put it wherever you want.  I typically seperate these types of classes out into other class library projects.  The reason is I don’t want any of the objects I reference tied to one single interface.  In the example below I am going to call it “Global.cs”.  Here is how that object would look.

 

using System;

using System.Collections.Generic;

using System.Text;

using System.Data;

 

namespace KeithElder

{

    public static class Global

    {

        private static CustomerDataSet _customers = null;

        public static CustomerDataSet Customers

        {

            get

            {

                if (_customers == null)

                {

                    CustomerDataSetTableAdapters.CustomerTableAdapter ta = new DotNetPimps.CustomerDataSetTableAdapters.CustomerTableAdapter();

                    CustomerDataSet.CustomerDataTable dt =  ta.GetData();

                    _customers = new CustomerDataSet();

                    _customers.Customer.Merge(dt);

                }

                return _customers;

            }

        }

    }

}

 

Notice the class is marked public and static.  This means we do not have to instantiate the class to use the class and we can access it publically in our namespace. There are also two static properties for our customers data.  One is private and one is public.  Having a private static variable allows us to check to see if this variable has ever been accessed and if not, go get the new data.  Otherwise it will return the current data.  You can think of this as sort of a Singleton pattern.

 

The last piece of the puzzle is how do we use this in our Form1 and Form2 scenario.  Let’s look at the code for Form1. There isn’t any need to show Form2 since it will be the same.  That’s the beauty of seperating the data out.

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

namespace KeithElder

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void Form1_Load(object sender, EventArgs e)

        {

            this.customerDataGridView.DataSource = Global.Customers;

            this.customerDataGridView.DataMember = “Customers”;

        }

}

 

On Form_Load we retrieve the customer data and bind that to our DataGridView control.  The same code would apply to Form2.

Page Methods and URL rewriting

Posted by Keith Elder | Posted in Asp.Net, Programming | Posted on 11-03-2006

0

Although I haven’t used this particular project, I ran across something today that I thought was an interesting project.  The project allows you to handle page methods and rewrite URLs.  For example if you have a URL like keithelder.net/blog/article.aspx?id=12 and you want it to be keithelder.net/my-title.aspx instead.  Virtual URLs are very handy.  Even on blogs like this for example where you link to a post of a item, you aren’t really hitting a static page.  It is all virtual. 

The project just released an update for VS2005. You can check it out on the offical PageMethods web site.

How an open source developer transitioned to .Net

Posted by Keith Elder | Posted in .Net, Asp.Net, Open Source, PHP, Programming | Posted on 11-03-2006

0

For a long time I’ve been wanting to put this together.  A lot of my friends who were open source advocates like myself are perplexed with my transition to what they call the “Dark Side” of development.  Referring of course to Microsoft as the evil empire.  I took some time this morning to finish how and why I migrated from programming mainly in PHP to .Net.  I didn’t want to put this information into a blog post because as I was writing it, it just didn’t feel right so I created an article out of it.  In order to give you the full picture I give some information on my background to cement how firmly planted I was in open source technologies.  Then I give you some of my thoughts on the conversion process.  In the end, I give some advice for others that might be curious as how to make this conversion.

NOTE: This is the original article below (thank you wayback machine!)

Intro
Let me be the first to point out that I haven’t always done .Net. No one really has since it has been around for only a few years, let’s be honest.  For all practical purposes the technology is still fairly new.  Before .Net I was primarily developing web-based applications using LAMP (linux, apache, php, mysql).  The $1,000,000.00 question is how does one transition from LAMP to .Net?  And more important is why?  After all, aren’t those technologies left and right brian technologies?  These are the questions I hope to answer in this article.

My Background
Let’s first start out back in 1993 when I was in college.  In 1993 most computers were  Windows 3.1 and a few people were holding onto their Amigas while others were running a Mac.  486 computers reigned supreme and Doom 2 was the big hit.  I was bored with my Windows 3.1 486 computer though.  I had read just about every help file in the whole system and knew all the command line switches to programs that the average computer user didn’t even know existed.  I then got introduced to Linux by the primary Unix Administrator at the college.  I remember the day vividly because he called me into his office because I had taken over the X11 terminals in the lab and he wanted to know how I did it.  Sitting in his office he had a Gateway P133 machine running X11 (the primary graphics front-end to unix operating systems).  I of course questioned how he was running it on a standard PC because up until this time, standard PC equipment couldn’t be used.  Even though I was in trouble I was still curious.  He explained it was a new unix like operating system that was free.  He then showed me how he was using it and I was hooked.  The thought of running multiple programs at the same time on my PC and using the same tools the college was using (mainly so I could hack my friends shell accounts) was appealing.  I immediately went out and bought 50 floppy discs, download Slackware and started compiling.  Trying to get things to compile and work were just fun.  I spent 6 months just getting my Trident 1MB video card to work with XWindows.  I have no idea why at the time but looking back on it I guess this more challenging than the assignments I was getting from the teachers.

By 1994 I was working for the college IT department and we setup one of the first known Linux labs.  I think it was the first Linux lab in the country but I don’t have any proof, let’s just say we were an early adopter.  In the lab students could browse the web, write papers, all within their shell accounts on the cluster, or they could dual boot the computer into Windows.  Pretty cool stuff for 1994.  After I graduated college with a music degree and a computer science minior, I continued playing with Linux and open source software.  When my wife and I moved to Ann Arbor, MI, I joined a local Linux User Group.  It wasn’t long after joining I started presenting at the group with topics ranging from how to get your TV Tuner card to work in Linux to “Migrating Business Processes to the Web Using Open Source Technologies”.  I spent a lot of time coding and doing system administration in the open source world and in 1997 started my own web hosting company which I still have today.  Most everything I did after 1997 was based on what the community calls the LAMP model (Linux, Apache, Mysql, PHP).  I didn’t even have a Windows PC, except for my wife’s computer.  After doing so many Linux presentations and becoming somewhat of a go to guy based on my professional experience I was invited to teach at a local college.  There I taught four classes on Linux which led students to a Linux Certification.  The classes included an introduction, system administration, networking and security.  I also taught the first PHP class at the college and continued to do so until it got taken over by another professor.

After using Linux for years, I had taken the OS just about as far as I could take it.  I was growing tired of reading Howto’s, compiling code, posting to newsgroups, loading untested software and drivers and bringing down my PC for days at a time.  For me the experience was about learning.  In other words, why break a production server when I can break my own?  I was growing tired of this routine nevertheless.  Using a computer with Linux on it was like, well, work.  Using Linux on servers I was happy as a lark.  But, for my personal day to day machine, it was work.  Why couldn’t I just plug something into my personal PC  and it work?  Why did I have to touch the command line all the time?  Why did I have to compile or hack a driver just to plugin a digital camera and transfer a picture to the PC?

Once Apple announced Mac OS X I started watching it pretty closely.  I was waiting on the moment their new operating system (which was unix based) was ready for prime time.  In 2002 I decided to switch from Linux as my primary OS to OS X.  I acquired a Powerbook and an Ipod and was very pleased.  OS X was such a blessing over Linux.  I was a true convert even though my attempts to get into the switch commercials at the time failed.  I was shouting OS X from the roof tops.  I no longer had to fight Linux on a laptop to get work done and was able to do so much more.  During my Mac OS X switch I was working for a consulting company who focused on building web applications using the LAMP model. We held PHP User Group meetings at the company and several other members were moving to OS X as well.  It was a great combination.

In 2004 I was hired as a PHP developer for Quicken Loans.  When I joined the company I was given a dual processor Mac running OS X and told to write PHP code.  This was great!  I was working for one of the best companies in the country and getting to do what I loved.

As you can see I was an open source developer.  It’s the only thing I really knew and the only thing I had ever really done.

The Conversion Begins
After working at Quicken for several months I started to change.  Call it whatever you want but working for a larger company changed how I started to view things.  I can’t explain it but I started to somehow think differently about the technology I was so passionate about.  Was I maturing?  I don’t know.  In retrospect I think once you absorb a technology so deep, two things happen.  One is you get bored.  The otherthing that happens is you know all of the strengths and weaknesses of the technology and you find yourself looking at other technologies to plug into the holes.

Early in 2004, I started playing with .Net while researching Sharepoint Portal Server for the company’s intranet.  The company intranet was written in PHP and I was assigned to the intranet.  We were having lots of problems with single sign on and other things like integrating with Active Directory.   Without giving too many details away, let me just say that our intranet is huge.  Thousands and thousands of pages, applications, content, data, etc.  Basically if you want to know anything, you go to the intranet.  I started researching Sharepoint because I was asked to look at it.  It wasn’t something I would have started looking at on my own given my background that’s for sure.  As I researched Sharepoint and Asp.Net, the more I read, the more I became intrigued by it.  As I mentioned earlier I had become bored and disgruntled with PHP.  I felt I had done just about everything there was to do with the language and the platform.  And, let’s face it, PHP is just for the web.  I wanted something more.  Something that challenged me mentally while also making my life easier.  Something that I could learn that would provide me a one stop shop for whatever I wanted to write as a developer.  I was looking for a Swiss Army Knife. I wanted to be able to learn the ins and outs of one technology and then write either a web application, desktop application,  mobile application, smart phone application or anything in between.

While investigating .Net I decided I was going to take my open source advocate hat off and place it in the floor. I then approached .Net as if I was an unbiased “architect” who had to make a decision which technology he was going to recommend.  Once I made this conscious decision I started to notice how well thought out the platform was.  .Net wasn’t just a scripting language like PHP, this an entire platform full of swiss army knives!  I finally managed to get my hands on Visual Studio and this is where I became even more impressed!  But wait, this is a Microsoft technology!  This can’t be good.  I mean after all Macs rule supreme and open source rocks.  What was going on?  Could it be I was turning to the “dark side” after all of these years of avoiding it?

All the while I was researching .Net I was still writing PHP applications.  This is where I started to differentiate the technologies and this is important.  I started to catch myself saying things like, “I could have done this a lot easier in Asp.Net”, or “Man I wish I could debug this better”, or “Why do I have to build my own session object or cache object and waste my time?”.  I could feel the dark side coming over me as I added more features to our intranet and built additional one off applications.  Writing code in VIM or Zend Studio on my Mac started to become more of a chore or a task and I found myself fighting the tools I had used for years.

Defending the “Dark Side”
Obviously by this point I was at a crossroad.  Then one day I got into a discussion at the water cooler with a coworker.  I found myself in the middle of a .Net vs PHP dual.  My coworker had his PHP pistol drawn and was firing away at me.  Every shot my coworker hurled at me I was able to deflect.  This surprised me.  Speed he mentioned for example.  Asp.Net code is complied I said unlike PHP which is just a scripting language.  I can compile my PHP code to byte code he added, and then I said yes, but you have to purchase Zend’s compiler.  I don’t have to purchase anything I continued adding.  He then drew back his open source pistol and hurled another bullet at me and said, well, PHP is free.  I then said, so is .Net.  Anyone can download the .Net framework, install it and start writing .Net apps.  I then added there was even an open source project called Mono that is taking the .Net framework and building it cross platform.  My coworker had fired two shots and my .Net shield had deflected them.  What was going on?  Why was I defending the technology I had used for years?  He then had one shot left in his open source barrell.  He pulled the trigger and “security” was fired at me.  This was the one I knew he was going to bring up and  I had researched this very topic and was shocked at what I found.  So he states, “well, that doesn’t matter, PHP is still more secure than .Net”.  By this point in the dual he was getting frustrated and had starting moving from fact based arguing to emotional based arguing.  I could just tell by his tone.  Then I said, “That’s interesting you say that because I did some research on it and comparing the .Net framework to PHP since .Net’s first release, it has only had 3 security holes.  PHP has had 43.”.  My coworker then dropped his open source gun and said, “hmm, really?”.

Conversation Complete
At this point I knew my conversion to the “dark side” was complete.  I had evaluated both technologies.  One I knew extremely well, the other I was just scratching the surface but it didn’t matter because the more I dug into .Net the more I moved away from PHP.  By this point my love affair with .Net was starting to spread internally.  When one of your coworkers on the Unix Team starts calling you “Syth Lord Elder”, you know you have turned (true story, and he still calls me this to this day but he’s trying to find a word higher than Syth) to the “dark side”.  To my coworker’s credit who was at the water cooler the day I defended the “dark side” he started researching .Net. Today I am proud to report he and I were founding  members of our internal .Net team.

Since my “re-birth” as a programmer as I like to call it, I’ve done quite a bit with .Net.   I spend most of my time building a Smart Client at work along with a lot of web services and web applications.  I am also building mobile applications and working on a mobile CRM product for all of our bankers in my spare time.  I also spend a lot of time training and mentoring to other programmers who are moving from various languages to .Net too.  I enjoy the training and mentoring since I have an education degree.  I need to use it for something right?

Word of Advice
That’s it.  Now you know how an open source LAMP developer made the transition to .Net.  It has been a long road for me needless to say.  Getting out of your comfort zone and learning new things can be frustrating.  Trust me I know. Things that would take you two minutes, now take you twenty minutes because you have to read how to do it within the new platform.  My recommendation for anyone that wants to learn .Net that is coming from another background as I did is this:

  1. First and foremost throw yourself into a really good C# book.  Don’t bother reading anything else.  Learn the basics of the language first, then learn what the .Net framework provides you as a developer.  Remember that the language and the framework are two seperate things.
  2. Second, dive head first into the framework on MSDN.  Dig into the namespaces of System.Data, System.Collections, System.XML and those type of things that you are going to use all the time.
  3. After that, download Visual Studio Express for free and learn how to use the IDE.  This is where you’ll really start to see how complex things turn into simple drag and drop operations.
  4. Lastly, don’t get discouraged or overwhelmed at the amount of information on .Net.  There is tons of information about .Net on the Internet and it is easy to get overwhelmed.  Remember that Microsoft is a big company and they have 1,000’s of developers pumping out code everyday.  Don’t let it discourage you.

Drop me a Line
I was speaking to one of the Microsoft reps in Jackson, MS at the launch event and he says I’m the only person that he knows of doing .Net programming in Hattiesburg, MS.  That doesn’t surprise me, but by the slim chance that someone from Hattiesburg reads this for the love of a good framework contact me!  Just take my first name and this domain and you’ve got my email address (decrypt that spam engines!).

Converting Generic Lists or Collections to a DataSet

Posted by Keith Elder | Posted in .Net, Programming | Posted on 10-03-2006

24

Today I had a situation where I was calling a web service that returned an array of items.  Here is a sample of the XML the web service was returning. 

<?

xml version=1.0 encoding=utf-8?>
<
ItemCollection>
   <
item>
      <
FirstName>Keith</FirstName>
      <
LastName>Elder</LastName>
      
<FavoriteColor>Blue</FavoriteColor>
   </
item>
   <
item>
      <
FirstName>Chris</FirstName>
      <
LastName>Risner</LastName>
      
<FavoriteColor>Pink</FavoriteColor>
   </
item>
   <
item>
      <
FirstName>David</FirstName>
      <
LastName>Little</LastName>
      <
FavoriteColor>Carnation Pink</FavoriteColor>
   </
item>
</
ItemCollection>

The web service returned the data as expected but I needed to bind this to a DataGridView in the user interface.  For anyone that has used VS2005 you know this is pretty simple.  I added a new data source of type “Object” and selected my ItemCollection object that was generated from the WSDL of the web service.   I dropped the ItemCollection onto the designer and I had a DataGridView with all of my columns.  So far, I’ve spent about 30 seconds on this and I’ve connected to a web service and bound data to the UI.  I was going to be done with this in a few minutes.  I proceeded to take out the columns that I didn’t want showing and built the solution and everything looked great. 

I then referred back to the spec and noticed something that I missed.  The columns need to be sortable in the UI.  This poses a problem because the data that is coming back from the web service gets converted into an array of items (items[]).  Although we can bind an array to a DataGridView there isn’t an easy way to make the DataGridView sort this information based on each column.

I stared at my screen for a few minutes and came to the conclusion that I was going to need to convert the items[] to a DataSet since when bound to a DataGridView it would provide automatic sorting as well as filtering down the road in case someone decided they wanted to search this data (which they typically do). I started then writing a CollectionToDataSet object that would take a collection of items and convert the collection to a DataSet.  When you decide to go down this path to make this type of library you really hate building something that only works for one type of object.  I first got the new class working but it only worked with the type of object I was working with.  During my playing around with the new class a light bulb went off and it hit me this would be a good place to implement a Generic. 

Here is the end result of the class which uses a Generic to figure out which type of object is being passed in.  The only thing it must do is implement the ICollection interface and things work.  Here is what I came up with.

    /// <summary>

    /// This will take anything that implements the ICollection interface and convert

    /// it to a DataSet.

    /// </summary>

    /// <example>

    /// CollectiontoDataSet converter = new CollectionToDataSet<Letters[]>(letters);

    /// DataSet ds = converter.CreateDataSet();

    /// </example>

    /// <typeparam name=”T”></typeparam>

    public class CollectionToDataSet<T> where T : System.Collections.ICollection

    {

        T _collection;

        public CollectionToDataSet(T list)

        {

            _collection = list;

        }

 

        private PropertyInfo[] _propertyCollection = null;

        private PropertyInfo[] PropertyCollection

        {

            get

            {

                if (_propertyCollection == null)

                {

                    _propertyCollection = GetPropertyCollection();

                }

                return _propertyCollection;

            }

        }

 

        private PropertyInfo[] GetPropertyCollection()

        {

            if (_collection.Count > 0)

            {

                IEnumerator enumerator = _collection.GetEnumerator();

                enumerator.MoveNext();

                return enumerator.Current.GetType().GetProperties();

            }

            return null;

        }

 

        public DataSet CreateDataSet()

        {

            DataSet ds = new DataSet(“GridDataSet”);

            ds.Tables.Add(FillDataTable());

            return ds;

        }

 

        private DataTable FillDataTable()

        {

            IEnumerator enumerator = _collection.GetEnumerator();

            DataTable dt = CreateDataTable();

            while (enumerator.MoveNext())

            {

                dt.Rows.Add(FillDataRow(dt.NewRow(),enumerator.Current));

            }

            return dt;

        }

 

        private DataRow FillDataRow(DataRow dataRow, object p)

        {

            foreach (PropertyInfo property in PropertyCollection)

            {

                dataRow[property.Name.ToString()] = property.GetValue(p, null);

            }

            return dataRow;

        }

 

        private DataTable CreateDataTable()

        {

            DataTable dt = new DataTable(“GridDataTable”);

            foreach (PropertyInfo property in PropertyCollection)

            {

                dt.Columns.Add(property.Name.ToString());

            }

            return dt;

        }

    }

 

There you go!  A class to take any type of object that implements the ICollection interface and convert it to a DataSet.

 

As I was writing this article I thought of another way this could be done.  Since the items[] is serializable to XML and a DataSet can take XML and convert that to a DataSet through the ReadXml() method, what I could have done is convert the object to XML, then have a DataSet just read in the XML.  Just food for thought.  I may play with that later on to see which one is “faster”.  I can tell you that serializing the object and then converting it would be a lot less code to write initially, however, this class will probably come in handy more than not.

 

Let me know what you think about the class or if you have any ideas on how to improve it or ways you would have done it differently.  I’ve attached the class file to this post for those that want to download it and give it whirl.

Single quotes in DataView.RowFilter and DataSet Selects

Posted by Keith Elder | Posted in .Net, Programming, Smart Clients | Posted on 09-03-2006

3

I’ve been working on a new feature for a Smart Client at work and it was time to push it to beta and have QA go over it.  I was speaking to the QA team member and they were certain they could break the new feature with just a single quote.  The reason this QA team member said this is they test a lot of PHP web apps which are notoriuos for this type of mistake because of magic quotes turned on or off or whatever.  As I explained to them, the Smart Client shouldn’t encounter this when saving or deleting data as ADO.Net does a pretty good job of handling this type of thing.

Later in the evening I got an email from the QA team member with a screen shot where they had created an entry with a single quote in it. O’Connel for example.  At first I thought it was a joke and then I confirmed it by doing it myself.  What happened I wondered?  I’ve never seen this before.  So, I dug into the code. 

Smart Client HelpDesk Sample AppIn this particular application the screen it occured on was a screen where I had applied a DataView filter to narrow the results of a DataSet.  Here is a simple app I built called “Help Desk” to show you what I am talking about.  Below the menu in the sample you’ll notice I added a TextBox and a Filter button to the ToolStrip.  As you type information into the TextBox it filters the dataset by the First Name column.  Here is how that’s done.

private void toolStripTextBox1_TextChanged(object sender, EventArgs e)
{
   DataView dv = adventureWorksDataSet.Contact.DefaultView;
   dv.RowFilter = “FirstName LIKE ‘%”+ toolStripTextBox1.Text + “%'”;
   this.contactBindingSource.DataSource = dv;
}

The problem the QA team member found was not in the datalayer.  It is pretty simple to see that if you have a single quote in the toolStripTextBox1 object it is going to break the syntax of the RowFilter.  So that’s the problem, now let’s fix it.  I solved it quickly by doing this:

private void toolStripTextBox1_TextChanged(object sender, EventArgs e)
{
   DataView dv = adventureWorksDataSet.Contact.DefaultView;
   dv.RowFilter = “FirstName LIKE ‘%”+ toolStripTextBox1.Text.Replace(“‘”, “””) + “%'”;
   this.contactBindingSource.DataSource = dv;
}

This got me to thinking though, what other situations would this come up.  There may be others where you need to be careful to watch out for this but the only other similar situation was whereby you would do a select on a DataTable to return an array of rows.  For example:

AdventureWorksDataSet

.ContactRow[] rows = adventureWorksDataSet.Contact.Select(“FirstName='” + toolStripTextBox1.Text.Replace(“‘”, “””) + “‘”);

I then started testing all types of other characters in this situation and the single quote is the only thing I came up with that would break it.  I guess in the end we were both right.  I was right in the fact that the datalayer wouldn’t be broken but the QA team memeber did in fact find break it with a single quote.  Note to self.  Self, if you are doing a RowFilter or DataSet Selects with a filter and are getting the input from the user, replace the single quotes.

I’ve attached the sample Help Desk solution to this post for those that want to download and play with it.  All you need is the AdventureWorks database and change the connection string to your own connection string.