<?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>midnight muse &#187; Hour</title>
	<atom:link href="http://midnightmuse.com.au/category/projects/hour/feed/" rel="self" type="application/rss+xml" />
	<link>http://midnightmuse.com.au</link>
	<description>Richard Wright's musings about software and other things that take his fancy</description>
	<lastBuildDate>Thu, 06 May 2010 05:43:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Edit Contact</title>
		<link>http://midnightmuse.com.au/2006/04/28/edit-contact/</link>
		<comments>http://midnightmuse.com.au/2006/04/28/edit-contact/#comments</comments>
		<pubDate>Fri, 28 Apr 2006 08:31:39 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Hour]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/2006/04/28/edit-contact/</guid>
		<description><![CDATA[<p>We need to edit contacts, and add new contacts. Here's how.</p>]]></description>
			<content:encoded><![CDATA[<p>It has been a while since my last post on this project. I have been held up with other things. But now it is time to move on.</p>
<p>The next thing to do is allow the user, in this case, me, to add, edit or delete contacts. Deleting is a subject which will need further investigation, but at this stage we will just allow simple deletes.</p>
<p>First we need a form. So we will create a new inherited form called ContactEditForm, and inherit from our BaseForm. On this form we will place some Labels, Text Boxes and Buttons, so that it looks like the diagram below.<br />
<img src="/wp-content/uploads/2006/04/ClientEdit.gif" alt="Contact Edit Form" /></p>
<p>There are a couple of things to do, all of them fairly straightforward.</p>
<p>First, we have to be able to get to the form, and this is done from the Contact Form, using the New and Edit buttons on that form. We will create a new Contact object in the ContactEdit form by declaring a new private instance of the Contact class, and make it accessible by creating a public property, called Contact. All very standard. The code looks like this:</p>
<pre>
   Private m_Contact as new ContactEntity

   Public Property Contact() as ContactEntity
      Get
          Return m_Contact
      End Get
      Set(ByVal Value as ContactEntity)
          m_Contact = Value
      End Set
   End Property
</pre>
<p>Visual Basic is very verbose, and in C# the code to do the same thing is much more concise. The good thing is that the IDE does most of the work for you.</p>
<p>To edit a contact the user needs to select a contact from the Listview control. Selecting the contact creates a new ContactEntity object and this object is passed to the ContactEdit form in the Set part of the property. So m_Contact, in the ContactEdit form is the same object as the Contact selected in the Contact form. The code to open the ContactEdit form also contains a command to set the Text of the ContactEdit form to <strong>Edit Contact</strong></p>
<p>If the New button is pressed then the ContactEdit form is created but the Text is set to <strong>New Contact</strong></p>
<p> and the <strong>IsNew</strong> property of the ContactEntity is set to true.</p>
<p>In either case the form is then opened with the Show method.</p>
<p>Next we need to set up databinding. In previous versions of VB databinding was a sad joke, but it is much improved in VB.NET. There are a couple of ways to set up databinding. I usually do it in code like this.</p>
<pre>txtSurname.Databindings.Add("Text",m_Contact,"Surname")</pre>
<p>And so on for each of the text boxes. Then it is merely a matter of attaching a Save method to the Save button, and a Delete method to the Delete button. We will revisit Delete at a later date when we consider validation.</p>
<p>The Close button has a form.close method attached and we are almost done.</p>
<p>There are two final things to do. The first is to set the Tab order which is done in the designer from the View menu. You merely select Tab Order from the menu and click each control in the order you wish to tab through them.</p>
<p>Lastly, we set the AcceptButton of the form to Save and the CancelButton to Close, and we are done.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2006/04/28/edit-contact/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Contacts Sub-system</title>
		<link>http://midnightmuse.com.au/2006/03/17/contacts-sub-system/</link>
		<comments>http://midnightmuse.com.au/2006/03/17/contacts-sub-system/#comments</comments>
		<pubDate>Fri, 17 Mar 2006 06:42:54 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Hour]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/2006/03/17/contacts-sub-system/</guid>
		<description><![CDATA[<p>It's time to create our first proper form.</p>]]></description>
			<content:encoded><![CDATA[<p>Everything is set up and now we can start on the first sub-system we are going to build &#8211; Contacts.</p>
<p>The reason I call this a sub-system is that it really stands on its own. All it does is list all the contacts I have and allow me to add new contacts, edit the details of existing contacts and delete contacts. It will interact with the other sub-systems, but it stands on its own.</p>
<p>If I was building this for a client I could deliver this subsystem prior to building anything else. And if the client decided that they didn&#8217;t want the rest of the application then all it would mean is some quick changes to the Main Form and they would have a complete system.</p>
<p>Most of the procedures I use here will be followed in subsequent sub-systems and forms, so I will go into detail for this section, but later on we will move much more quickly.</p>
<p>First thing to do is create a new inherited form called <strong>ContactsForm</strong>. It is inherited from the BaseForm, as most, if not all, our forms will be. We then hook it up to the menu item on the Main Form called <strong>mnuContactDetails</strong>. The code looks like this:</p>
<pre>
Private Sub mnuContactDetails_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles mnuContactDetails.Click
        Dim frm As New ContactForm
        frm.ShowDialog(Me)
End Sub
</pre>
<p>Notice that, because every form is created from the form class it must be instantiated before it can be used, just like any other object. This is quite different from previous versions of Visual Basic.</p>
<p>Back to our Contact Form, and we will put some controls on it. I want to show a listview which will list all the contacts together with phone number. I will also show all the other details for the contact in text boxes to the right of the listview. There is some disagreement between developers as to whether we should use text boxes or labels for read-only information. In reality, it doesn&#8217;t really matter. I use text boxes for information that is coming from the database, and use labels to label things, like other controls. If you are goint to use a text box, as I do, then you need to set the Read-only property to <strong>True</strong>, otherwise the user will think that they can change the values. I also set the TabStop property to false and the BorderStyle to None. If, as I do, you have used a different background colour for the form than the default control colour, then you also need to set the background colour of the text boxes to the same colour. These properties can all be set at once in a matter of seconds, or you could, if you wished, sub-class the text-box to look just like you want and use the new inherited control. This is probably a more object oriented way of doing it.</p>
<p>Now for a bit on the code. Whenever I fill a list type control, such as a Listview or Treeview, or even a list box or combo box, I always do a couple of things.</p>
<ul>
<li>Set the cursor to wait, that is it will show an hourglass, or whatever equivalent cursor the user has set up as their wait cursor.</li>
<li>Prevent the control from updating itself until all the items have been placed into the control. This speeds up the filling of the control.</li>
<li>Clear the control</li>
<li>Populate the control.</li>
<li>Update the control</li>
<li>Reset the cursor.</li>
</ul>
<p>So the code looks like this. My Listview control is named lvContact.</p>
<pre>
   Cursor.current = Cursors.WaitCursor
   lvContact.BeginUpdate()
   lvContact.Items.Clear()
   '////////////////////////////////////////////////////////////
   'Code for populating the listview goes here
   '///////////////////////////////////////////////////////////
   lvContact.EndUpdate()
   Cursor.Current = Cursors.Default
</pre>
<p>Populating the listview can be done in a number of ways. First we need to remember that the Listview control is not data aware, so it cannot be databound. You can create a User Control that is data aware, but it is not really necessary. I use an Object-Relational mapper called <a href="http://www.llblgen.com/">LLBLGen</a> to create my data layer. There are other O/R mappers around, or you can do it another way. I wouldn&#8217;t recommend using datasets, a lot of overhead for no advantage. LLBLGen allows me to create read-only lists which can be sorted, and are returned as data rows. So I add a sort expression and create the list.</p>
<p>So my code for populating the list view is the following:</p>
<pre>
   Dim myrow as Datarow
   Dim LVI as ListViewItem
   For Each myrow in Contacts 'Contacts is the name of my list
      LVI = lvContact.Items.Add(Cint(myrow(0)))
      LVI.SubItems.Add(Cstr(myrow(1)))
      LVI.SubItems.Add(Cstr(myrow(2)))
   Next
</pre>
</p>
<p>The Contacts List, which I created in LLBLGen, has three fields, ContactID, Name and Phone, and I created them in that order, so they are the fields returned by the datarow. I could have used name fields, rather than refer to them by their index, but this way provides a littel better performance.</p>
<p>There are just couple of things left to do. First, when a contact is selected in the ListView we want to show their details in the Read-only text boxes on the right of the form. So I have declared a Private variable m_contact as a ContactEntity. That is the name which LLBLGen has given to Entity created from my Contact table in the database. When I select a contact I create a new ContactEntity object</p>
<pre>m_Contact = New ContactEntity(Cint(lvContact.SelectedItems(0).Text))
</pre>
<p>I then use the properties of the m_Contact object to populate the text boxes.</p>
<p>Finally, I need to hook up the buttons. The Close button is easy, I just close the form with a <code>Me.Close()</code> method. The other two buttons required the creation of a new form, which is the subject of the next episode.</p>
<p>This has been a long article. We won&#8217;t go into as much detail with most of the other forms.</p>
<p><img src="/wp-content/uploads/2006/03/contact.gif" alt="Contact Form" /></p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2006/03/17/contacts-sub-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Chicken and Egg</title>
		<link>http://midnightmuse.com.au/2006/03/16/chicken-and-egg/</link>
		<comments>http://midnightmuse.com.au/2006/03/16/chicken-and-egg/#comments</comments>
		<pubDate>Thu, 16 Mar 2006 08:28:23 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Hour]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/2006/03/16/chicken-and-egg/</guid>
		<description><![CDATA[<p>We now have a slight dilemma &#8211; what comes first?</p>]]></description>
			<content:encoded><![CDATA[<p>It is now time to create the first real page, the Contacts Form, and the database tables to support it.</p>
<p>But there is a problem. I use LLBLGen, an Object Relational Mapper, which maps my database tables to classes. It creates a number of classes:</p>
<ul>
<li>Entity classes &#8211; the classes which map to the tables</li>
<li>Collection classes &#8211; collections of entities</li>
<li>Typed List classes &#8211; read only lists which include the specific fields from tables or relations that I might want to use, for example in list boxes</li>
<li>Classes formed from relationships that I establish</li>
<li>Various factory and helper classes for sorting, filtering and other assorted functions.</li>
</ul>
<p>While there is no problem with the Contact entity, or table, that I will create, It is worthwhile mentioning here the procedure that I follow.</p>
<p>Data is held in a relational database, which follows fairly strict rules. Relational databases can be described in purely mathematical terms, and there is a well-deveoped relational theory to support them.</p>
<p>But the object which I use to populate the controls on the forms, such as text boxes, list boxes, etc, do not necessarily relate 1 to 1 with the tables. So my thinking is in terms of the objects and classes, but my O/R mapper does not translate classes into data tables, rather it maps data tables onto classes.</p>
<p>So I need to consider, first what objects I want to show, and from those determine the data that is needed to create these objects. Once that is done I can then apply relational theory to create the database tables. The O/R mapper then generates my classes which I use to create the objects.</p>
<p>As I said earlier, it is not a problem with the Contacts table or classes. I will create a table for Contacts and map it directly to a Contacts entity.</p>
<p>The Contacts table will consist of the following fields, or attributes, or columns, depending upon your prefered nomenclature &#8211; isn&#8217;t that a great word!</p>
<ul>
<li>ContactID, the primary key and we will make it autoincrement</li>
<li>CompanyName</li>
<li>Surname &#8211; the surname of the contact person within the company</li>
<li>FirstName</li>
<li>Add1 &#8211; the street number and name, or post office box</li>
<li>Add2 &#8211; the town or suburb</li>
<li>Postcode</li>
<li>State &#8211; that is geographical state, like NSW, VIC etc</li>
<li>Phone</li>
<li>Mobile</li>
<li>Email</li>
</ul>
<p>I have realised that I left fax out of this. I have already built the form, but I have made a note to amend it, at some stage soon.</p>
<p>The next thing to do is to create the form, the subject of the next article.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2006/03/16/chicken-and-egg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Main Form</title>
		<link>http://midnightmuse.com.au/2006/03/15/the-main-form/</link>
		<comments>http://midnightmuse.com.au/2006/03/15/the-main-form/#comments</comments>
		<pubDate>Wed, 15 Mar 2006 08:40:14 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Hour]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/2006/03/15/the-main-form/</guid>
		<description><![CDATA[<p>Every application needs somewhere for the user to start.</p>]]></description>
			<content:encoded><![CDATA[<p>I mentioned in <a href="/2006/03/15/setting-up/">the previous article</a> that we need an entry screen, but it won&#8217;t contain much because I haven&#8217;t designed it yet. It is time to build something, but nothing very fancy.</p>
<p>I will go through this in detail because it is the same procedure that I will adopt for all my forms, with a few exceptions.</p>
<p>In Solution Explorer I right clicked on the name of my project, which in this case is HourWin, and in the pop-up menu selected Add inherited form. In the Add New Item dialog box I gave the form the name MainForm and clicked OK. A new dialog appeared asking me which form I wanted to inherit from. I clicked BaseForm and OK. A new form was created.</p>
<p>I could have merely added a new form, and in the code changed the inherits to BaseForm.</p>
<p>For this time only, I have to change the Project Properties so that the new MainForm is the start up form.</p>
<p>I now have a form which shows me two red lines running down each side of the form, and 25 pixels from the border. I will use these as guides to place my controls. The code entered into the paint method in the BaseForm ensures that these only appear if the form is in Design mode.</p>
<p>So now I need some menu items. I will follow the normal Windows standard and have the first menu item <strong>File</strong>, and under that I will place <strong>Exit</strong>. I also know that the first Form I am going to build is for my Contact subsystem, so I may as well create a menu item to access that form.</p>
<p>I build these menu items using the menu control from the toolbox. The File menu item will not have any code attached so I will leave it with its default name. The Exit item will have code so I will change its name to mnuExit, and in the code view simply tell it to end. At some stage I might want to add other code to perform clean up operations, but I am not sure yet. At this stage all this window does is provide me with an entry point to the application sub-systems.</p>
<p>I haven&#8217;t worked out the design of this form yet, so to get to the Contacts section I will add another main menu item, <strong>Contacts</strong>, and under that an item <strong>Details</strong> with the name mnuContactDetails. This gives me the option of adding more windows which relate to Contacts at a later stage, if I want them.</p>
<p>The final thing to do is show the name of the application in the Main Form. In the code after <strong>InitializeComponent</strong> I added <code> Me.Text = MyName</code>. MyName can be set in one of two places. In an application configuration file or in a module.  It doesn&#8217;t really matter which. The point is that it only has to be set once. I set it to <strong>Midnight Hour 1.0</strong>, and now we are done. We have a form that does nothing except exit the application.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2006/03/15/the-main-form/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting Up</title>
		<link>http://midnightmuse.com.au/2006/03/15/setting-up/</link>
		<comments>http://midnightmuse.com.au/2006/03/15/setting-up/#comments</comments>
		<pubDate>Wed, 15 Mar 2006 07:30:09 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Hour]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/2006/03/15/setting-up/</guid>
		<description><![CDATA[<p>The first thing to do is set up the environment for the project.</p>]]></description>
			<content:encoded><![CDATA[<p>Now that we have a very broad idea of what we are going to create we need to set up the environment where all the work will be done.</p>
<p>The application will be written in VB.NET. So the first thing is to create the folders where the work will be done. To do this I opened up Visual Studio and created a blank solution called <em><strong>MidnightHour</strong></em>. That&#8217;s what I will call my new masterpiece.</p>
<p>I had decided that I will use, at least at this stage, an Access database, so I may as well create it now. In the MidnightHour folder that was created by Visual Studio I created a database and called it Hour.mdb. I am not doing anything with it yet, so I won&#8217;t add any tables at this stage.</p>
<p>There are a number of subsystems within the application but I am still going to need a Windows form to serve as an entry point to the application. At this stage I haven&#8217;t designed that yet, so I will just create a main form with a menu that does nothing more than exit the application. When I create each of the subsystems I will add a menu item which I can use to access each system. It might make sense to design this now but I would rather do some coding than graphic designing, so I will do it later.</p>
<p>What I will have to do, though, is create a template form from which I will inherit all my other forms. There are a few reasons for this. First, because this is going to be used on my computer I can set the colours to whatever I want. I don&#8217;t like the Windows control background colour much, so I set the background colour to white. But there are more important reasons.</p>
<p>First, I want to have a standard look to my windows forms. Same colour, same font, same icon, and, most importantly, a standard border, or padding between the window border and the window controls.</p>
<p>To accomplish the first tasks I set the background color of my template form, called BaseForm, in this case to white, attach an icon, and change the font to Tahoma &#8211; I think it looks much better than the default Microsoft sans-serif.</p>
<p>Then change to View Code and select BaseForm events in the Class drop-down list. In the Methods drop-down list I select Paint. This will fire whenever the form is painted. I added the following code:</p>
<pre>
If Me.DesignMode = True Then
          Dim myPen As Pen = New Pen(Color.Red)
          e.Graphics.DrawLine(myPen, 25, 0, 25, Me.Height)
          e.Graphics.DrawLine(myPen, Me.Width - 25, 0, Me.Width - 25, Me.Height)
End If
</pre>
<p>The last thing I want to do with the Visual Studio designer is to ensure that controls get a Windows XP look. Controls such as the Button can have a number of Styles which are set with the FlatStyle property. If you set this style to System you can have apply  XP themes to these controls. But in order for these themes to apply you need a file called <em>applicationname.exe.manifest</em>. This is an XML file and it contains the following code:</p>
<pre>
&lt;?xml version="1.0" encoding="UTF-8" standalone="yes" ?&gt;
&lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">&lt;/assembly&gt;
&lt; description>Windows Forms Common Control manifest&lt;/description&gt;
  &lt;dependency&gt;
    &lt;dependentassembly&gt;
      &lt;assemblyidentity type="win32"
      name="Microsoft.Windows.Common-Controls"
      version="6.0.0.0"
      processorArchitecture="X86"
      publicKeyToken="6595b64144ccf1df" language="*" /&gt;
    &lt;/dependentassembly&gt;
  &lt;/dependency&gt;
&lt;/assembly&gt;
</pre>
<p>The last thing to do prior to any coding is to set up LLBLgen, my O/R mapper of choice. I won&#8217;t go into the details of doing that here because all O/R mappers are set up differently. But because I don&#8217;t have anything in the database it doesn&#8217;t do much yet. All I have done is create the folders and set the preferences.</p>
<p>I told LLBLGen to create a data access layer, and called it DAL. It creates a number of folders for me and created a new VB.NET project called DAL. I now have to add it to the solution and set some references to it.</p>
<p>And that is the end of setting up.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2006/03/15/setting-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Aim</title>
		<link>http://midnightmuse.com.au/2006/03/14/project-aim/</link>
		<comments>http://midnightmuse.com.au/2006/03/14/project-aim/#comments</comments>
		<pubDate>Tue, 14 Mar 2006 02:29:11 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Hour]]></category>

		<guid isPermaLink="false">http://midnightmuse.com.au/2006/03/14/project-aim/</guid>
		<description><![CDATA[<p>The first thing to do is determine what you want the application to do</p>]]></description>
			<content:encoded><![CDATA[<p>Midnight Hour is an application to look after parts of my business. It will keep a list of my clients and contacts, invoices, work done, project design, and a bug tracker. The following is my first draft of the UML (Unified Modelling Language) Package diagram for the application.<br />
<img src="./wp-content/uploads/2006/03/package.gif" alt="UML package diagram of project" /></p>
<p>First off, UML purists may not like my diagrams, but I know what they mean, and I use them to assist me. But this one is pretty obvious.</p>
<p>There are a few things to notice. I have separated each of the subsystems and I will build these separately. This makes it easier to build, because, while there will be a lot of interaction between each of the subsystems, they are each, more or less, complete systems in themselves.</p>
<p>I think this approach also makes for better encapsulation. I need to look after the interfaces between each subsystem, but hopefully I can keep the implementation in each system fairly well hidden.</p>
<p>The database will be built incrementally, and that means that the database mapper will need to be updated whenever there is a database change, but that is no big deal, it takes less than a minute to do. And by only changing the database and the mapper to what I need at the time I avoid building stuff I don&#8217;t want &#8211; the YAGNI (You ain&#8217;t gunna need it!) principle.</p>
<p>I have put the printing as a subsystem, but at this stage I am not sure about that. Certainly I will add some printing classes that will service each subsystem. These are standard printing routines that I use in many projects. But whether I need some printing stuff in each of the other main subsystems or not, I&#8217;m not sure yet. I think I might, but that is something to look at down the track.</p>
</p>
<p>The final decision I had to make at this stage relates to the Contacts subsystem. Should I have a Clients system, for existing clients, and a separate Contacts system? Or should I  do some sub-classing &#8211; a client is a contact with the additional property of having work done, and some extra methods? At this stage I am thinking that there is no difference between a client and a contact. When I have finished some work for a client they are just a contact &#8211; I still have to get more work from them for them to be termed a current client. Or so my thinking is at this stage. But I will see when I analyse the contacts system more fully.</p>
]]></content:encoded>
			<wfw:commentRss>http://midnightmuse.com.au/2006/03/14/project-aim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
