﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
  <channel>
    <title>Tim Murphy</title>
    <description>Blogging by Examples</description>
    <link>http://26tp.com/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.5.1.10</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://26tp.com/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Tim Murphy</dc:creator>
    <dc:title>Tim Murphy</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <item>
      <title>Goodbye BlogEngine; Hello Orchard</title>
      <description>&lt;p&gt;It has been 375 days since my last blog post. Why so long? Well I have been busy but the main reason was that there were tweaks I needed to make to the site that made me feel it wasn’t worthwhile. While I am incredibly busy at the moment there are a few posts I have brewing in my head so it’s time to bite the bullet and fix the blog now!&lt;/p&gt; &lt;p&gt;When I installed BlogEngine I thought I’d be smart and do some customisations; bad idea. I needed to fix these customisations and just couldn’t find the time nor had the inclination to do so. I figured I had two options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Install a clean copy of BlogEngine.&lt;/li&gt; &lt;li&gt;Install a different blogging platform.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I’ve decided on the later. Specifically I’m moving the blog to Orchard. I chose Orchard to two reasons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I consider Orchard as a better CMS than BlogEngine.&lt;/li&gt; &lt;li&gt;Now this is petty but who has file extensions on a website anymore?&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I will create a series of posts on the move.&lt;/p&gt;</description>
      <link>http://26tp.com/post/Goodbye-BlogEngine3b-Hello-Orchard.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/Goodbye-BlogEngine3b-Hello-Orchard.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=fa6999c1-3bcd-41c0-8f41-da717daef6d1</guid>
      <pubDate>Mon, 09 May 2011 00:31:20 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=fa6999c1-3bcd-41c0-8f41-da717daef6d1</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=fa6999c1-3bcd-41c0-8f41-da717daef6d1</trackback:ping>
      <wfw:comment>http://26tp.com/post/Goodbye-BlogEngine3b-Hello-Orchard.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=fa6999c1-3bcd-41c0-8f41-da717daef6d1</wfw:commentRss>
    </item>
    <item>
      <title>Deduplicating SQL data</title>
      <description>&lt;p&gt;So you stuff up and didn’t write unit tests to properly test that duplicate data does not get appended to the database. Plus you were a bigger idiot and had not set a unique index on the column.&lt;/p&gt; &lt;p&gt;First thing is to write those unit tests to ensure code is correct.&lt;/p&gt; &lt;p&gt;Now we need to deduplicate the existing data. The following SQL query show you how many affected records there are.&lt;/p&gt;&lt;pre class="brush: sql;"&gt;SELECT LoweredSlug, Count(LoweredSlug)
FROM "Issues.Issues"
GROUP BY LoweredSlug
HAVING (COUNT(LoweredSlug) &amp;gt; 1)
&lt;/pre&gt;
&lt;p&gt;Of course you need to change the table and column names accordingly.&lt;/p&gt;
&lt;p&gt;A quick and dirty why to the remove the duplicates to add the primary key value to the end of the affected data (ie LoweredSlug-PrimaryKey). Here’s the SQL command:&lt;/p&gt;&lt;pre class="brush: sql;"&gt;UPDATE "Issues.Issues"
SET Slug = Slug + "-" + IssueKey, 
    LoweredSlug = LoweredSlug + "-" + IssueKey
WHERE LoweredSlug IN
(
    SELECT LoweredSlug
    FROM "Issues.Issues"
    GROUP BY LoweredSlug
    HAVING (COUNT(LoweredSlug) &amp;gt; 1)
)
&lt;/pre&gt;
&lt;p&gt;No go and fix the database schema to not allow duplicates!&lt;/p&gt;</description>
      <link>http://26tp.com/post/Deduplicating-SQL-data.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/Deduplicating-SQL-data.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=c011fbac-7b7a-4d95-a3b8-41765f705756</guid>
      <pubDate>Thu, 29 Apr 2010 10:59:04 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=c011fbac-7b7a-4d95-a3b8-41765f705756</pingback:target>
      <slash:comments>189</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=c011fbac-7b7a-4d95-a3b8-41765f705756</trackback:ping>
      <wfw:comment>http://26tp.com/post/Deduplicating-SQL-data.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=c011fbac-7b7a-4d95-a3b8-41765f705756</wfw:commentRss>
    </item>
    <item>
      <title>How to install Python and CGI scripts on IIS 7 (Windows 7, Vista, Server 2008)</title>
      <description>&lt;ol&gt; &lt;li&gt;Download and install required version of &lt;a href="http://www.python.org/download/"&gt;Python&lt;/a&gt;.  &lt;li&gt;Open &lt;strong&gt;Internet Information Services&lt;/strong&gt;.  &lt;li&gt;Select the site that requires Python CGI scripts. &lt;li&gt;Ensure &lt;strong&gt;Features View&lt;/strong&gt; is the current view in the middle pane of IIS. &lt;li&gt;Double-click &lt;strong&gt;Handler Mappings&lt;/strong&gt;. &lt;li&gt;Click &lt;strong&gt;Add Script Map…&lt;/strong&gt; in Actions pane. &lt;li&gt;Set the &lt;strong&gt;Request path&lt;/strong&gt; value to &lt;strong&gt;*.cgi&lt;/strong&gt;.  &lt;li&gt;Set the &lt;strong&gt;Executable&lt;/strong&gt; value to &lt;strong&gt;C:\Python26\python.exe -u "%s %s" &lt;/strong&gt;&lt;em&gt;(Change path appropriately)&lt;/em&gt;  &lt;li&gt;Set the &lt;strong&gt;Name&lt;/strong&gt; value to &lt;strong&gt;PythonCGI&lt;/strong&gt;. &lt;li&gt;Click &lt;strong&gt;Request Restrictions…&lt;/strong&gt; button. &lt;li&gt;Click the &lt;strong&gt;Access&lt;/strong&gt; tab in &lt;strong&gt;Request Restrictions&lt;/strong&gt; dialog. &lt;li&gt;Select &lt;strong&gt;Execute&lt;/strong&gt;. &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to return to &lt;strong&gt;Add Script Map&lt;/strong&gt; dialog.&amp;nbsp; &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to save the mapping. &lt;li&gt;Click &lt;strong&gt;Yes&lt;/strong&gt; to &lt;strong&gt;Do you want to enable this ISAPI application?&lt;/strong&gt; dialog. &lt;li&gt;Right-click the newly create &lt;strong&gt;PythonCGI&lt;/strong&gt; mapping and select &lt;strong&gt;Edit Feature Permissions…&lt;/strong&gt; &lt;li&gt;Ensure every permission is ticked. Click &lt;strong&gt;OK&lt;/strong&gt;. &lt;li&gt;Install a simple CGI script to test the web site.&lt;br&gt;&lt;pre class="brush: py;"&gt;print 'Status: 200 OK'
print 'Content-type: text/html'
print
 
print '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;'
print ''
print '&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;'
print ''
print ''&lt;/pre&gt;
&lt;li&gt;Point your browser to the test script and hey presto it should be working.&lt;/li&gt;&lt;/ol&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://vampirebasic.blogspot.com/2009/06/running-mercurial-on-windows.html"&gt;&lt;font color="#0066cc"&gt;http://vampirebasic.blogspot.com/2009/06/running-mercurial-on-windows.html&lt;/font&gt;&lt;/a&gt; 
&lt;li&gt;&lt;a href="http://www.jeremyskinner.co.uk/mercurial-on-iis7/"&gt;&lt;font color="#0066cc"&gt;http://www.jeremyskinner.co.uk/mercurial-on-iis7/&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description>
      <link>http://26tp.com/post/How-to-install-Python-and-CGI-scripts-on-IIS-7-(Windows-7-Vista-Server-2008).aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/How-to-install-Python-and-CGI-scripts-on-IIS-7-(Windows-7-Vista-Server-2008).aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=31c08d48-4589-4201-8d22-4a631e82236a</guid>
      <pubDate>Fri, 16 Apr 2010 12:00:51 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=31c08d48-4589-4201-8d22-4a631e82236a</pingback:target>
      <slash:comments>363</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=31c08d48-4589-4201-8d22-4a631e82236a</trackback:ping>
      <wfw:comment>http://26tp.com/post/How-to-install-Python-and-CGI-scripts-on-IIS-7-(Windows-7-Vista-Server-2008).aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=31c08d48-4589-4201-8d22-4a631e82236a</wfw:commentRss>
    </item>
    <item>
      <title>How to install Python and CGI scripts on Windows Server 2003</title>
      <description>&lt;ol&gt; &lt;li&gt;Download and install required version of &lt;a href="http://www.python.org/download/"&gt;Python&lt;/a&gt;.  &lt;li&gt;Open &lt;strong&gt;Internet Information Services&lt;/strong&gt;.  &lt;li&gt;Open the &lt;strong&gt;Properties&lt;/strong&gt; dialog for web site that required Python CGI scripts.  &lt;li&gt;Go to the &lt;strong&gt;Home Directory&lt;/strong&gt; tab.  &lt;li&gt;Ensure &lt;strong&gt;Execute permissions&lt;/strong&gt; is set to &lt;strong&gt;Scripts Only&lt;/strong&gt;.  &lt;li&gt;Click the &lt;strong&gt;Configuration&lt;/strong&gt; button and select the &lt;strong&gt;Mappings&lt;/strong&gt; tab.  &lt;li&gt;Click &lt;strong&gt;Add…&lt;/strong&gt; button.  &lt;li&gt;Set the &lt;strong&gt;Executable&lt;/strong&gt; value to &lt;strong&gt;C:\Python26\python.exe -u "%s %s" &lt;/strong&gt;&lt;em&gt;(Change path appropriately)&lt;/em&gt;  &lt;li&gt;Set the &lt;strong&gt;Extension value&lt;/strong&gt; to &lt;strong&gt;.cgi&lt;/strong&gt;.  &lt;li&gt;Set &lt;strong&gt;Verbs&lt;/strong&gt; to &lt;strong&gt;All Verbs&lt;/strong&gt;.  &lt;li&gt;Tick &lt;strong&gt;Script engine&lt;/strong&gt; on.  &lt;li&gt;Tick &lt;strong&gt;Verify that file exists&lt;/strong&gt; on.  &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to return to the &lt;strong&gt;Application Configuration&lt;/strong&gt; dialog.  &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to return to the web site &lt;strong&gt;Properties&lt;/strong&gt; dialog.  &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to return to &lt;strong&gt;Internet Information Services&lt;/strong&gt; manager.  &lt;li&gt;Install a simple CGI script to test the installation.&lt;br&gt;&lt;pre class="brush: py;"&gt;print 'Status: 200 OK'
print 'Content-type: text/html'
print
 
print '&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;'
print ''
print '&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;'
print ''
print ''
&lt;/pre&gt;
&lt;li&gt;Point your browser to the test script and hey presto it should be working.&lt;/li&gt;&lt;/ol&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://vampirebasic.blogspot.com/2009/06/running-mercurial-on-windows.html"&gt;&lt;font color="#0066cc"&gt;http://vampirebasic.blogspot.com/2009/06/running-mercurial-on-windows.html&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jeremyskinner.co.uk/mercurial-on-iis7/"&gt;&lt;font color="#0066cc"&gt;http://www.jeremyskinner.co.uk/mercurial-on-iis7/&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description>
      <link>http://26tp.com/post/How-to-install-Python-and-CGI-scripts-on-Windows-Server-2003.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/How-to-install-Python-and-CGI-scripts-on-Windows-Server-2003.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=d6ab9211-87e8-4bc4-8262-9272cbcb74b7</guid>
      <pubDate>Sun, 11 Apr 2010 13:26:57 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=d6ab9211-87e8-4bc4-8262-9272cbcb74b7</pingback:target>
      <slash:comments>168</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=d6ab9211-87e8-4bc4-8262-9272cbcb74b7</trackback:ping>
      <wfw:comment>http://26tp.com/post/How-to-install-Python-and-CGI-scripts-on-Windows-Server-2003.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=d6ab9211-87e8-4bc4-8262-9272cbcb74b7</wfw:commentRss>
    </item>
    <item>
      <title>Building a MVP Framework: Part 3: The About Dialog</title>
      <description>&lt;p&gt;In this post of the &lt;a href="http://www.26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx"&gt;series&lt;/a&gt; we will build the About Dialog.&lt;/p&gt; &lt;h2&gt;The Goal&lt;/h2&gt; &lt;p&gt;Display a dialog showing the application name, version, link to blog and OK button.&lt;/p&gt; &lt;h2&gt;The Model&lt;/h2&gt; &lt;p&gt;I’m quickly learning that there is an effective order to follow when develop a new form for an MVP application:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Model  &lt;li&gt;Presenter  &lt;li&gt;View&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;It is best to write the model first because both the Presenter and the View rely on the model. In particular the Model should be written and compiled before the view so you can use Data Sources in the designer to drag and drop the Model on to the form.&lt;/p&gt; &lt;p&gt;The AboutViewModel has just three readonly properties: ApplicationName, ApplicationVersion, BlogTitle &amp;amp; BlogURL.&lt;/p&gt; &lt;h3&gt;Refactoring&lt;/h3&gt; &lt;p&gt;Obviously the AboutViewModel shares data with the AppWindowViewModel. This shows the benefit of creating ViewModels, we can now refactor the common properties into Models and have each ViewModel refer to the model and our Views are unaffected.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Class AboutViewModel

    Private mApplication As New ApplicationModel
    Private mBlog As New BlogModel

    Public ReadOnly Property Application() As ApplicationModel
        Get
            Return mApplication
        End Get
    End Property

    Public ReadOnly Property Blog() As BlogModel
        Get
            Return mBlog
        End Get
    End Property

End Class

Public Class AppWindowViewModel

    Public mApplication As New ApplicationModel
    Public mBlog As New BlogModel

    Public ReadOnly Property Name() As String
        Get
            Return mApplication.Name
        End Get
    End Property

    Public ReadOnly Property BlogTitle() As String
        Get
            Return mBlog.Name
        End Get
    End Property

    Public ReadOnly Property BlogURL() As String
        Get
            Return mBlog.URL
        End Get
    End Property

End Class

Namespace Models

    Public Class Application

        Public ReadOnly Property Name() As String
            Get
                Return "Building a MVP Application"
            End Get
        End Property

        Public ReadOnly Property Version() As String
            Get
                Return "0.0.3.0"
            End Get
        End Property

    End Class

End Namespace

Namespace Models

    Public Class Blog

        Private mApplication As New Application

        Public ReadOnly Property Name() As String
            Get
                Return mApplication.Name
            End Get
        End Property

        Public ReadOnly Property URL() As String
            Get
                Return "http://www.26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx"
            End Get
        End Property

    End Class

End Namespace
&lt;/pre&gt;
&lt;h2&gt;The Presenter&lt;/h2&gt;
&lt;p&gt;The AboutPresenter has the same requirements as AppWindowPresenter we created in &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-2-The-Application-Window.aspx"&gt;Part 2&lt;/a&gt; so we refactor to create the IPresenter, IView &amp;amp; IModel interfaces.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Interface IPresenter(Of TModel As IModel, TView As IView)

    ReadOnly Property View() As TView
    ReadOnly Property Model() As TModel

End Interface

Public Interface IModel
End Interface

Public Interface IView
    Sub BindData()
End Interface
&lt;/pre&gt;
&lt;p&gt;I’ve also written our first abstract class.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public MustInherit Class Presenter(Of TModel As IModel, TView As IView)
    Implements IPresenter(Of TModel, TView)

    Private mView As TView
    Private mModel As TModel

    Public Sub Initialize(ByVal model As TModel, ByVal startupView As TView)

        mModel = model.MustNotBeNull("model")
        mView = startupView.MustNotBeNull("startupView")

        mView.BindData()

    End Sub

    Public ReadOnly Property Model() As TModel Implements IPresenter(Of TModel, TView).Model
        Get
            Return mModel
        End Get
    End Property

    Public ReadOnly Property View() As TView Implements IPresenter(Of TModel, TView).View
        Get
            Return mView
        End Get
    End Property

End Class
&lt;/pre&gt;
&lt;p&gt;The new AboutPresenter is down to 7 lines of code.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Imports TwentySixTP.MVP

Public Class AboutPresenter
    Inherits Presenter(Of AboutViewModel, AboutView)

    Public Sub New()
        Me.Initialize(New AboutViewModel, New AboutView(Me))
    End Sub

End Class
&lt;/pre&gt;
&lt;h2&gt;The View&lt;/h2&gt;
&lt;p&gt;The AboutView was created with the Form Designer following these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add AboutViewModel to Data Sources. 
&lt;li&gt;Drag AboutViewModel from Data Sources on to form. 
&lt;li&gt;Delete the generated text boxes. 
&lt;li&gt;Update the binding property of each remaining label.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Now the form has been designed we need the following code behind:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Class AboutView
    Implements TwentySixTP.MVP.IView

    Private mPresenter As AboutPresenter

    Public Sub New(ByVal presenter As AboutPresenter)
        MyBase.New()
        Me.InitializeComponent()
        mPresenter = presenter
    End Sub

    Public Sub BindData() Implements TwentySixTP.MVP.IView.BindData
        Me.AboutViewModelBindingSource.DataSource = mPresenter.Model
    End Sub

    Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
        Me.Close()
    End Sub

    Private Sub BlogLinkLabel_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles BlogLinkLabel.LinkClicked
        System.Diagnostics.Process.Start(mPresenter.Model.Blog.URL)
    End Sub

End Class
&lt;/pre&gt;
&lt;h2&gt;Showing Aboutview&lt;/h2&gt;
&lt;p&gt;It is the responsibility of the Application view, sorry presenter in this MVP world, to show the AboutView on startup.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Class AppWindowPresenter
    Inherits Presenter(Of AppWindowViewModel, AppWindow)

    Public Sub New()
        Me.Initialize(New AppWindowViewModel, New AppWindow(Me))

        mStartupView.ShowAboutView()

    End Sub

End Class
&lt;/pre&gt;
&lt;h2&gt;The Unit Tests&lt;/h2&gt;
&lt;p&gt;We have a problem Houston. Actually we have two problems.&lt;/p&gt;
&lt;h3&gt;Problem 1&lt;/h3&gt;
&lt;p&gt;The AboutView is now being displayed during our tests. Not only is this visually annoying as AboutView is a dialog it stops the tests waiting for our response. What will the answer be????&lt;/p&gt;
&lt;p&gt;Mock is the answer, of course!!! I’m relatively new to mocking so sorry if I’ve done some stupid.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;&amp;lt;TestMethod()&amp;gt; Public Sub StartupForm_ReturnsAppWindow()

    ' Arrange
    ' ---------------------------------------------------------------------
    Dim mock = New Moq.Mock(Of AppWindowPresenter)
    mock.Setup(Function(m As AppWindowPresenter) m.ShowAboutView())
    mock.CallBase = True

    Dim presenter = mock.Object

    ' Act
    ' ---------------------------------------------------------------------
    Dim actual = presenter.View

    ' Assert
    ' ---------------------------------------------------------------------
    actual.ShouldNotBeNull()
    actual.ShouldBeInstance(Of AppWindow)()

End Sub&lt;/pre&gt;
&lt;p&gt;The above “mocks” the AppWindowPresenter and in particular it stubs out the ShowAboutView method so the dialog does not get displayed nor pause our unit tests.&lt;/p&gt;
&lt;h2&gt;Problem 2&lt;/h2&gt;
&lt;p&gt;The unit test for AboutView.BindData fails.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;&amp;lt;TestMethod()&amp;gt; Public Sub AboutView_BindsData()

    ' Arrange
    ' ---------------------------------------------------------------------
    Dim presenter = New AboutPresenter

    ' Act
    ' ---------------------------------------------------------------------
    Dim frm = presenter.View()

    ' Assert
    ' ---------------------------------------------------------------------
    frm.BlogLinkLabel.Text.ShouldEqual(presenter.Model.Blog.Name)

End Sub&lt;/pre&gt;
&lt;p&gt;The test fails on the last line. Binding has been setup but .NET has not changed the value of frm.BlogLinkLabel.Text yet, seems not to do it until the form is actual displayed.&lt;/p&gt;
&lt;p&gt;After some research it seems the only way for the test to work as is to show the form in the unit test. This works but I’m not sure it’s the best way to go about it. On reflection what is it we are trying to test. Can we trust that Microsoft have tested their binding framework? I think so. What we actually want to test is have we set the binding up correctly. Well of course we have if we used the designer’s drag and drop. But what if we change a property name? Because the designer uses “magic strings” it won’t recognise the refactoring. So what we need to do is test the definition of the bindings is correct. I’ll write a blog dedicated to this problem and its solution.&lt;/p&gt;
&lt;h2&gt;Source Code&lt;/h2&gt;
&lt;p&gt;Source code is available for this post via SVN:&lt;/p&gt;&lt;pre class="brush: bat;"&gt;svn export https://26tp.svn.codeplex.com/svn/tags/Building a MVP Framework - Part 3
&lt;/pre&gt;
&lt;p&gt;Or to get the latest copy of the complete series code:&lt;/p&gt;&lt;pre class="brush: bat;"&gt;svn export https://26tp.svn.codeplex.com/svn/trunk/
&lt;/pre&gt;
&lt;p&gt;View the 26tp.Examples.MVP project via the 26tp.Examples.sln solution.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this post we did some refactoring to create our first interfaces and abstract class. We also introduced some mocking. Finally we found a problem unit testing data binding.&lt;/p&gt;
&lt;p&gt;The next post, Create SQLite database from a SQL file, will look at a presenter controlling a collection of forms.&lt;/p&gt;</description>
      <link>http://26tp.com/post/Building-a-MVP-Framework-Part-3-The-About-Dialog.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/Building-a-MVP-Framework-Part-3-The-About-Dialog.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=1e963e3d-eb9c-4651-ba47-f5fc4acd10f8</guid>
      <pubDate>Sun, 10 Jan 2010 08:48:56 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=1e963e3d-eb9c-4651-ba47-f5fc4acd10f8</pingback:target>
      <slash:comments>848</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=1e963e3d-eb9c-4651-ba47-f5fc4acd10f8</trackback:ping>
      <wfw:comment>http://26tp.com/post/Building-a-MVP-Framework-Part-3-The-About-Dialog.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=1e963e3d-eb9c-4651-ba47-f5fc4acd10f8</wfw:commentRss>
    </item>
    <item>
      <title>Building a MVP Framework: Part 2: The Application Window</title>
      <description>&lt;p&gt;In &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx"&gt;Part 1&lt;/a&gt; of &lt;a href="http://www.26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx"&gt;series&lt;/a&gt; I said there would be five forms; in fact there are six. I forgot about the application window. The application window needs a title and link in the status bar to this series’ table of contents.&lt;/p&gt; &lt;p&gt;In Part 2 of the&amp;nbsp; series I’m going to design and implement a simple Welcome Dialog. Personally I hate Welcome Dialogs but its nice and simple to get the ball rolling.&lt;/p&gt; &lt;p&gt;The dialog will display:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Application Name  &lt;li&gt;Version  &lt;li&gt;Web Link  &lt;li&gt;OK button&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;Application Startup&lt;/h2&gt; &lt;p&gt;Later in this post I’ll describe the Presenter class but for now suffice to say it is god in an MVP application. That being the case we need to change the default startup routine of the WinForm project. Create a module with a public sub main:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Module Main

    Public Sub Main()

        Dim appWindowPresenter = New AppWindowPresenter

        Application.Run(appWindowPresenter.StartupForm)

    End Sub

End Module
&lt;/pre&gt;
&lt;p&gt;The name of the module is not important but the procedure must be named Main.&lt;/p&gt;
&lt;p&gt;Next go into the project properties and untick the &lt;strong&gt;Enable application framework&lt;/strong&gt; option and select Sub Main as the &lt;strong&gt;Startup object&lt;/strong&gt; (must be done in that order.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.26tp.com/image.axd?picture=ApplicationStartup.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ApplicationStartup" border="0" alt="ApplicationStartup" src="http://www.26tp.com/image.axd?picture=ApplicationStartup_thumb.png" width="664" height="331"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;The Presenter&lt;/h2&gt;
&lt;p&gt;As previously mentioned the Presenter is god. It is responsible for constructing the form, serving data to the form and responding to UI events.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Class AppWindowPresenter

    Private mStartupForm As AppWindow

    Public Sub New()
        mStartupForm = New AppWindow(me)
    End Sub

    Public ReadOnly Property StartupForm() As AppWindow
        Get
            Return mStartupForm
        End Get
    End Property

End Class
&lt;/pre&gt;
&lt;p&gt;As you can see in the above code the AppWindowPresenter has a reference to the AppWindow form is constructs and AppWindow has a reference to AppWindowPresenter. This is required so when form receives a UI event it can talk to the presenter and the presenter can talk back to the window.&lt;/p&gt;
&lt;h2&gt;The Model&lt;/h2&gt;
&lt;p&gt;The AppWindow needs to set the text for it’s title and status bars; it does this via a Model. A Model is simple a data object, entity call it what you like. In this series of example class names ending with Model refer to object holding raw data from the database. Classes ending with ViewModel are objects tailor made for a View.&lt;/p&gt;
&lt;p&gt;The AppWindowViewModel has just three readonly properties Name, BlogTitle and BlogURL.&lt;/p&gt;
&lt;h2&gt;Binding The Data&lt;/h2&gt;
&lt;p&gt;Now we have the model and the application window being displayed we need the application window to update itself with the values in the model. A quick change the presenter constructor:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Sub New()
    mModel = New AppWindowViewModel
    mStartupForm = New AppWindow(Me)
    mStartupForm.BindData()
End Sub
&lt;/pre&gt;
&lt;p&gt;Followed by adding AppWindow.BindData() method:&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Sub BindData()
    Me.Text = mPresenter.Model.Name
    Me.BlogToolStripStatusLabel.Text = mPresenter.Model.BlogTitle
End Sub&lt;/pre&gt;
&lt;p&gt;Now when the application starts the application title bar and status bar are updated with the required buttons.&lt;/p&gt;
&lt;h2&gt;The Unit Tests&lt;/h2&gt;
&lt;p&gt;So far I’ve not mention unit tests. Well of course I’ve been writing this as we go. As you can imagine the unit tests for the AppWindowPresenter and AppWindowViewModel class are very quick and easy to implement. The AppWindow tests are equally easy.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;&amp;lt;TestClass()&amp;gt; Public Class AppWindow_Tests

    &amp;lt;TestMethod()&amp;gt; Public Sub CanConstruct()

        ' Arrange

        ' Act
        Dim value = New AppWindow(New AppWindowPresenter)

        ' Assert
        value.ShouldNotBeNull()

    End Sub

    &amp;lt;TestMethod()&amp;gt; Public Sub AppWindow_BindsData()

        ' Arrange
        Dim presenter = New AppWindowPresenter

        ' Act
        Dim frm = presenter.StartupForm()

        ' Assert
        frm.Text.ShouldEqual(presenter.Model.Name)
        frm.BlogToolStripStatusLabel.Text.ShouldEqual(presenter.Model.BlogTitle)

    End Sub

End Class
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you can see the we have been able to test every method in the AppWindow with very little pain or fanfare.&lt;/p&gt;
&lt;h2&gt;Source Code&lt;/h2&gt;
&lt;p&gt;Source code is available for this post via SVN:&lt;/p&gt;&lt;pre class="brush: bat;"&gt;svn export "https://26tp.svn.codeplex.com/svn/tags/Building a MVP Framework - Part 2"
&lt;/pre&gt;
&lt;p&gt;Or to get the latest copy of the complete series code:&lt;/p&gt;&lt;pre class="brush: bat;"&gt;svn export https://26tp.svn.codeplex.com/svn/trunk/
&lt;/pre&gt;
&lt;p&gt;View the 26tp.Examples.MVP project via the 26tp.Examples.sln solution.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this post we can created our first Presenter, Model &amp;amp; Form classes along with accompanying unit tests. So far the framework has meet all the goals set out in &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx"&gt;Part 1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Has it been worth it. It would have been quicker and easy just to design the AppWindow in Visual Studio, use the properties window to set the required values and we could write unit tests for this. But one positive side effect is we can easily read the code to see exactly have properties have been set. Using the MVP pattern we are able to create the AppWindow with the designer and the only properties we change in the designer is the name of the controls.&lt;/p&gt;
&lt;p&gt;In the next post, &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-3-The-About-Dialog.aspx"&gt;The About Dialog&lt;/a&gt;, we will look at using a BindingSource to bind the model to the form.&lt;/p&gt;</description>
      <link>http://26tp.com/post/Building-a-MVP-Framework-Part-2-The-Application-Window.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/Building-a-MVP-Framework-Part-2-The-Application-Window.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=a747c4dc-de09-42f2-a501-7a907e2ceb4e</guid>
      <pubDate>Fri, 08 Jan 2010 12:10:47 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=a747c4dc-de09-42f2-a501-7a907e2ceb4e</pingback:target>
      <slash:comments>1961</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=a747c4dc-de09-42f2-a501-7a907e2ceb4e</trackback:ping>
      <wfw:comment>http://26tp.com/post/Building-a-MVP-Framework-Part-2-The-Application-Window.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=a747c4dc-de09-42f2-a501-7a907e2ceb4e</wfw:commentRss>
    </item>
    <item>
      <title>Building a MVP Framework: Part 1: The Goals</title>
      <description>&lt;p&gt;In Part 1 of the &lt;a href="http://www.26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx"&gt;Building a MVP Framework&lt;/a&gt; series I’m going to define the goals of the sample application and the framework itself.&lt;/p&gt; &lt;h2&gt;Framework Goals&lt;/h2&gt; &lt;p&gt;The goals of any Framework are (or at least should be) determined by the requirements of the applications that will use the Framework. The MVP Framework must address the following needs.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Separation of UI and Business Logic code.  &lt;li&gt;Thin UI.  &lt;li&gt;Easy to implement.  &lt;li&gt;Easy to Unit Test a very high percentage of the application.&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;Sample Application Goals&lt;/h2&gt; &lt;p&gt;In this series I’ll be using the &lt;a href="http://chinookdatabase.codeplex.com/"&gt;Chinook Database&lt;/a&gt; imported into a SQLite database. Initially the application will have &lt;strike&gt;five&lt;/strike&gt; six forms.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Application Window.  &lt;li&gt;Welcome Dialog.  &lt;li&gt;Create SQLite database from SQL file.  &lt;li&gt;Edit Artists. Very simple form allowing scrolling throw the list of Artists and editing.  &lt;li&gt;Grid of Artists. Very simple form display a grid of Artists with editing.  &lt;li&gt;Artists Explorer. The explorer will have three panels: Tree, Grid &amp;amp; Edit. The explorer will use and display data from the Artist, Album, Track, PlaylistTrack &amp;amp; Playlist tables of the Chinook Database.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In Part 2, &lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-2-The-Application-Window.aspx"&gt;The Application Window&lt;/a&gt;, I’ll look at the first implementation of MVP.&lt;/p&gt;</description>
      <link>http://26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=00195e30-8d70-47e8-b96c-e8f1455dc0f3</guid>
      <pubDate>Thu, 07 Jan 2010 22:43:10 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=00195e30-8d70-47e8-b96c-e8f1455dc0f3</pingback:target>
      <slash:comments>304</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=00195e30-8d70-47e8-b96c-e8f1455dc0f3</trackback:ping>
      <wfw:comment>http://26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=00195e30-8d70-47e8-b96c-e8f1455dc0f3</wfw:commentRss>
    </item>
    <item>
      <title>Building a MVP Framework: Table of Contents</title>
      <description>&lt;p&gt;Lately I’ve spent a reasonable amount of time with ASP.NET MVC and grown to love the pattern.&amp;nbsp; My current project is a Windows Form application and in need of help from a similar. Having spent the last two days researching the topic I’ve not been able to find a framework that I’m satisfied. Largely they are under documented or overly complex. I’m trying to make development easier that harder!&lt;/p&gt; &lt;p&gt;To quote a &lt;a href="http://www.hanselman.com/"&gt;Scott Hansleman&lt;/a&gt; blog &lt;a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx"&gt;post&lt;/a&gt; I read recently “If you don't like something, fix it.”. I have a very pressing need and short deadline for the current project. In other words to begin with it’s going to be a hack fest. The main concern will be to get the job done, worry about the pretty stuff later on.&lt;/p&gt; &lt;p&gt;Wish me luck.&lt;/p&gt; &lt;h2&gt;Table of Contents&lt;/h2&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-1-The-Goals.aspx"&gt;The Goals&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-2-The-Application-Window.aspx"&gt;The Application Window&lt;/a&gt;  &lt;li&gt;&lt;a href="http://www.26tp.com/post/Building-a-MVP-Framework-Part-3-The-About-Dialog.aspx"&gt;The About Dialog&lt;/a&gt; &lt;li&gt;…&lt;/li&gt;&lt;/ol&gt;</description>
      <link>http://26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=73432338-f900-4704-a213-eaf9df16871f</guid>
      <pubDate>Thu, 07 Jan 2010 21:19:36 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=73432338-f900-4704-a213-eaf9df16871f</pingback:target>
      <slash:comments>188</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=73432338-f900-4704-a213-eaf9df16871f</trackback:ping>
      <wfw:comment>http://26tp.com/post/Building-a-MVP-framework-Table-of-Contents.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=73432338-f900-4704-a213-eaf9df16871f</wfw:commentRss>
    </item>
    <item>
      <title>Example: Implementing INotifyPropertyChanged</title>
      <description>&lt;p&gt;In the previous example &lt;a href="http://www.26tp.com/post/Example-DataGridView.aspx"&gt;DataGridView&lt;/a&gt; we had a very simple Models.Contact class being displayed in a DataGridView. In this post we will look at how and why to implement INotifyPropertyChanged interface on the Models.Contact.&lt;/p&gt; &lt;h2&gt;Why&lt;/h2&gt; &lt;p&gt;It is time to be generous and give away some cars :-)&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Private Sub GiveCarButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GiveCarButton.Click

    Dim contact As Models.Contact = Me.ContactBindingSource.Current

    If contact Is Nothing Then

        MessageBox.Show("Must be on a current record to give away a car.", "Car Give Away", MessageBoxButtons.OK, MessageBoxIcon.Information)

    End If

    If MessageBox.Show(String.Format("Give a car away to '{0}'?", contact.FullName), "Car Give Away", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then

        contact.Cars += 1

    End If

End Sub

&lt;/pre&gt;
&lt;p&gt;Pretty simple but the grid/edit window that raises this event will not display the new number cars. Updating Models.Contacts to implement the INotifyPropertyChanged interface will fix this problem.&lt;/p&gt;
&lt;h2&gt;How&lt;/h2&gt;&lt;pre class="brush: vb;"&gt;Imports System.ComponentModel

Namespace Models

    Public Class Contact
        Implements INotifyPropertyChanged

        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

        ...

        Private mCars As Integer
        Public Property Cars() As Integer
            Get
                Return mCars
            End Get
            Set(ByVal value As Integer)
                If mCars &amp;lt;&amp;gt; value Then
                    mCars = value
                    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Cars"))
                End If
            End Set
        End Property

        ...

    End Class

End Namespace
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;With the above change to our property any control that is bound to Models.Contact will be aware of any changes made to the underlying data. We need to update every property and in the codes current form that would be time consuming and error prone. A future post will look at refactoring Models.Contact.&lt;/p&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;p&gt;The example can be downloaded from &lt;a href="http://26tp.codeplex.com"&gt;http://26tp.codeplex.com&lt;/a&gt;, project 26tp.Examples.ImplementINotifyPropertyChanged.&lt;/p&gt;
&lt;p&gt;This example has two forms, Grid &amp;amp; Edit. Each form has a &lt;strong&gt;Notify Property Changes&lt;/strong&gt; checkbox. Try giving a car away with the checkbox ticked and unticked to see the effect of raise the PropertyChanged event.&lt;/p&gt;</description>
      <link>http://26tp.com/post/Example-Implementing-INotifyPropertyChanged.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/Example-Implementing-INotifyPropertyChanged.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=0e9f3da2-f102-4edf-970d-55f18cd0e32f</guid>
      <pubDate>Sun, 03 Jan 2010 17:43:55 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=0e9f3da2-f102-4edf-970d-55f18cd0e32f</pingback:target>
      <slash:comments>897</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=0e9f3da2-f102-4edf-970d-55f18cd0e32f</trackback:ping>
      <wfw:comment>http://26tp.com/post/Example-Implementing-INotifyPropertyChanged.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=0e9f3da2-f102-4edf-970d-55f18cd0e32f</wfw:commentRss>
    </item>
    <item>
      <title>Example: DataGridView</title>
      <description>&lt;p&gt;This is the first in a series of &lt;a href="http://www.26tp.com/?tag=/examples"&gt;examples&lt;/a&gt; on databinding, MVC and related matters using .NET Framework, Visual Studio 2008 &amp;amp; VB.NET.&lt;/p&gt; &lt;p&gt;The purpose of this example is to show how to quickly and easily develop a form with a DataGridView, Navigation and the ability to load data. It is purposely simplistic in nature and future examples will provide best practice and real world examples.&lt;/p&gt; &lt;p&gt;Source code for all examples can be found at &lt;a href="http://26tp.codeplex.com"&gt;http://26tp.codeplex.com&lt;/a&gt;. 26tp.Examples.DataGridView is the project for this blog.&lt;/p&gt; &lt;h2&gt;Models.Contact&lt;/h2&gt; &lt;p&gt;Models.Contact is a very simple class with the following properties:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;FirstName  &lt;li&gt;LastName  &lt;li&gt;Birthday  &lt;li&gt;Cars  &lt;li&gt;Age: Read only, calculated from their birthday to today.  &lt;li&gt;FullName: Read only, FirstName + “ “ + LastName.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Excerpt of class.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Namespace Models

    Public Class Contact

        Private mFirstName As String
        Public Property FirstName() As String
            Get
                Return mFirstName
            End Get
            Set(ByVal value As String)
                mFirstName = value
            End Set
        End Property

        ...

        Public ReadOnly Property Age() As Long?
            Get

                If Not mBirthday.HasValue Then
                    Return Nothing
                End If

                Dim years = Now.Year - mBirthday.Value.Year

                If New Date(mBirthday.Value.Year, Now.Month, Now.Day) &amp;lt; mBirthday.Value Then
                    years -= 1
                End If

                Return years

            End Get
        End Property

        Public ReadOnly Property FullName() As String
            Get
                Return CStr(mFirstName + " " + mLastName).Trim
            End Get
        End Property

    End Class

End Namespace
&lt;/pre&gt;
&lt;h2&gt;Creating the DataGridView&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create a blank form. 
&lt;li&gt;Add a StatusStrip. 
&lt;li&gt;Add a Panel docked to the right. This will be used to host buttons and labels that will be created later. 
&lt;li&gt;Add Models.Contact to Data Sources via the Data –&amp;gt; Add New Data Source menu option. 
&lt;li&gt;Finally drag the Models.Contact Data Source onto the window and dock it into the Parent Container.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Hit F5 and you have a working DataGridView. FullName changes when you enter FirstName and/or LastName. Age changes when you enter a Birthday.&lt;/p&gt;
&lt;h2&gt;Load Existing Data&lt;/h2&gt;
&lt;p&gt;To load existing data the ContactBindingSource.DataSource needs to be updated.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Public Class Contacts

    Private mContacts As New BindingList(Of Models.Contact)

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)

        Me.ContactBindingSource.DataSource = mContacts

    End Sub

    Private Sub LoadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LoadButton.Click

        mContacts = New BindingList(Of Models.Contact)((New Models.ContactRepository).FindAll)
        Me.ContactBindingSource.DataSource = mContacts

    End Sub

End Class
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the above code the mContacts was introduced as the container for our fake contacts. A BindingList is used so any changes we make to mContacts will be recognised by ContactBindingSource and shown in the data grid.&lt;/p&gt;
&lt;p&gt;The ContactRepository.FindAll method simply returns a list of fake contacts.&lt;/p&gt;&lt;pre class="brush: vb;"&gt;Namespace Models

    Public Class ContactRepository

        Public Function FindAll() As List(Of Contact)

            Dim list = New List(Of Contact)

            list.Add(New Contact With {.FirstName = "Edna", .LastName = "Kimble", .Birthday = New Date(1957, 12, 24)})
            list.Add(New Contact With {.FirstName = "Maria", .LastName = "Fenimore", .Birthday = New Date(1946, 7, 7)})
            list.Add(New Contact With {.FirstName = "John", .LastName = "Bateman", .Birthday = New Date(1970, 2, 8)})
            list.Add(New Contact With {.FirstName = "James", .LastName = "Ferguson", .Birthday = New Date(1967, 7, 8)})
            list.Add(New Contact With {.FirstName = "Debra", .LastName = "Lyons", .Birthday = New Date(2010, 1, 1)})

            Return list

        End Function

    End Class

End Namespace

&lt;/pre&gt;
&lt;p&gt;The next blog in the &lt;a href="http://www.26tp.com/?tag=/examples"&gt;Examples&lt;/a&gt; series will look at implementing INotifyPropertyChanged.&lt;/p&gt;</description>
      <link>http://26tp.com/post/Example-DataGridView.aspx</link>
      <author>Tim Murphy</author>
      <comments>http://26tp.com/post/Example-DataGridView.aspx#comment</comments>
      <guid>http://26tp.com/post.aspx?id=4d5771e8-a3b5-4179-a33e-532f16d31f46</guid>
      <pubDate>Sat, 02 Jan 2010 17:40:00 +1000</pubDate>
      <dc:publisher>Tim Murphy</dc:publisher>
      <pingback:server>http://26tp.com/pingback.axd</pingback:server>
      <pingback:target>http://26tp.com/post.aspx?id=4d5771e8-a3b5-4179-a33e-532f16d31f46</pingback:target>
      <slash:comments>350</slash:comments>
      <trackback:ping>http://26tp.com/trackback.axd?id=4d5771e8-a3b5-4179-a33e-532f16d31f46</trackback:ping>
      <wfw:comment>http://26tp.com/post/Example-DataGridView.aspx#comment</wfw:comment>
      <wfw:commentRss>http://26tp.com/syndication.axd?post=4d5771e8-a3b5-4179-a33e-532f16d31f46</wfw:commentRss>
    </item>
  </channel>
</rss>