Click here to Skip to main content
Click here to Skip to main content

Taming the FormView: Understanding how to Implement the FormView Control Effectively

By , 15 Nov 2009
 

The FormView Challenge

Mastering the FormView control has the benefit of leveraging one of Microsoft's most powerful controls to enhance the user experience. Yet, there is sparse information describing and illustrating how to code a well behaved interface that leverages the FormView control. I have yet to find a book that effectively explains its use. Nor have I found adequate tutorials on the many sites that I have searched.

I sympathize with users expressing frustration at many International firms where I have worked. They are using enterprise applications and attempting to modify records that rely solely upon the GridView control. Often, the user must edit records that contain over fifty columns. That means that they must first locate the record, use the slider to find the correct column, edit the field, and pan back to the left side of the GridView to update or insert a new record. Alternatively, the users are required to use the master/detail pattern for the record updates. That pattern can become quite confusing quickly. When the FormView is used in combination with the MultiView control, the user has a much friendlier experience. Better yet, the developer will use AJAX to enhance the smoothness of the application, but that is beyond the scope of this article.

This article focuses on exposing the tips-n-tricks that must be understood by the developer to work with the form view control. The idea here is to guide the developer in a direction such that the pit falls and quirks of the control are avoided, and to provide a basic example of a reliable design pattern that can be leveraged in future projects.

Business Problem

Management has observed that the users are operating at half their expected productivity because they are editing and inserting records composed of over fifty columns in a grid view. The users have difficulty navigating the page to find the correct column, make the update, and then they must return back to the beginning of the row to search for another record. The solution is to click an edit button on the left hand column, have the focus to the first field in a FormView, edit the record, and submit the change. The addition of a new record will follow a similar process.

Finally, it is assumed that a search function is already present that users can utilize to navigate to the next record. So, that will be omitted in this project because it is not required. Only two columns will be displayed in the example to limit the amount of source code necessary to demonstrate the design pattern.

Illustrating the Use Case

The user opens an application to view the club listings, and clicks on the Edit button to modify a record.

Initial view

In response to the edit request, the system displays the FormView in Edit mode with the record populated. Note that the grid view record is not in Edit mode. Also, there is no need to navigate away from the page and deal with the complexities introduced by cross page posting patterns.

Initial view

The user submits the change, and the system closes the form. It then lists the records with the updates.

Initial view

Next, the user must add a record. The user clicks the Add-record link and the system responds by opening the form in Insert mode. The user fills out the club information and clicks the Submit link.

Initial view

When the record is submitted, the system responds by closing the form and adding the record to the list of clubs. Optionally, the system could keep the form open for heads down data entry. I chose to close the form to illustrate how to manage the control in the switch structure for the developer's reference. Additional details will follow below.

Initial view

Tips and Tricks

  • When designing the form, use templates. The "ItemTemplate", regardless of whether it is used in read only mode, will cause the VS2008 designer to show the format of the form. I suggest using the same format in the edit, update, and insert item templates.
  • Put a switch statement in the "ItemCommand" handler. I suggest generally ignoring all of the other form view event handlers because they tend to introduce quirks into the system design. It is better to use a simple control structure than to attempt intercepting the other events. I have found that using the form view control's other events only introduces complexity in the design and irritating quirks.
  • Always use a link or image button to put the form view control into the Add-record mode. This handles the case where no record will be displayed when there is an empty record. Otherwise, there will be challenges encountered when starting with an empty form view. An empty form view is not displayed, and the control is not instantiated when there is no record. That means the links will not be present.
  • The FormView control expects an object that is a collection or enumeration. Thus, using the following technique will not work:
  • FormView1.ChangeMode(FormViewMode.Edit);
    TextBox tb = (TextBox) FormView1.FindControl("ClubName");
    tb.Text = "Club Name";

    Instead, put the form into Edit mode and bind a collection like an array list or data table to the data source. Then call the DataBind method as follows:

    FormView1.ChangeMode(FormViewMode.Edit);
    FormView1.DataSource = al;
    FormView1.DataBind();

Key Design Concepts

Managing the FormView is done by handing the ItemCommand event. A switch structure is used to control the mode of the FormView control within the ItemCommand handler. The FormView control has three modes that include insert, edit, and read only. The FormView's ChangeMode() method is used to switch the mode of the control.

The class Club is used to contain records that are updated and new records that are inserted into the table.

Club
Instance Variables
ClubID An integer used to hold the unique club's identification.
ClubName The name of the club.
URL The URL of the organization.

The class ClubList is a helper class that substitutes for a database table in this example. It is straightforward, and the key items are listed in the following table:

ClubList
Instance Variables
ClubList cl The class uses the singleton design pattern.
DataTable _dt A data table is used to contain the club records.
Methods
BuildClubList() Builds and populates a default club list for binding to the grid view when the application starts.
AddClub(Club c) Adds a club to the data table. The Club object is used to add a new record.
UpdateClubByID(Club c) Accepts the Club object and updates the record in the data table.

Create the ClubList class that builds a table for creating default data, adding, and updating club records. The records go into a data table. The class uses the singleton design pattern.

Default Form (ASP.NET)
Event Handlers
Page_Load When the page loads for the first time, get the club list and bind it to the grid view.
FormView1_ItemCommand Whenever a form view ItemCommand event occurs, the switch structure uses e.CommandName to determine what event took place. The FormView is changed into the appropriate mode and the databind() function is called so that the update will take place.
AddNewClub_Click Click on the Add New Club link to handle the event to switch the form into Insert mode.
gvClubList_RowEditing Handles the edit click event message from the grid view. Here, the club record is retrieved from the data table and displayed in the FormView control. The edit event for the grid view is cancelled to prevent the control from entering the edit record mode.
Methods
UpdateClub() Update a club record in the data table.
AddClub() Add a new club to the data table.

Coding the Application

Step 1. Create the Club class as follows:

/// <summary>
/// Jeff Kent - 11/15/2009
/// Table class of type club that helps
/// with customer record insertion and updates.
/// </summary>
public class Club
{
  public Club()
  {
  }

  private int _ClubID;
  public int ClubID{
    get { return _ClubID; }
    set { _ClubID = value; }
  }

  private string _ClubName;
  public string ClubName
  {
    get { return _ClubName; }
    set { _ClubName = value; }
  }


  private string _URL;
  public string URL
  {
    get { return _URL; }
    set { _URL = value; }
  }
}

Step 2. Create the ClubList class that builds a table for creating default data, adding, and updating club records. The records go into a data table. The class uses the singleton design pattern.

// <summary>
/// Jeff Kent - 11/14/2009
/// Helper that is used to populate the gridview, 
/// add a new club, and expose the data table for binding.
/// This is intended only for use in demonstrating this application, and 
/// it is not suitable for production use.
/// 
/// 
/// UTILIZE THE SINGLETON DESIGN PATTERN.
/// </summary>
public sealed class ClubList
{
  private static readonly ClubList cl = new ClubList();
  private static DataTable _dt;
  private ClubList() { }

  //PROPERTY THAT EXPOSES THE DATA TABLE FOR BINDING.
  static public DataTable dt
  {
    get { return _dt; }
    set { _dt = value; }
  }

  // CREATE A CLUB LIST AND RETURN THE DATA TABLE.
  static public DataTable BuildClubList()
  {
    DataColumn col;
    DataColumn col2;
    DataColumn col3;
    DataRow row;

    if (!(dt == null))
    {
      return dt;
    }
    dt = new DataTable("ClubList");
    // Create new Datacol, set DataType, 
    // colName and add to DataTable.
    col = new DataColumn();
    col.DataType = Type.GetType("System.Int32");
    col.ColumnName = "ClubID";
    col.AutoIncrement = true;
    col.AutoIncrementSeed = 1000;
    col.AutoIncrementStep = 10;
    col.ReadOnly = true;
    col.Unique = true;
    dt.Columns.Add(col);

    // Make the ID column the primary key column.
    DataColumn[] PrimaryKeyColumns = new DataColumn[1];
    PrimaryKeyColumns[0] = dt.Columns["ClubID"];
    dt.PrimaryKey = PrimaryKeyColumns;

    col2 = new DataColumn();
    col2.DataType = Type.GetType("System.String");
    col2.ColumnName = "ClubName";
    col2.AutoIncrement = false;
    col2.Caption = "Club Name";
    col2.ReadOnly = false;
    col2.Unique = false;
    dt.Columns.Add(col2);

    col3 = new DataColumn();
    col3.DataType = Type.GetType("System.String");
    col3.ColumnName = "URL";
    col3.AutoIncrement = false;
    col3.Caption = "URL";
    col3.ReadOnly = false;
    col3.Unique = false;
    dt.Columns.Add(col3);

    row = dt.NewRow();
    row["ClubName"] = "Joe's Rocketry";
    row["URL"] = "www.joes.com";
    dt.Rows.Add(row);

    row = dt.NewRow();
    row["ClubName"] = "American Rocketry";
    row["URL"] = "www.ar.com";
    dt.Rows.Add(row);

    row = dt.NewRow();
    row["ClubName"] = "NSSR Rockets";
    row["URL"] = "www.nssr.com";
    dt.Rows.Add(row);

    return dt;
  }

  //ADD A CLUB TO THE DATA TABLE.
  public static DataTable AddClub(Club c)
  {
    DataRow row;

    row = dt.NewRow();
    //row["ClubID"] = c.ClubID;
    row["ClubName"] = c.ClubName;
    row["URL"] = c.URL;
    dt.Rows.Add(row);

    row = dt.NewRow();

    return dt;
  }

  //GET THE CLUB BY THE ID.
  public static Club GetClubByID(int ClubID)
  {
    Club c = new Club();
    DataRow row = dt.Rows.Find(ClubID);

    c.ClubID = (int)row["ClubID"];
    c.ClubName = row["ClubName"].ToString();
    c.URL = row["URL"].ToString();

    return c;
  }

  //UPDATE THE CLUB RECORD BY ID.
  public static void UpdateClubByID(Club c)
  {
    DataRow row = dt.Rows.Find(c.ClubID);
    row.BeginEdit();
    row["ClubName"] = c.ClubName;
    row["URL"] = c.URL;
    dt.AcceptChanges();
  }
}

Step 3. Create your standard default page. Add the form and grid view controls. I like to organize the page using divisions, selectors from a cascading style sheet, and tables. The style sheet is included in the coding sample. The sample also includes the images used in this article.

<div id="wrapper">
    <form id="form1" runat="server">
    <div id="header">
      <asp:Image ID="Image1" runat="server" 
             ImageUrl="~/images/ClubAdmin.jpg" />
    </div>
    <div id="maincontent">
      <asp:FormView ID="FormView1" 
           runat="server" DataKeyNames="ClubID" 
           OnItemCommand="FormView1_ItemCommand"
           BorderStyle="Outset" 
           BorderWidth="2px" CssClass="FormView">
        <ItemTemplate>
          <table>
            <tr>
              <td class="FormViewHeader">
                Club Name:
              </td>
              <td>
                <asp:Label ID="ClubName" runat="server" 
                     Text='<%# Bind("ClubName") %>'></asp:Label>
              </td>
            </tr>
            <tr>
              <td class="FormViewHeader">
                URL:
              </td>
              <td>
                <asp:Label 
                    ID="URL" runat="server" 
                    Text='<%# Bind("URL") %>'></asp:Label>
              </td>
            </tr>
          </table>
          <asp:LinkButton ID="LinkButton1"
                   runat="server" CommandName="EditInfo" 
                   Text="Edit">Edit</asp:LinkButton>
          <asp:LinkButton ID="LinkButton10" runat="server" 
                          CommandName="InsertInfo" 
                          Text="New">Insert</asp:LinkButton>
        </ItemTemplate>
        <PagerSettings Mode="NextPreviousFirstLast" />
        <EditItemTemplate>
          <table>
            <tr>
              <td class="FormViewHeader">
                Club Name:
              </td>
              <td>
                <asp:TextBox 
                  ID="ClubName" runat="server" 
                  Text='<%# Bind("ClubName") %>'></asp:TextBox>
              </td>
            </tr>
            <tr>
              <td class="FormViewHeader">
                URL:
              </td>
              <td>
                <asp:TextBox ID="URL" 
                       runat="server" 
                       Text='<%# Bind("URL") %>'></asp:TextBox>
              </td>
            </tr>
          </table>
          <asp:LinkButton ID="LinkButton2"
            runat="server" CommandName="UpdateInfo" 
            Text="UpdateInfo">Update</asp:LinkButton>
          <asp:LinkButton ID="LinkButton3"
            runat="server" CommandName="CancelUpdate" 
            Text="CancelInfo">Cancel</asp:LinkButton>
        </EditItemTemplate>
        <InsertItemTemplate>
          <table>
            <tr>
              <td class="FormViewHeader">
                Club Name:
              </td>
              <td>
                <asp:TextBox ID="ClubName" runat="server" 
                     Text='<%# Bind("ClubName") %>'></asp:TextBox>
              </td>
            </tr>
            <tr>
              <td class="FormViewHeader">
                URL:
              </td>
              <td>
                <asp:TextBox ID="URL" runat="server" 
                       Text='<%# Bind("URL") %>'></asp:TextBox>
              </td>
            </tr>
          </table>
          <asp:LinkButton ID="LinkButton20" runat="server" 
                CommandName="SubmitInfo" 
                Text="SubmitInfo">Commit</asp:LinkButton>
          <asp:LinkButton ID="LinkButton30"
                   runat="server"
                   CommandName="CancelInsert" 
                   Text="CanceInsert">Cancel</asp:LinkButton>
        </InsertItemTemplate>
      </asp:FormView>
      <br />
      <br />
      <hr />
      <asp:LinkButton ID="AddNewClub" runat="server" 
                     OnClick="AddNewClub_Click" 
                     CssClass="LinkButton">
                     Add New Club</asp:LinkButton>
      <asp:GridView ID="gvClubList"
            runat="server" AutoGenerateColumns="False" 
            DataKeyNames="ClubID"
            OnRowEditing="gvClubList_RowEditing" 
            AlternatingRowStyle-CssClass="AlternatingRowStyle">
        <Columns>
          <asp:CommandField ShowEditButton="True" />
          <asp:TemplateField InsertVisible="False">
            <HeaderTemplate>
              <table width="400px">
                <thead>
                  <td class="TableHeader" style="width: 40%">
                    Club Name
                  </td>
                  <td class="TableHeader">
                    URL
                  </td>
                </thead>
              </table>
            </HeaderTemplate>
            <AlternatingItemTemplate>
              <table width="400px">
                <tr>
                  <td style="width: 40%">
                    <asp:Label 
                         ID="ClubName" runat="server" 
                         Text='<%# Bind("ClubName") %>'></asp:Label>
                  </td>
                  <td>
                    <asp:Label ID="URL" 
                       runat="server" Text='<%# Bind("URL") %>'></asp:Label>
                  </td>
                </tr>
              </table>
            </AlternatingItemTemplate>
            <ItemTemplate>
              <table width="400px">
                <tr>
                  <td style="width: 40%">
                    <asp:Label ID="ClubName" runat="server" 
                           Text='<%# Bind("ClubName") %>'></asp:Label>
                  </td>
                  <td>
                    <asp:Label ID="URL" runat="server" 
                         Text='<%# Bind("URL") %>'></asp:Label>
                  </td>
                </tr>
              </table>
            </ItemTemplate>
          </asp:TemplateField>
        </Columns>
      </asp:GridView>
      <br />
    </div>
    </form>
  </div>

Step 4. Add the logic to the code-behind for the default page. As mentioned, the key handlers are the FormView control's ItemCommand and the GridView's RowUpdating command. Take special note of how the edit is cancelled for the GridView, and the FormView is set into Edit mode and populated with the record. The LinkButton control's Click event is used to put the form into Insert mode when the user chooses to add a new club to the list.

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
      if (!Page.IsPostBack)
      {
        gvClubList.DataSource = ClubList.BuildClubList();
        gvClubList.DataBind();
        FormView1.ChangeMode(FormViewMode.ReadOnly);
      }
    }
    //MANAGE THE FORM VIEW CONTROL'S STATE IN RESPONSE TO CLICK EVENTS 
    //RELATED TO SUBMISSION, UPDATE, AND CANCEL REQUESTS.

    protected void FormView1_ItemCommand(object sender, FormViewCommandEventArgs e)
    {
      switch (e.CommandName)
      {
        //case "EditInfo":
        //  FormView1.ChangeMode(FormViewMode.Edit);
        //  break;
        case "UpdateInfo":
          UpdateClub();
          FormView1.ChangeMode(FormViewMode.ReadOnly);
          gvClubList.DataSource = ClubList.dt;
          gvClubList.DataBind();
          break;
        case "SubmitInfo":
          AddClub();
          FormView1.ChangeMode(FormViewMode.ReadOnly);
          gvClubList.DataSource = ClubList.dt;
          gvClubList.DataBind();
          break;
        case "CancelUpdate":
          FormView1.ChangeMode(FormViewMode.ReadOnly);
          break;
        case "CancelInsert":
          FormView1.ChangeMode(FormViewMode.ReadOnly);
          break;
        default:
          break;
      }
      // FOR THE MODE TO CHANGE CALL DATA BIND.
      FormView1.DataBind();
    }

    //Update an existing club.
    protected void UpdateClub()
    {
      TextBox tb;
      Club c = new Club();

      c.ClubID = Int32.Parse(FormView1.DataKey.Value.ToString());
      tb = (TextBox)FormView1.FindControl("ClubName");
      c.ClubName = tb.Text;
      tb = (TextBox)FormView1.FindControl("URL");
      c.URL = tb.Text;
     
      ClubList.UpdateClubByID(c);
    }

    //Add and new club to the table.
    protected void AddClub()
    {
      TextBox tb;
      Club c = new Club();

      //c.ClubID = Int32.Parse(FormView1.DataKey.Value.ToString());
      tb = (TextBox)FormView1.FindControl("ClubName");
      c.ClubName = tb.Text;
      tb = (TextBox)FormView1.FindControl("URL");
      c.URL = tb.Text;

      if (c.ClubName != String.Empty)
      {
        ClubList.AddClub(c);
      }
    }

    //PUT THE FORM VIEW INTO THE INSERT MODE IN RESPONSE TO 
    //A CLICK EVENT FROM A LINK OR IMAGE BUTTON.
    protected void AddNewClub_Click(object sender, EventArgs e)
    {
      //PUT THE FORM VIEW INTO INSERT MODE.
      FormView1.ChangeMode(FormViewMode.Insert);
    }

    protected void gvClubList_RowEditing(object sender, GridViewEditEventArgs e)
    {
      int ClubID;
      string ClubName;
      string URL;
      Label lb;
      Club c;
      ArrayList al = new ArrayList();

      ClubID = Int32.Parse(gvClubList.DataKeys[e.NewEditIndex].Value.ToString());
      lb = (Label)gvClubList.Rows[e.NewEditIndex].FindControl("ClubName");
      ClubName = lb.Text;
      lb = (Label)gvClubList.Rows[e.NewEditIndex].FindControl("URL");
      URL = lb.Text;

      //CANCEL PUTTING THE GRID VIEW INTO EDIT MODE.
      e.Cancel = true;

      //GET THE FORM CONTROLS AND BIND THE DATA.
      //THE CLUB IS PUT INTO AN ARRAY LIST BECAUSE THE FORM VIEW.
      c = ClubList.GetClubByID(ClubID);
      al.Add(c);
      FormView1.ChangeMode(FormViewMode.Edit);
      FormView1.DataSource = al;
      FormView1.DataBind();

    }
}

Conclusion

The FormView control has proven to be one of the most powerful and useful controls for performing inserts, deletes, and updates related to managing records. It is a challenge to find good information that explains how to avoid the quirks present in this control. Once understood, it is a simple control to implement in any application. I use it often. Clearly, the user experience and efficiency is enhanced when the developer is able to effectively implement the control. I encourage developers to learn and leverage the pattern illustrated in this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jeffrey Kent
Software Developer (Senior) Firestorm Igniters
United States United States
Member
Professional Summary:
 
Jeff has fourteen years of extensive experience in research and development of leading edge technology in both software and hardware based systems. His background includes architecting, designing, developing, and implementing enterprise business systems.
 
Experience includes development of web systems for user permissions (security) management, order entry, franchise information management, content management systems (CMS), e-commerce, inventory, warehousing, job tracking, reporting applications, artwork submission, automation of active directory security, and mobile device applications (smartclients).
 
Scope of experience includes architecting of enterprise systems, database design, database replication, web services, custom controls development, mobile applications, multithreaded modeling and development, risk mitigation and disaster recovery, and systems implementation.
 
Finally, Jeff has the proven ability to integrate leading edge technology with legacy systems to provide a modern framework, or develop an independent system using modern technologies based on Microsoft and IBM related frameworks.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhere is the data being storedmemberhoule3 Apr '13 - 9:35 
Hi Jeffrey,
 
Great article. Could you tell me where the data is stored/cached? I add/edit records and the data persists for each instance of running the application.
QuestionVBmemberMember 972684616 Jan '13 - 9:17 
Does anyone know if there is a VB.net version of this?
Questionform viewmembersteve714 Jan '13 - 9:33 
why does the system close the formview afte a cancel or update ?
isnt the data still in the formview when you swith modes ?
GeneralMy vote of 5membersteve714 Jan '13 - 9:23 
well written and thought out
QuestionExcellent job.memberasp_crazy_guy6 Sep '12 - 20:23 
Firstly, I like to congratulate you on writing such an informative article. The problem description you mentioned really helped me understanding where to apply the form view.
 
1) You could have used a single custom control for both edit/insert & populate it from data layer (Some mix of javascript/panel controls etc)? I see the controls duplicating for insert & edit mode (This might be problematic with 50 fields as you would have 50 controls for edit & 50 for insert mode)
GeneralF5 duplicates the last committed recordmemberGuennadi Vanine28 Nov '09 - 0:16 
I am just poking superficiously into this application.
 
What I immediately noticed is that refreshing the page (e.g. by pressing F5) multiplies (duplicates, adds) the record of the last Commit
(pressing on link Commit after entering data)
 
This is quite obvious to press F5 (or Ctrl+F5) to make sure that the data comes from server but not just cached or jshown by browser.
But each such desire ends up in adding one more already existing row.
 
I'd like to know how to better fix such behavior?
GeneralWhy is this article marked with .NET 4.0? [modified]memberGuennadi Vanine27 Nov '09 - 1:01 
Hello,Jeffrey,
and thanks a lot!
Accept my 5!
 
This topic seems trivial only on the surface by those who did not engage practically the FormView.
But,according to the amount of ratings and comments th this article,
the FormView is simply in oblivion!
 
This is very useful topic, I was looking for quite a time!
And, during my searches I skipped this article
because it is marked by .NET 4.0
thinking that it is illustrations of some new ASP.NET 4.0 features.
 
What has this article to do with .NET 4.0?
 
It is misleading.
99% of coders are solving current practical needs and problems.
Hardly .NET4.0, as BETA framework, is in any considerable use in "production".
 
I am afraid you are loosing 99% of interested in this topic
readers/developers by having marked it with .NET4.0!
 
Your code perfectly works under ASP.NET2.0 and from Visual Studio 2005!
 

All the best,
Gennady Vanin ---- Guennadi Vanine --- Геннадий Ванин
GeneralRe: Why is this article marked with .NET 4.0?; Leverage Code to Reduct Business Costs.memberJeffrey Kent27 Nov '09 - 14:45 
Historically, when a developer wanted to migrate from an older version of software (i.e. VB6 to .NET 1.1 OR .NET 1.1 to .NET 2.0) the developer was required to essentially rewrite the software or port it to the new technology.
 
In other scenarios, where Java, ABAP, or some esoteric 4GL languages were used, the complete rewrites of the code were not required. Those technologies use more of a dynamically scalable architecture. That means that the developer is able to leverage existing code. In addition, when new manuals are written they include both the legacy development techniques and the new features.
 
Microsoft has clearly moved in the direction of following and leveraging this design philosophy with the .NET architecture. Thus the complete rewrites of code are no longer necessary. Also, I am finding that authors have picked up on this trend and that they leverage their existing material while illustrating how to embrace the new features of the language.
 
As a developer, I can easily leverage legacy code written in .NET 2.0 and port the applications to .NET 3.5 and .NET 4.0. I currently ignore .NET 2.0 and work exclusively on .NET 3.5. Developers who fail to transition are, sadly, being left behind. Indeed, I still know of classic asp/VB 6.0 developers who, out of shear stubbornness, are failing to make the transition. As new hardware comes out they will find that their applications will no longer support their business models.
 
For example at one International organization where I worked, the business managers insisted upon using legacy systems written legacy code. Due to their size, their serial numbers require at minimum 32 bit technology and ideally 64 bit hardware. But their code can only manage 16 bit serial numbers. Their business model requirements obsolete the technology they have in place. The applications are writing in non-scalable languages like classic asp and VB6.0. They cannot easily port their applications or leverage their existing investment in code. Further, the politics of getting the legacy developers to migrate to the new technology is impossible due to outright hostility. They will never make the transition due to the costs that are will over a million dollars. Nor do the developers have the skill to make such a transition. That organization is in a high risk scenario that can lead to failure due to the current economy and they are bleeding red ink all over the place while trying to adapt their systems using legacy technology.
 
When .NET 4.0 comes out I will again migrate to .NET 4.0 and leave .NET 3.5 behind. Historically, the new .NET release would require me to trash all of the old code. That is no longer the case with Microsoft, albeit there are some limitations that I may still encounter because Microsoft does make some syntax obsolete unlike other major software vendors.
 
For example, I have been examining Silverlight and found that I can easily port my applications to that technology with minimal effort. I have also tested the MVC framework and found that my applications will support that technology without a major rewrite. To do this, I follow a set of design rules that are a topic for another discussion. The key here is to avoid excessive use of their party tools that lock a developer into a specific .NET technology. That is because many third party tools are not well supported and cannot migrate due to poor architectural design practices. They lock the system into a legacy design that cannot be ported to a new framework.
 
One of the biggest challenges that I encounter today is getting Junior Software Developers to understand that you don't have to throw out proven code when the new .NET release becomes available. However, there are rules that must be followed to leverage this practice. Most developers fail to practice the rules. The core idea of OOA/OOD/OOP technology is that it is scalable. The developer is supposed to leverage what is in place and add new features as called for by the innovations afforded by technological advances.
 
From a business perspective, business managers who embrace the practice of leveraging proven code will see a reduction in costs. Reducing costs equals more profit for the organization and higher pay for software developers. Managers tend to strongly dislike disposing of old code in favor of new bells and whistles when the application is affectively solving a business problem. Their first question always involves asking of there a new business problem that needs to be resolved? If the answer is no then the business manager typically chooses to maintain the legacy application.
 
To further illustrate, SAP has the largest business application software installation in the world today. SAP routinely leverages existing ABAP code in their dynamically scalable architecture while adding on new features that improves the user experience. They never remove legacy syntax. It is always supported. New code and applications are built around the legacy work. It is a proven design philosophy that allows their systems to scale. They use dynamically scalable architecture (DSA).
 
Microsoft is still new to the arena in using the DSA design philosophy. They are wise to embrace this philosophy, and it will help to increase their market penetration of business applications. Historically, it was impossible to leverage existing applications written using Microsoft’s technology. It will take years to overcome the historical legacy of writing throw away code. A side affect is that many Microsoft developers today are unaware of how to embrace such software design practices, and they are still learning to embrace the value of developing dynamically scalable systems.
Using dynamically scalable designs, I have been migrated my applications every one to two years to the new frameworks. There are minimal bugs, no major disruptions of business, and the development activities always continued without disruption. The ability to do such migrations with Microsoft technology is still new. By contrast, I have successfully used IBM and SAP technology to perform such migrations for years, and they do not suffer from the reputation of writing throw away code. The releases, from a business perspective, are seen as basic maintenance costs to the organizations. Better yet, the old school developers were able to using their existing skills to expand on the systems while developing new skills that leverage the new features.
 
With this in mind, I have included this article in .NET 4.0. I agree that perhaps I should also mark the article with .NET 2.0. However, for whatever reason, I am unable to edit the article at this time. I will make the change when I figure out why or how to edit this article. On the other hand, it occurs to me that perhaps there is value in leaving the .NET 2.0 audiences behind….I will give it more thought. It seems that there may be value in getting people to look for this stuff in the .NET 3.5/ 4.0 section of the site.
 
Later!
 
Jeff
GeneralRe: Why is this article marked with .NET 4.0?; Leverage Code to Reduct Business Costs. [modified]memberGuennadi Vanine27 Nov '09 - 20:20 
Jeffrey,
.NET 3.x seems to be no more than just pure .NET 2.0 augmented by some additional frameworks, components and libraries while 4.0 is using some 2.0, 3.x components.
So, if someone mentions 3.0 (or 3.5) then this immediately means to me the engagement of some specific technologies which this article simply does not touch.
 
If your code can run in 2.0, there is no sense to mention following versions, this is obvious and by design.
YOU SHOULD NOT MARK this ARTICLE by 3.x, 4.0 AT ALL.You miss and repel your audience!
 
Vice versa is not valid.
People interested in ASP.NET 2.0 core features (I believe 98% of audience for this article) just skip your article fast upon seeeing in the right top coner C# 3.0, 3.5, 4.0
 
Also, have you checked the version of ASP.NET that runs your web application even if you target it to 4.0?
My computer shows that it is run by ASP.NET 2.0.50727.3082
 
And the versions 3.x of ASP.NET runtime engine simply does not exist
(it is still 2.0).
There are either ASP.NET 2.x or 4.x ASP.NET runtime,
i.e. ASP.NET 3.x uses 2юч runtime.
 
modified on Saturday, November 28, 2009 7:08 AM

GeneralThoughts...memberMR_SAM_PIPER23 Nov '09 - 14:01 
I agree, I think FormView is a better option than GridView for adding or editing objects, but I find it encourages violation of DRY (Don't Repeat Yourself) principles by making the developer duplicate UI structure across the different templates, which is illustrated in your tutorial - you have copied the same basic template 3 times across ItemTemplate, EditItemTemplate and InsertItemTemplate.
 
This is OK for a tutorial but it quickly becomes a PITA when you work with large, complex objects because you have to repeat the maintenance work for each template - forgetting to make the same logical change 3 times will usually show up as a runtime error later on, which is a class of error you want to prevent as much as possible. The workaround I've used is to factor the template UI into a single user control which can then be maintained independently from its usage in FormView controls.
 
You do need a control interface that allows the FormView to communicate with the template control (ie, set the 'mode', handle events, etc), but this only needs to be defined once then implemented as needed by template controls, and it is less effort-intensive and error-prone than maintaining multiple "inline" templates.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 16 Nov 2009
Article Copyright 2009 by Jeffrey Kent
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid