Tuesday, December 11, 2007

asp.net 2.0 and up, C#: User Control within formview (using properties (accessors) and stored procedures)

Many times, we find ourselves developing a formview, with quite a long template (item, edititem and insertitem templates). The Idea here is to include the insert and edit item templates into one user control, and then the item template into another user control. this way, we dramatically reduce the amount of code in the form, and also, get a better grip on the business logic asked for in the form.

We will start with a very simple example. To make things simple, we'll have a Clients table, with three fields. we'll use the SQLDataSource, For binding with the formview, and stored procedures.

Here's the database table :

image Note: ClientID is an identity field (with auto-increment, seed 1)

Here is the data entry user control :

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ClientsDataEntry.ascx.cs"
Inherits="Controls_ClientsDataEntry" %>

<table>
<tr>
<td>
Full Name
</td>
<td>
<asp:TextBox runat="server" ID="txtFullName" />
</td>
</tr>
<tr>
<td>
Is Valid
</td>
<td>
<asp:CheckBox runat="server" ID="chkIsValid" />
</td>
</tr>
</table>



Code Behind (notice the use of properties to access the data entry controls) :




using System;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

public partial class Controls_ClientsDataEntry : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{

}
public string FullName
{
get { return this.txtFullName.Text; }
set { this.txtFullName.Text = value; }
}
public int IsValid
{
get
{
if (this.chkIsValid.Checked)
return 1;
else
return 0;
}
set
{
if (value == 1)
this.chkIsValid.Checked = true;
else
this.chkIsValid.Checked = false;
}
}
}



Here's the formview :




<asp:FormView ID="FormView1" runat="server" DataSourceID="SqlSourceClients" DefaultMode="Insert"
DataKeyNames="ClientID" OnItemInserted="FormView1_ItemInserted" OnItemUpdated="FormView1_ItemUpdated">
<EditItemTemplate>
<table>
<tr>
<td>
<uc1:ClientsDataEntry ID="ClientsDataEntry1" runat="server" IsValid='<%# Bind("IsValid") %>'
FullName='<%# Bind("FullName") %>'></uc1:ClientsDataEntry>
</td>
</tr>
<tr>
<td colspan="2" align="right">
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update"
Text="Update" />
<asp:LinkButton ID="UpdateCancelButton" runat="server" CausesValidation="False" CommandName="Cancel"
Text="Cancel" />
</td>
</tr>
</table>
<asp:HiddenField ID="ClientIDLabel1" runat="server" Value='<%# Bind("ClientID") %>' />
</EditItemTemplate>
<InsertItemTemplate>
<table>
<tr>
<td>
<uc1:ClientsDataEntry ID="ClientsDataEntry2" runat="server" IsValid='<%# Bind("IsValid") %>'
FullName='<%# Bind("FullName") %>'></uc1:ClientsDataEntry>
</td>
</tr>
<tr>
<td colspan="2" align="right">
<asp:LinkButton ID="InsertButton" runat="server" CausesValidation="True" CommandName="Insert"
Text="Insert" />
<asp:LinkButton ID="InsertCancelButton" runat="server" CausesValidation="False" CommandName="Cancel"
Text="Cancel" />
</td>
</tr>
</table>
</InsertItemTemplate>
</asp:FormView>


notice how the user control is implemented, in both the EditItemTemplate and the InsertItemTemplate, using properties to access the textboxes. this way we don't have validation code and customizations inside our formview.




and the SqlDataSource :




<asp:SqlDataSource ID="SqlSourceClients" runat="server" ConnectionString="<%$ ConnectionStrings:ClientsConnectionString %>"
InsertCommand="spCreateClients" InsertCommandType="StoredProcedure" SelectCommand="spGetClientsByID"
SelectCommandType="StoredProcedure" UpdateCommand="spUpdateClients" UpdateCommandType="StoredProcedure">
<SelectParameters>
<asp:ControlParameter ControlID="GridView1" DefaultValue="0" Name="ClientID" PropertyName="SelectedValue"
Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="ClientID" Type="Int32" />
<asp:Parameter Name="FullName" Type="String" />
<asp:Parameter Name="IsValid" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="FullName" Type="String" />
<asp:Parameter Name="IsValid" Type="Int32" />
</InsertParameters>
</asp:SqlDataSource>



Simplicity, encapsulation, and seperation of concern, make things much easier to maintain.



here's the full code download. the database is included in the appdata folder, a simple view in browser code to the default.aspx will run the sample.

UserControl In Fromview Sample Code in C#.rar


UserControl In Formview Sample Code in C#.zip


Comments are welcome.

No comments: