Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Microsoft ASP .NET Professional Projects - Premier Press

.pdf
Скачиваний:
147
Добавлен:
24.05.2014
Размер:
4.63 Mб
Скачать

}

Convert Columns to Template Columns

Though the DataGrid is workable at this stage, it is better to convert the columns into Template columns. The most important advantage of doing this is that we can associate IDs with the EditItemTemplates that we can use to access the column values in the update mode. In the Grid1_Update method, we are required to extract the column values in order to build an update SQL query. In the absence of the IDs, we have to refer to the control using its index value as shown below:

TextBox t;

t = (TextBox)e.Item.Cells[2].Controls[0];

String code_display = " code_display = '" + t.Text.Trim() + "'," ;

For some reason, this does not always work as expected whereas using the ID of the control works reliably. As will be explained later, we can use the FindControl method of a control to locate a control of a specified ID within the DataGrid. This can be cast to a TextBox and its Text property extracted as shown below:

t = (TextBox) e.Item.FindControl("editCode_Display");

String code_display = " code_display = '" + t.Text.Trim() + "'," ;

To convert these columns to Template columns go back to the Property Builder and select Columns. Select code_display, rate, uom, and opening columns (each one separately) in the Selected Columns list box and click on the hyperlink that appears at the bottom which says Convert this column into a Template Column. Now, go to the HTML view and give unique IDs to the EditItemTemplates. As soon as you start typing, you will note that Visual Studio.NET will try to auto-complete the selection for you.

You will note that each Template column has an ItemTemplate and an associated EditItemTemplate. This EditItemTemplate can be any type of ASP.NET control (for example, a TextBox or a DropDownList control), whereas the ItemTemplate is a Label control. The ItemTemplate is the control that displays initially in the DataGrid. When you click on the Edit hyperlink in the DataGrid, the EditItemTemplate displays. As this is an editable control like a TextBox, you can edit the displayed values.

Add the following IDs under the EditItemTemplate tag:

§The code_display column, the id will be editCode_display.

§The rate column, the id will be editRate.

§The uom column, the id will be editUom.

§The opening column, the id will be editOpening.

The <Columns> element tags should look like this in the HTML view:

<Columns>

<asp:EditCommandColumn ButtonType="LinkButton"

UpdateText="Update"

CancelText="Cancel"

EditText="Edit">

</asp:EditCommandColumn>

<asp:BoundColumn DataField="code_value"

SortExpression="code_value" ReadOnly="True"

HeaderText="code_value">

</asp:BoundColumn>

<asp:TemplateColumn HeaderText="code_display">

<ItemTemplate>

<asp:Label runat="server" Text='<%# DataBinder.Eval (Container, "DataItem.code_display") %>'></asp:Label>

</ItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="editCode_Display" runat="server"

Text='<%# DataBinder.Eval(Container, "DataItem.code_display") %>'></asp:TextBox>

</EditItemTemplate>

</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="rate"> <ItemTemplate>

<asp:Label runat="server" Text='<%# DataBinder.Eval (Container, "DataItem.rate") %>'></asp:Label>

</ItemTemplate>

<EditItemTemplate>

<asp:TextBox id="editRate" runat="server"

Text='<%# DataBinder.Eval(Container, "DataItem.rate") %>'></asp:TextBox> </EditItemTemplate>

</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="uom"> <ItemTemplate>

<asp:Label runat="server" Text='<%# DataBinder.Eval (Container, "DataItem.uom") %>'></asp:Label>

</ItemTemplate>

<EditItemTemplate>

<asp:TextBox id="editUom" runat="server"

Text='<%# DataBinder.Eval(Container, "DataItem.uom") %>'></asp:TextBox> </EditItemTemplate>

</asp:TemplateColumn>

<asp:BoundColumn DataField="closing" ReadOnly="True" HeaderText="closing">

</asp:BoundColumn>

<asp:TemplateColumn HeaderText="opening"> <ItemTemplate>

<asp:Label runat="server" Text='<%# DataBinder.Eval (Container, "DataItem.opening") %>'></asp:Label>

</ItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="editOpening" runat="server"

Text='<%# DataBinder.Eval(Container, "DataItem.opening") %>'>

</asp:TextBox>

</EditItemTemplate>

</asp:TemplateColumn>

</Columns>

If you run the web form at this time, you will note that each column appears twice in the DataGrid. This is because the DataGrid is auto-generating columns, in addition to the Template columns we have created. You can do this either by setting the AutoGenerateColumns property of the DataGrid to False or by unchecking the

Create columns automatically at run time check box in the Property Builder as shown in Figure 30.8.

Figure 30.8: Setting the AutoGenerateColumn attribute to False.

If you look at the generated HTML in the HTML view, you will note that the attribute AutoGenerateColumns="False" has been inserted within the DataGrid element tag as follows:

<asp:datagrid id="DataGrid1"

------------------------

------------------------

AutoGenerateColumns="False">

The Add Panel

The functionality to insert new rows to the stock_master table is provided by a number of TextBox controls and Label controls residing on a Panel control. The reason why we have these controls on a Panel control is that we can show or hide all the TextBox controls and Label controls just by setting the Visible property of the Panel to True or

False.

Drag and drop a Panel control from the ToolBox onto the web form. Right-click on the Panel control and select Properties. Give it an ID of AddPanel and set the Visible property to False.

Now, drag and drop four Label controls and four TextBox controls on the Panel. These should line up one under the other. To line them within the Panel, drag and drop the first TextBox and Label. Then right-click and copy the label and paste it one line below. Stretch the second label with your mouse until it lines up with the Label on the top. Now copy and paste the TextBox so that it sits next to the label on the second line. Repeat this process for all the Label and TextBox controls you need on the Panel. You need to

follow this process in order to line up the components. The TextBox controls will be of similar size, however the Label sizes can vary, depending on the caption you want to display, hence you need to stretch the Label controls so that they line up under each other. You can use your mouse or CRTL -arrows to move the controls and SHIFT-arrows to size them.

Give the four TextBox controls IDs of AddCode_Display, AddRate, AddUom, and AddOpening respectively. You can do this by right clicking on each of them and selecting Properties and then ID.

Add a Button Control onto the Panel. Give it the ID of SaveNew. Double-click on it to create a method skeleton, which will look like this:

private void SaveNew_Click(object sender, System.EventArgs e)

{

}

We will code this method later. I have also added a blank label before the Button Control in order to position it in the center of the form.

Specifying the DataGrid Command Methods

Specify the OnEditCommand, OnCancelCommand, OnUpdateCommand, and the

OnDeleteCommand within the DataGrid element tag. These attributes of the DataGrid specify the method that will fire when the user clicks on the Edit, Cancel, Update, or Delete hyperlinks in the DataGrid. You will have to open the form in HTML view and manually add these attributes within the DataGrid element tag as follows:

<asp:datagrid id="DataGrid1"

------------------------

-------------------------

OnEditCommand="Grid1_Edit"

OnCancelCommand="Grid1_Cancel"

OnUpdateCommand="Grid1_Update"

OnDeleteCommand="Grid1_Delete" >

Methods

In this step, you will code some methods for the web form. Open the Code Behind file (StockMaster.aspx.cs) and add the following methods.

The Bind() method will populate the DataSet using the Fill method of the DataAdapter. It will also bind the DataGrid to the DataSet as follows:

The Bind Method

public void Bind()

{

sqlDataAdapter1.Fill(dsStock1);

DataGrid1.DataSource=dsStock1;

DataGrid1.DataBind();

if (AddPanel.Visible==true)

{AddPanel.Visible=false;}

}

The Bind method is called in the Page_Load event as follows:

private void Page_Load(object sender, System.EventArgs e)

{

if (! IsPostBack)

{

Bind();

}

}

If you build and run the web form (by pressing CTRL-F5), you will see the form displayed in the browser as shown in Figure 30.9.

Figure 30.9: The Stock Master form displaying data.

The Grid1_Edit method fires when the user clicks on the Edit LinkButton. It sets the EditItemIndex of the DataGrid to the clicked row and calls the Bind method as follows:

Grid1_Edit

public void Grid1_Edit(Object sender, DataGridCommandEventArgs e)

{

DataGrid1.EditItemIndex = e.Item.ItemIndex;

Bind();

}

The Grid1_Cancel event fires when the user clicks on the Cancel LinkButton in the Edit mode of the DataGrid. This method simply sets the EditItemIndex to –1, which in effect tells the DataGrid that no row is now selected and that it should close the update mode. The Bind method is then called to refresh the DataGrid.

Grid1_Cancel

public void Grid1_Cancel(Object sender, DataGridCommandEventArgs e)

{

DataGrid1.EditItemIndex = -1;

Bind();

}

The Grid1_Delete event fires when the user clicks on the Delete LinkButton in the DataGrid. This event extracts the primary key of the clicked row and builds a SQL Delete query, which it hands over to the method RunSql for execution. Finally it sets the EditItemIndex to –1 and refreshes the DataGrid by calling the Bind method.

Grid1_Delete

public void Grid1_Delete(Object sender, DataGridCommandEventArgs e)

{

int Key=(int)DataGrid1.DataKeys[(int)e.Item.ItemIndex];

String code_value = Key.ToString() ;

String s = "Delete from stock_master";

s +=" where code_value = " + code_value;

RunSql(s);

DataGrid1.EditItemIndex = -1;

Bind();

}

The Grid1_Update method is fired when the user is satisfied with the changes he has made to a record in the Update mode and clicks on the Update LinkButton. The method

extracts the primary key by looking at the DataKey property of the clicked row. Then it uses the FindControl method of a control to locate its ID within the DataGrid. The returned object is cast to a TextBox and its Text property extracted as shown below. A SQL update query is built using the extracted Text properties of the TextBox controls, which is then handed over to the RunSql method for the actual execution. Finally the EditItemIndex is set to –1 and the Bind method called to refresh the DataGrid.

Grid1_Update

public void Grid1_Update(Object sender, DataGridCommandEventArgs e)

{

TextBox t;

//This is the primary key

int Key=(int)DataGrid1.DataKeys[(int)e.Item.ItemIndex];

String code_value = " code_value =" + Key.ToString() ;

t = (TextBox) e.Item.FindControl("editCode_Display");

String code_display = " code_display = '" + t.Text.Trim() + "'," ;

t = (TextBox) e.Item.FindControl("editRate");

String rate = " rate = " + t.Text.Trim() + "," ;

t = (TextBox) e.Item.FindControl("editUom");

String uom = " uom ='" + t.Text.Trim() + "'," ;

t = (TextBox) e.Item.FindControl("editOpening");

String opening = " opening = " + t.Text.Trim() ;

String s = " Update stock_master Set";

s += code_display +rate +uom ;

s += opening ;

s += " Where " + code_value;

RunSql(s);

DataGrid1.EditItemIndex = -1;

Bind();

}

This method will be used to execute SQL insert, update, and delete commands.

RunSql

public String RunSql( string vsql)

{

try

{

SqlCommand mycommand = new SqlCommand(vsql,sqlConnection1);

sqlConnection1.Open();

mycommand.ExecuteNonQuery();

sqlConnection1.Close();

}

catch(Exception e)

{

string ret = "Exception: " + e.ToString() ;

messages.Text=ret;

}

return("OK");

}

The Add_Click event fires when the user clicks on the Add LinkButton. This event initializes the TextBox controls with default values and displays them by setting the

Visible property of the AddPanel to True.

Add_Click

private void Add_Click(object sender, System.EventArgs e)

{

AddPanel.Visible=true;

AddCode_Display.Text= "";

AddRate.Text= "0";

AddUom.Text= "";

AddClosing.Text= "0";

}

The SaveNew_Click event fires when the user clicks on the SaveNew button that resides on the AddPanel. This event first sets a default value to any TextBox control not filled in by the user. It then builds a SQL Execute query call to the stored procedure p_stock_master and passes it the required parameters by extracting the Text properties of the various TextBox controls. This procedure was discussed in Chapter 24 (Inventory Masters) and if you remember, to insert a new record, you pass it a NULL code_value. This Execute query is handed over to the RunSql method that handles the actual execution. Finally the EditItemIndex is set to –1 and the Bind method is called to refresh the DataGrid.

SaveNew_Click

private void SaveNew_Click(object sender, System.EventArgs e)

{

if (AddCode_Display.Text.Length == 0)

{ messages.Text="Sorry - Account Name cannot be blank";

return ;

}

if (AddRate.Text.Length == 0)

{AddRate.Text= "0";}

if (AddUom.Text.Length == 0)

{AddUom.Text= "";}

if (AddClosing.Text.Length == 0)

{AddClosing.Text= "0";}

String s = "Execute p_stock_master ";

s += " @code_value=NULL," ;

s += " @code_display = '" + AddCode_Display.Text + "',";

s += " @rate = " + AddRate.Text + ",";

s += " @uom = '" + AddUom.Text + "',";

s += " @closing = " + AddClosing.Text ;

messages.Text= "";

RunSql(s);

DataGrid1.EditItemIndex = -1;

Bind();

}

This concludes our discussion on using Visual Studio.NET to build CRUD applications. No doubt you might have noticed the significant advantages of scripting using this tool. I must admit that I am quite impressed with the auto-completion features of Visual Studio.NET that work with the element tags in HTML view. I no longer need to remember the various attributes associated with a tag as I can see them displayed as soon as I start typing. The ability to move (and place) the controls around with my mouse is another feature that I like.

Chapter 31: Creating a Web Service Using Visual Studio.NET

In this chapter, I show you how to develop and consume a web service using Visual Studio.NET. You will first build a generic database service in C#. The web service will have a method called Populate, which will accept a SQL SELECT query. Based on this SELECT query, the web service will return a DataSet to the calling object that will contain the result set of the SELECT query. This web service will have another method called RunSQL, which will be used to apply an action query (that is, an insert, an update, or a delete query) to the database.

You will then build another Web project that will consume this service. This project will call the Populate function of the web service with appropriate parameters and receive the DataSet that contains the result set. A DataGrid will then be bound to this DataSet to display the rows returned from the database. You will also test out the RunSQL method by inserting and deleting a few rows.

Building the Generic Database Web Service

Here is how you will build the database web service: