繁体中文
设为首页
加入收藏
当前位置:.Net技术首页 >> Asp.Net开发 >> List控件中使用日期选择

List控件中使用日期选择

2007-09-15 08:00:00  作者:  来源:互联网  浏览次数:0  文字大小:【】【】【
简介:Ask the DotNetJunkies: Using a Pop-Up Calendar and a List Control Send this to a friend Printable Version By Doug Seven, Microsoft ASP.NET MVP Published Date: 1/9/2003 Tested With: ASP.NET v...
关键字:控件 日期 选择 List

Ask the DotNetJunkies: Using a Pop-Up Calendar and a List Control

Send this to a friend Printable Version

By Doug Seven, Microsoft ASP.NET MVP

Published Date:

1/9/2003

Tested With:

ASP.NET v1

Check or Rate Page:

No VB.NET Download

Download C# Code

Rate This Article

The Question:

In a DataGrid, when the user clicks on the Edit button, a cell (TableCell) and an image link are created at runtime. When the user clicks on the image, a calendar pops up. It closes itself when the user clicks on a date. My problem is that I don't know how to populate the cell with the date that the user chooses from the calendar. I can, however, get the date from the calendar to populate the text outside the datagrid. I'd be appreciate if you coud show me some samples on how to achieve this. Thanks.

Wally Stem

The Answer:

Truthfully, if you can populate a TextBox outside of a DataGrid, you have done all of the work. The only thing your missing is how to correctly identify the control inside the DataGrid that you want to put the date into. DataGrids implement the INamingContainer interface, which means that the DataGrid dynamically renames its child controls to prevent any naming conflicts. If you look at the source code for the Web Form shown in Figure 1 you will see what I mean.

Figure 1

In Figure 1 is a DataGrid displaying the first 10 records from the Northwind Orders table, with the third record in edit mode. In the rendered HTML you can see how the TextBox (which has the ID value of txtDate) has been rendered as shown here:

You can see how the TextBox's ID value was changed to "DataGrid1:_ctl4:txtDate" - this is what the INamingContainer interface does. With this in mind, the soluion to the problem is to capture the rendered name of the TextBox at runtime and use it.

How It Works

When the Web Form is rendered with a DataGrid in edit mode you need to:

Link to a JavaScript file with the CalendarPopUp function

Render a JavaScript link in the row that is being edited

The JavaScript file is included in the source code (CalendarPopUp.js) for this article, and is shown here:

function pickDate(Src){

window.open("CalendarPopUp.ASPx?src="http://www.XMLASP.net/+ Src, "_blank", "height=260, width=250, left=100, top=100," +

"location=no, menubar=no, resizable=no, " +

"scrollbars=no, titlebar=no, toolbar=no", true);

}

When the pickDate() function is invoked, a new browser window is opened, without the navigation bars (as seen in Figure 2), and a Web Form showing the calendar is rendered.

Figure 2

The Web Form

The Web Form (WebForm1.ASPx) has a DataGrid with a single column set up for editing, the last column - the Shipped Date column. In the EditItemTemplate I have defined a single TextBox and assigned it the ID value of txtDate. When this EditItemTemplate is rendered, this TextBox will be renamed, as we saw above.

<%@ Page language="c#" Codebehind="WebForm1.ASPx.cs" AutoEventWireup="false" Inherits="CalendarPopUp.WebForm1" %>

WebForm1

The Event Handlers

Let me break down all of the event handlers for this Web Form.

The Page_Load() Event Handler

In the Page_Load() event handler I simply invoke the BindData() method whenever the request is NOT a postback. In the BindData methid I create a connection to my Northwind database and I bind the results of a SQL command to the DataGrid.

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

if (! Page.IsPostBack)

BindData();

}

private void BindData() {

SqlConnection con=newSqlConnection("server=localhost;database=Northwind;uid=sa;pwd=;");

SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Orders", con);

try {

con.Open();

DataGrid1.DataSource = cmd.ExecuteReader();

DataGrid1.DataBind();

con.Close();

}

catch (Exception ex) {

Trace.Warn(ex.Message);

}

}

The InitializeComponent() Method

In order for the next few event handlers to work properly, I edited the InitializeComponent() method that is created by Visual Studio .NET. I hade to register the new DataGrid event handlers I am adding.

private void InitializeComponent() {

this.DataGrid1.CancelCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_CancelItemCommand);

this.DataGrid1.EditCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_EditItemCommand);

this.DataGrid1.UpdateCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_UpdateItemCommand);

this.DataGrid1.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid1_OnItemDataBound);

this.Load += new System.EventHandler(this.Page_Load);

}

The DataGrid1_EditItemCommand() Handler

In the DataGri1_EditItemCommand handler I simply set the EditItemIndex property of the DataGrid and rebind the data.

private void DataGrid1_EditItemCommand(object sender, System.Web.UI.WebControls.DataGridCommandEventArgs e) {

DataGrid1.EditItemIndex = e.Item.ItemIndex;

BindData();

}

The DataGrid1_CancelItemCommand() Event Handler

In this event handler I simply reset the DataGrid to non-edit mode and rebind the data.

private void DataGrid1_CancelItemCommand(object sender, System.Web.UI.WebControls.DataGridCommandEventArgs e) {

DataGrid1.EditItemIndex = -1;

BindData();

}

The DataGrid1_UpdateItemCommand() Event Handler

In this event handler, I capture the value submitted in the txtDate TextBox and - for the purposes of this sample - render the value to a Label control. Normally you would use the value to update your data source (as is indicated by a comment in the code).

private void DataGrid1_UpdateItemCommand(object sender, System.Web.UI.WebControls.DataGridCommandEventArgs e) {

Int32 iLastCellIndex = e.Item.Cells.Count-1; //The Index for the last cell

String sNewDate = ((TextBox)e.Item.Cells[iLastCellIndex].FindControl("txtDate")).Text; //Get the value of the TextBox

Label1.Text = "You set the date " + sNewDate;

//Add database updating here

DataGrid1.EditItemIndex = -1;

BindData();

}

The DataGrid1_OnItemDataBound() Event Handler

In the DataGrid1_OnItemDataBound event handler I do a little more work. Here I render the link tag and image tag for the calendar pop-up link. I need to pass the name of my TextBox control to the CalendarPopUp.ASPx Web Form so that that Web Form know which control it has to pass a value back to. This is where I have to know the name of the TextBox as it is rendered to the client. I can use the Control.ClientID property. This property (which is inherited by all Web controls) returns the name of the HTML element that is rendered to the client. That's the big secret...that's how you can get the rendered name of a control embedded in a parent control that implements INamingContainer.

Using the ClientID value I can render the link tag, passing the ClientID value to the pickDate() JavaScript function.

private void DataGrid1_OnItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) {

if ( e.Item.ItemType == ListItemType.EditItem ) {

Int32 iLastCellIndex = e.Item.Cells.Count-1; //The Index for the last cell

String sTextBoxName = e.Item.Cells[iLastCellIndex].FindControl("txtDate").ClientID; //The rendered name of the TextBox

String sLink = "

sTextBoxName +

"');\">"; //The HTML to add to the Edit cell

e.Item.Cells[iLastCellIndex].Controls.Add(new LiteralControl(sLink)); //Add the HTML

}

}

The CalendarPopUp.ASPx Web Form

The CalendarPopUp.asx Web Form displays a Calendar control and a LinkButton control. After a date is selected in the Calendar, and the LinkButton is clicked, an event handler is used to rewrite the HTML output of the page. The new HTML closes the page and passes the selected value back to the originating page and control.

private void LinkButton1_Click(object sender, System.EventArgs e) {

System.Text.StringBuilder sbScript = new System.Text.StringBuilder();

sbScript.Append(" "); //Closing script tag

//Add the script to the page

this.Page.Controls.Add(new LiteralControl(sbScript.ToString()));

}

Summary

To use a pop-up calendar, I implemented some basic JavaScript and opened a new browser window. When I opened the window, I passed a reference to the Web control I want to put the date into. When the pop-up window is closed, it passed the date value back to the correct control. For DataGrid embedded controls I used the Control.ClientID property to get the rendered name of the Web control I am modifying. The ClientID value is the ID of the control as it appears in the browser source text, which may not be the same as the ID value assigned to the control in code.

责任编辑:admin
相关文章