DataGrid common attention problem solutions

zhaozj2021-02-16  52

DataGrid common attention problem solutions

HBZXF (A Ho) http://www.hebcom.net

Introduction

. The DataGrid Web server control is a powerful tool for displaying information from a data source It is easy to use;. You can display editable data in a professional-looking grid by setting only a few properties At the same time, the grid has a Sophistated Object Model That Provides You with Great Flexibility In How You Display The Data.

This paper addresses some of the questions about customizing grid display that are commonly asked in newsgroups, on Web sites, and in other developer forums. The techniques described here are sometimes quite simple and at other times somewhat involved. In each case, however, they Address a Question of How To Go Beyond The Basic FunctionAry of The DataGrid Control.

This paper assumes that you are already familiar with the control -.. How to add it to a form and configure it to display data You should also understand how to put a row in the grid into edit mode and other basic tasks (For details, SEE DATAGRID Web Server Control.) Finally, You Will Find IT Helpful To Know How To Work with Templates - Adding Template Column To The Grid and Layout Out Controls Inside A Template.

Windows Forms Versus Web Forms DataGrid Control

The Web Forms DataGrid control is not the same as the Windows Forms equivalent. It is a common (and not unreasonable) assumption that they are the same control, or at least have identical functionality. However, the entire programming paradigm for Web Forms is quite DiffERENT from That for Windows Forms. for Example, Web Forms Pages Perform A Round Trip to the Server for Any Process; The Server For Any Process; They Feature A Very Different Data-Binding Model; Ando ON.

Because of these differences, there are also significant differences in their respective controls, including the DataGrid control As a general rule, the Web Forms DataGrid control includes less built-in functionality A few examples of differences in the Web Forms DataGrid control are..: It does not inherently support master-detail data structures. As with other Web server controls, it does not support two-way data binding. If you want to update data, you must write code to do this yourself. you can only edit one row At a time. It does not inherently support sorting, although IT Raises events you can handle in Order to Sort The Grid Contents.

On the Other Hand:

You can bind the Web Forms DataGrid to any object that supports the IEnumerable interface. The Web Forms DataGrid control supports paging. It is easy to customize the appearance and layout of the Web Forms DataGrid control as compared to the Windows Forms one. (Details are Provided later in this paper.)

Controlling Column Width, Height, And Alignment

By default, the DataGrid control sizes rows and columns to fit the overall height and width that you have assigned to the grid. Within the overall grid width, it sizes columns according to the width of the column heading text. All data is displayed left- Justified by default.

To control column characteristics, you should turn off auto column generation by setting the AutoGenerateColumns property to false. In fact, you should set this property to true only for short-term uses, such as quick proof-of-concept pages or demonstrations. For PRODUCTION Applications, You Should Add Column Explicitly. The Individual Column Can Be Bound Columns Or Template Columns.

To set the column width, you create a style element for that column and then set the element's Width property to standard units (say, pixels). The following example shows you what the HTML syntax looks like for an ItemStyle element with its Width property set .

Headertext = "Title">

Alternatively, you can do the above, one by setting the itemstyle, as in the folload

Sortexpression = "title" Headertext = "Title">

You can set alignment using the style element, setting it to "Right," "Left," and other values ​​defined in the HorizontalAlign enumeration. (In Visual Studio, alignment is available for individual columns in the Format tab of the grid's Property builder. ) The folloading is an example:

Headertext = "Title">

You can also set a column's height using the style element (or the ItemStyle-Height property). You will probably find this less flexible than setting the width, since setting the height for one column sets it for all of them.

.. You can set the width in code at run time as well One place to do so is in an ItemCreated event handler The following example sets the width of the first two columns to 100 and 50 pixels, respectively: 'Visual Basic

Private sub DataGrid1_itemcreated (byval sender as object, _

Byval e as system.web.ui.webcontrols.DataGriditeMeventArgs_

Handles DataGrid1.Itemcreated

E.Item.cells (0) .width = new unit (100)

E.Item.cells (1) .width = new unit (50)

End Sub

// C #

Private void DataGrid1_Itemcreated (Object Sender,

System.Web.ui.WebControls.DataGriditeMeventargs E)

{

E.Item.cells [0] .width = new unit (100);

E.Item.cells [1] .width = new unit (50);

}

Of course, there is little sense in setting a fixed width in code that you could set at design time. You would normally do this only if you wanted to set the width based on a run-time value. You can set the width of a cell or control in units (typically pixels), but it is not straightforward to translate the length of data - which is simply a character count -. into pixels But the data is available for you to examine when you are creating the item.

Customizing Column Layout in Display and Edit Mode

.

If you want to customize the content of a column, make the column a template column. Template columns work like item templates in the DataList or Repeater control, except that you are defining the layout of a column rather than a row.

WHEN You Define a Template Column, You Can Specify The Following Template Types:

The ItemTemplate allows you to customize the normal display of the data. The EditItemTemplate allows you to specify what shows up in the column when a row is put into edit mode. This is how you can specify a control other than the default text box for editing . A HeaderTemplate and FooterTemplate allow you to customize the header and footer, respectively. (The footer is only displayed if the grid's ShowFooter property is true.) The following example shows the HTML syntax for a template column that displays Boolean data. Both the ItemTemplate and EditItemTemplate use a check box to display the value. In the ItemTemplate, the check box is disabled so that users do not think they can check it. In the EditItemTemplate, the check box is enabled.

ID = "CheckBox2"

Checked = '<% # databinder.eval (container,

"DataItem.discontinued")%> '>

Runat = "server" name = "checkbox2" id = "checkbox2"

Checked = '<% # databinder.eval (container,

"DataItem.discontinued")%> '>

Note if you use a

Checkbox Control in The

EditItemTemplate, Be Aware That At Run Time, The Grid Cell Actually Contains Several

LITERALCONTROL Controls (for spacing) in addition to the check box itself. WHENEVER You know the id of the control whose value you want, us

FindControl Method to create a reason to it, rather Than Using Specific Indexes INTO Thecells and

Controls Collectes:

'Visual Basic

DIM CB As Checkbox

CB = CType (E.Item.FindControl ("Checkbox2"), Checkbox)

// C #

Checkbox CB;

CB = (Checkbox) E.Item.FindControl ("CheckBox2");

In Visual Studio, you can use the grid's Property builder to create the template column and use the template editor to specify the layout. In the Columns tab of the Properties window page for the grid, select the column and at the bottom, click Convert this COLUMN INTO A Template Column. Close The Properties Window, Right-Click The Grid, And Choose Edit Template. You can the TEX THE TEMPLATE AND ADD Static Text.

Formatting Dates, Currency, And Other Data

Information in a DataGrid control is ultimately displayed in an HTML table in the Web Forms page. To control how data is displayed, therefore, you can specify .NET string formatting for column values. You can not specify formatting for columns generated when the grid's AutoGenerateColumns property IS set to true, only for bound or template columns.

To format, set the column's DataFormatString property to a string-formatting expression suitable for the data type of the data you are formatting A slightly confusing aspect of format strings is that the same specifier -. For example, "D" - can be applied to DiffERENT DATA TYPES (Integers, Dates) with Different Results.

Note in Visual Studio, You CAN Specify A Formatting Expression in The

Columns Tab of The Control's Property Builder.

Some example formatting strings are listed in the following table For more information, see the topics Formatting Types and BoundColumn.DataFormatString Property in the Visual Studio documentation.Format expressionApplied to this data typeDescriptionPrice:. {0: C}

Note the {0} is a zero, not the letter.

numeric / decimalDisplays the literal "Price:" followed by numbers in currency format The currency format depends on the culture setting specified via the culture attribute on the Page directive or in the Web.config file.. {0: D4} integer (Can not be . used with decimal numbers) Integers are displayed in a zero-padded field four characters wide {0: N2}.% numericDisplays the number with 2-decimal place precision followed by the literal "%" {0: 000.0}. numeric / decimalNumbers . rounded to one decimal place Numbers less than three digits are zero padded {0: D}. date / datetimeLong date format ( "Thursday, August 06, 1996") Date format depends on the culture settting of the page or the Web.. Config file. {0: D} Date / DateTimeshort Date Format ("12/31/99"). {0: YY-MM-DD} Date / DateTimedate in Numeric Year-Month-Day Format (96-08-06) .

Showing and hiding columns dynamically

One way to have columns appear dynamically is to create them at design time, and then to hide or show them as needed. You can do this by setting a column's Visible property. The following example shows how to toggle the visibility of the second column ( INDEX 1) of the grid:

'Visual Basic

DataGrid1.columns (1) .visible = NOT (DataGrid1.columns (1) .visible)

// C #

DataGrid1.columns [1] .visible =! (DataGrid1.columns [1] .visible);

Add COLUMNS DYNAMICOLY

You can hide and show columns if you know in advance what columns you need. Sometimes, however, you do not know that until run time. In that case, you can create columns dynamically and add them to the grid.To do so, you create an instance of one of the column classes supported by the grid -. BoundColumn, EditCommandColumn, ButtonColumn, or HyperlinkColumn (You can add template columns to the grid, but it is slightly more complex For details, see Creating Web Server Control Templates Programmatically. .) Set The Column's Properties, and then add it to the grid's columns collection.

The Following Example Shows How To Add Two Bound Column To A Grid.

'Visual Basic

Private sub button1_click (byval sender as system.Object, _

Byval e as system.eventargs) Handles Button1.click

'Set Data-Binding Properties of The Grid

DataGrid1.autogeneratecolumns = false

DataGrid1.datasource = me.dsbooks1

DataGrid1.DataMember = "Books"

DataGrid1.DataKeyfield = "BookID"

'Add Two Columns

DIM DGC_ID AS New BoundColumn ()

DGC_ID.Datafield = "BookID"

DGC_ID.Headertext = "ID"

DGC_ID.ItemStyle.Width = New Unit (80)

DataGrid1.columns.add (DGC_ID)

DIM DGC_TITLE AS New BoundColumn ()

DGC_Title.Datafield = "Title"

DGC_TITLE.HEADERTEXT = "Title"

DataGrid1.columns.add (dgc_title)

Me.sqldataAdapter1.fill (me.dsbooks1)

DataGrid1.databind ()

End Sub

// C #

Private void Button1_Click (Object Sender, System.Eventargs E)

{

DataGrid1.autogeneratecolumns = false;

DataGrid1.datasource = this.dsbooks1;

DataGrid1.DataMember = "books";

DataGrid1.DataKeyfield = "BookID";

// Add Two Column

BoundColumn DGC_ID = New BoundColumn (); DGC_ID.Datafield = "BookID";

DGC_ID.Headertext = "ID";

DGC_ID.ItemStyle.Width = New Unit (80);

DataGrid1.columns.add (DGC_ID);

BoundColumn DGC_Title = new boundcolumn ();

DGC_TITLE.DATAFIELD = "Title";

DGC_TITLE.HEADERTEXT = "Title";

DataGrid1.columns.add (dgc_title);

THIS.SQLDATAADAPTER1.FILL (THIS.DSBOOKS1);

DataGrid1.databind ();

}

Any time that you add controls to a page dynamically, you have the problem of persistence. Dynamically-added controls (or in this case, columns) are not automatically added to the page's view state, so you are obliged to add logic to the page To make Sure The Column Are Available with Each Round Trip.

An excellent way to do this is to override the page's LoadViewState method, which gives you an early opportunity to reestablish columns in the DataGrid control. Because the LoadViewState method is called before the Page_Load event is raised, re-adding columns in the LoadViewState method assures That They area is the Time Any Event Code Run.

The following example shows how you would expand the previous example to restore the columns each time the page runs again. As before, the Button1_Click handler adds two columns to the grid. (In this example, the event handler calls a separate routine called AddColumns to . do so) in addition, the page contains a simple Boolean property called DynamicColumnsAdded indicating whether the grid has had columns added; the property persists its value in view state The LoadViewState method first calls the base class's LoadViewState method, which extracts view state information. And Configures Controls with it. if columns were previously added to the dynamiccolumnsadded profrty

Private property DynamicColumnAdded () as boolean

Get

IF ViewState ("ColumnAdded") Is Nothing Then

Return False

Else

Return True

END IF

END GET

Set (ByVal Value As Boolean)

ViewState ("ColumnAdded") = Value

End set

End Property

Protected Overrides Sub LoadViewState (Byval SavedState As Object)

Mybase.loadviewState (SavedState)

If Me. DynamicColumnAdded Then

Me.AddColums ()

END IF

End Sub

Private sub button1_click (byval sender as system.Object, _

Byval e as system.eventargs) Handles Button1.click

'Check Property to Be Sure Column Are Not Added More Tan ONCE

If Me. DynamicColumnAdded Then

Return

Else

Me.AddColums ()

END IF

End Sub

Protected sub addcolums ()

'Add Two Columns

DIM DGC_ID AS New BoundColumn ()

DGC_ID.Datafield = "Instock"

DGC_ID.Headertext = "in stock?"

DGC_ID.ItemStyle.Width = New Unit (80)

DataGrid1.columns.add (DGC_ID)

DIM DGC_TITLE AS New BoundColumn ()

DGC_Title.Datafield = "Title" DGC_Title.Headertext = "Title"

DataGrid1.columns.add (dgc_title)

Me.DataGrid1.databind ()

Me. DynamicColumnAdded = TRUE

End Sub

// C #

Private bool dynamiccolumnadded {

get

{

Object b = viewstate ["DynamicColumnAdded"];

Return (b == null) False: true;

}

set

{

ViewState ["DynamicColumnAdded"] = Value;

}

}

Protected Override Void LoadViewState (Object SavedState)

{

Base.LoadViewState (SavedState);

IF (DynamicColumnAdded)

{

THIS.ADDCOLUMNS ();

}

}

Private void Button1_Click (Object Sender, System.Eventargs E)

{

IF (this. DynamicColumnAdded! = true)

{

THIS.ADDCOLUMNS ();

}

}

Private void addColumns ()

{

BoundColumn DGC_ID = new boundcolumn ();

DGC_ID.Datafield = "BookID";

DGC_ID.Headertext = "ID";

DGC_ID.ItemStyle.Width = New Unit (80);

DataGrid1.columns.add (DGC_ID);

BoundColumn DGC_Title = new boundcolumn ();

DGC_TITLE.DATAFIELD = "Title";

DGC_TITLE.HEADERTEXT = "Title";

DataGrid1.columns.add (dgc_title);

THIS.SQLDATAADAPTER1.FILL (THIS.DSBOOKS1);

DataGrid1.databind ();

THIS. DynamicColumnAdded = True;

}

Add New Records to a Data Source Using The DataGrid Control

. The DataGrid control allows users to view and edit records, but does not inherently include the facility to add new ones However, you can add this functionality in various ways, all of which involve the following:

Adding a new, blank record to the data source of the grid (in the dataset or database). If necessary, you will need to assign an ID for the record and put placeholder values ​​into it for any columns can not be null that. Rebinding the DataGrid control to the source. Putting the grid into edit mode for the new record. You need to be able to determine where in the grid the new record appears. Updating the record normally when the user clicks Update, thereby writing the new record to the source with user-provided values.The following example shows the process for adding the new record, binding the grid, and putting it into edit mode. In this example, the data source is a dataset (dsBooks1 or dsBooks1) containing a table called " Books. "

'Visual Basic

Private sub btnaddrow_click (byval sender as system.Object, _

Byval e as system.eventargs) Handles btnaddrow.click

DIM DR AS DATAROW = Me.dsbooks1.books.newrow

DR ("Title" = "(New)"

DR ("Instock") = true

Me.dsbooks1.books.rows.insertat (DR, 0)

Session ("DSBooks") = dsbooks1

DataGrid1.editIndex = 0

DataGrid1.databind ()

End Sub

// C #

Private void btnaddrow_click (Object Sender, System.Eventargs E)

{

DataRow Dr = this.dsbooks1.books.newrow ();

DR ["Title"] = "(New)";

DR ["Instock"] = TRUE;

this.dsbooks1.books.rows.insertat (DR, 0);

Session ["DSBooks"] = dsbooks1;

DataGrid1.edititemindex = 0;

DataGrid1.databind ();

}

Some things to notice:

This code runs when a user clicks an Add button somewhere in the page. The new row is created using the NewRow method. It is then inserted into the dataset table using the InsertAt method, which allows you to place it at a specific, predefined location - in this case, as the first record in the table (that is, the first record in the Rows collection) Alternatively, you could add it to the end of the table, using the row count as the value The important thing is.. that you know exactly where the row is in the table. Because you know that the record is in the first position of the table, you can set the grid's EditItemIndex value to zero to put the new row into edit mode. (If you created the . row elsewhere in the table, you would set EditItemIndex to that location instead) Because you have a new record in the dataset (but not yet in the database), you have to keep a copy of the dataset between round trips - you do not Want to refill it from the database and lose the new record. here, the . Code stores it in Session state You need to reload the dataset from Session state when the page loads The following example shows what your Page_Load handler might look like:. 'Visual BasicPrivate Sub Page_Load (ByVal sender As System.Object, _

BYVAL E as system.eventargs) Handles mybase.load

IF me.ispostback then

DSBooks1 = CType (Session ("DSBooks"), DSBooks

Else

Me.sqldataAdapter1.fill (me.dsbooks1)

Session ("DSBooks") = dsbooks1

DataGrid1.databind ()

END IF

End Sub

// C #

Private Void Page_Load (Object Sender, System.EventArgs E)

{

IF (this.ispostback)

{

DSBooks1 = (DSBooks) session ["dsbooks"];

}

Else

{

THIS.SQLDATAADAPTER1.FILL (THIS.DSBOOKS1);

Session ["DSBooks"] = dsbooks1; this.dataGrid1.databind ();

}

......................

You can update the record normally For an example, see Walkthrough:.. Using a DataGrid Web Control to Read and Write Data in the Visual Studio documentation After updating the dataset, update the database, then refresh the dataset Be sure to save the refreshed. DataSet to session state again. Here is an esample of an update handler:

'Visual Basic

Private sub DataGrid1_updateCommand (Byval Source As Object, _

Byval e as system.Web.ui.WebControls.DataGridCommandEventArgs_

Handles DataGrid1.UpdateCommand

DIM DR AS DATASET.BOOKSROW

'Get a reason to row Zero (where the row was inserted)

DR = me.dsbooks1.books (0)

DIM TB As TextBox = CType (E.Item.cells (2) .controls (0), Textbox)

Dr.title = tb.text

DIM CB As Checkbox = CType (E.Item.cells (3) .controls (1), Checkbox)

Dr.instock = cb.checked

Me.sqldataAdapter1.Update (me.dsbooks1)

DataGrid1.editIndex = -1

'Refresh the dataset from the database

DSBooks1.clear ()

Me.sqldataAdapter1.fill (me.dsbooks1)

'Save the Refreshed Dataset in Session State Agin

Session ("DSBooks") = dsbooks1

DataGrid1.databind ()

End Sub

// C #

Private void DataGrid1_UpdateCommand (Object Source,

System.Web.ui.WebControls.DataGridCommandEventArgs E)

{

DSBOOKS.BOOKSROW DR;

// Get a reference to row zero (where the row was inserted)

Dr = this.dsbooks1.books [0];

Textbox TB1 = (TextBox) E.Item.cells [2] .controls [0];

Dr.title = tb1.text;

Checkbox CB = (Checkbox) E.Item.cells [3] .controls [1];

Dr.instock = cb.checked;

THIS.SQLDATAADAPTER1.UPDATE (this.dsbooks1); DataGrid1.editItemIndex = -1;

// Refresh the dataset from the database

DSBooks1.clear ();

THIS.SQLDATAADAPTER1.FILL (THIS.DSBOOKS1);

// Save the Refreshed DataSet in Session State Agin

Session ["DSBooks"] = dsbooks1;

DataGrid1.databind ();

}

Displaying a drop-down list in Edit Mode

A common request is to present users with a drop-down list when a row is in edit mode. For example, the grid might show a list of books, including each book's genre. When users edit a book record, they might want to assign A DiffERENT GENRE; Ideally, They CAN SELECT from A Drop-Down List That Shows Possible Genre Values ​​Such as "fiction," "" "" ""

Displaying a drop-down list requires a template column in the grid. Typically, the ItemTemplate contains a control such as a data-bound Label control to show the current value of a field in the record. You then add a drop-down list to the EditItemTemplate. in Visual Studio, you can add a template column in the Property builder for the grid, and then use standard template editing to remove the default TextBox control from the EditItemTemplate and drag a DropDownList control into it instead. Alternatively, you can add The Template Column in Html View.

After you have created the template column with the drop-down list in it, there are two tasks The first is to populate the list The second is to preselect the appropriate item in the list -.. For example, if a book's genre is set To "fiction," WHEN The Drop-down List Displays, You OFTEN WANT "fiction" to be preselected. (Preselecting An Item Might Not Be An Issue In All Scenarios.)

There are many ways to populate the drop-down list The following examples show you three possibilities:. Using static items; using records from a dataset; or by using a data reader to read information directly from a database.Static Items

To display static items in the drop-down list, you do not data bind the control. Instead, you simply define items in the control's Items collection. In Visual Studio, you can invoke the Items collection editor from the Items property in the Properties window Alternative, you can add items in html view.

The following shows a complete column definition for a template column that displays the genre in display mode, and a static list of genre types in edit mode. The ItemTemplate contains a Label control whose Text property is bound to the "genre" field of the current Record. The Declarations for the Static Items in The EditItemplate Are Highlight.

Text = '<% # DataBinder.eval (Container, "DataItem.genre")%>'>

fiction

Biography

Reference

DataSet

If the data you want to display in the drop-down list is in a dataset, you can use ordinary data binding. The following shows the declarative syntax. The DropDownList control is bound to the Genre table in a dataset called DsBooks1. The data- Binding settings are highlight.

Text = '<% # DataBinder.eval (Container, "DataItem.genre")%>'>

DataSource = "<% # dsbooks1%>" DataMember = "genre"

DataTextField = "genre" DataValuefield = "genre" width = "160px">

Data Reader

You can also populate the drop-down list directly from a database. This method is more involved, but it can be more efficient, since you do not actually read the data from the database till the moment you need it.

A relatively easy way to do this is to take advantage of Web Forms data-binding expressions. Although it is most common to call the DataBinder.Eval method in a data-binding expression, you can in fact call any public member available to the page .......................

For this scenario, you will need to be able to execute a data command that gets the records you want. For example, you might define a data command whose CommandText property is Select * from Genres. To simplify the example, it will be assumed that you have a connection object and a data command object already on the page.Start by creating a public function in the page that creates a data table object and defines the columns you need in it. Then open the connection, execute the data command to return .

The following example shows how you can do this. In this case, there is only one column in the returned table ( "genre"). When you populate a drop-down list, you usually need only one column, or two columns if you Want to set the drop-down list's text and values ​​to different columns.

'Visual Basic

Public Function GetgenRetable () AS DataTable

DIM DTGENRE AS DATATABLE = New DataTable ()

IF Application ("Genretable") Is Nothing Then

DIM DR AS DATAROW

DIM DC AS New Datacolumn ("Genre")

DTGENRE.COLUMNS.ADD (DC)

Me.sqlConnection1.Open ()

DIM DREADER As Sqlclient.sqlDataReader = _

Me.sqlcommand1.executeReader ()

While Dreader.read ()

Dr = dtgenre.newrow ()

DR (0) = DREADER (0)

DTgenre.Rows.Add (DR)

End while

Me.sqlConnection1.close ()

Else

DTGENRE = CTYPE (Application ("Genretable", DataTable)

END IF

Return DTGENRE

END FUNCTION

// C #

Public DataTable getgenretable ()

{

DataTable dtgenre = new datatable ();

IF (Application ["Genretable"] == NULL)

{

DataRow DR;

Datacolumn DC = New Datacolumn ("genre"); dtgenre.column.add (dc);

THIS.SQLCONNECTION1.OPEN ();

System.data.sqlclient.sqldataReader DREADER =

This.sqlcommand1.executeReader ();

While (DREADER.READ ())

{

DR = dtgenre.newrow ();

DR [0] = DREADER [0];

DTgenre.Rows.Add (DR);

}

THIS.SQLCONNECTION1.CLOSE ();

}

Else

{

DTGENRE = (DataTable) Application ["genretable"];

}

Return DTGENRE;

}

Notice that the function caches the table it creates into Application state. Since the table is acting as a static lookup table, you do not need to re-read it every time a different row is put into edit mode. Moreover, because the same table CAN be used by Multiple Uses, you can cache it in the global application state..

. The following shows the declaration for the template column You will see that this is very similar to the syntax used for binding to a dataset table;. The only real difference is that the DataSource binding calls your function A slight disadvantage of this technique is that you do not get much design-type assistance from Visual Studio. Because you are defining the table to bind to in code, Visual Studio can not offer you any choices for the DataMember, DataTextField, and DataValueField property settings. It is up to you to be Sure That You Set these Properties to the names of the members you create in code.

Text = '<% # DataBinder.eval (Container, "DataItem.genre")%>'>

DataMember = "genre"

DataTextField = "genre"

DataValuefield = "genre"

Width = "120px">

Preselecting An Item in the drop-down list

You often want to set the selected item in the drop-down list to match a specific value, usually the value displayed in the cell in display mode. You can do this by setting the SelectedIndex property of the drop-down list to the index of The value to display.

The following example shows a reliable way to do this in a handler for the DataGrid item's ItemDataBound event. This is the correct event to use, because it guarantees that the drop-down list has already been populated, no matter what data source the drop- Down List is using.

The trick is in knowing what value to set the drop-down list to. Typically, the value is already available to you either in the current item (being displayed) or in the DataItem property of the current item, which returns a DataRowView object containing . the current record Once you have the value, you can use the DropDownList control's FindByText or FindByValue method to locate the correct item in the list; you can then use the item's IndexOf property to return the index.

'Visual Basic

Private sub DataGrid1_itemdatabase (Byval Sender As Object, _

Byval e as system.web.ui.webcontrols.DataGriditeMeventArgs_

Handles DataGrid1.ItemDatabase

If E.Item.ItemType = ListItemType.editItem Then

DIM DRV AS DATAROWVIEW = CTYPE (E.Item.DataItem, DataRowView)

DIM Currentgenre As String = CType (DRV ("Genre"), String) DIM DDL As DropdownList

DDL = ctype (E.Item.FindControl ("DropdownList1"), DROPDOWNLIST)

Ddl.selectedIndex = DDL.Items.indexof (DDL.Items.FindBytext (currentgenre))

END IF

End Sub

// C #

Private void DataGrid1_itemdatabase (Object Sender,

System.Web.ui.WebControls.DataGriditeMeventargs E)

{

IF (E.Item.ItemType == ListItemType.editItem) {

DataRowView DRV = (DATAROWVIEW) E.Item.DataItem;

String currentgenre = DRV ["genre"]. TOSTRING ();

DropDownList DDL =

(DROPDOWNLIST) E.Item.FindControl ("DropDownList1");

DDL.SelectedIndex =

Ddl.Items.indexof (DDL.Items.FindBytext (currentgenre);

}

}

SELECTING MULTIPLE ITEMS Using a check box (Hotmail Model)

In Applications Such As Microsoft Hotmail®, Users Can "Select" rows by checking a box and then performing an Operation on all the successs - for example, delete them or copy them.

To Add A Template Column To The Grid and Put a Check Box Into The Column .hen The page runs, users..................

To actually perform the user action, you can walk the grid's Items collection, looking into the appropriate column (cell) to see if the check box is checked. The following example shows how you can delete rows in a dataset corresponding to the items that a User Has Checked. The Dataset, Called DSBooks1, IS Assumed to Contain A Table Called Books.

'Visual Basic

Private sub btndelete_click (Byval Sender as system.Object, _

Byval e as system.eventargs) Handles btndelete.click

'Walk the Grid Looking for SELECTED ROWS

DIM I as integer = 0

DIM CB As Checkbox

DIM DGI AS DataGridItemDim Bookid As INTEGER

DIM DR AS DSBOOKS.BOOKSROW

For Each DGI in DataGrid1.Items

CB = ctype (DGI.cells (0) .controls (1), Checkbox)

IF cb.checked then

'DETERMINE THE Key of The SELECTED RECORD ...

Bookid = ctype (DataGrid1.DataKeys (i), integer

'... get a pointer to the corresponding dataset record ...

DR = me.dsbooks1.books.findbybookid (bookid)

'... and delete it.

Dr.delete ()

END IF

i = 1

NEXT

Me.sqldataAdapter1.Update (dsbooks1)

Me.sqldataAdapter1.Fill (dsbooks1)

DataGrid1.databind ()

End Sub

// C #

Private void btndelete_click (Object Sender, System.Eventargs E)

{

INT i = 0;

Checkbox CB;

Int bookid;

DSBOOKS.BOOKSROW DR;

Foreach (DataGridItem DGI in this.DataGrid1.Items)

{

CB = (Checkbox) DGI.cells [0] .controls [1];

IF (cb.checked)

{

// determine the key of the selected record ...

Bookid = (int) DataGrid1.DataKeys [i];

// ... Get a Pointer to the Corresponding DataSet Record ...

Dr = this.dsbooks1.books.findbybookid (bookid);

// ... and delete it.

Dr.delete ();

}

i ;

}

This.sqldataAdapter1.Update (this.dsbooks1);

THIS.SQLDATAADAPTER1.FILL (THIS.DSBOOKS1);

DataGrid1.databind ();

}

Some Points to Note:

You can determine whether the check box is checked by using the standard approach for getting a control value from a template column -. Getting an object from the Controls collection of the cell and casting it appropriately If you are getting a Checkbox control, remember that it is usually the second control (index 1) because a literal control precedes it (even if it is blank). If you are deleting, you must do so by key and not by offset in the dataset. The index of an item in the DataGrid control might not match the index of the same record in the table. Even if it does at first, after the first record is deleted it will not. Here, the code gets the record key out of the grid's DataKey collection. It then uses the findBy method in the dataset table to locate the record to delete. After the records have been deleted from the dataset (technically, they are only marked for deletion), you delete them from the database by calling the data adapter's Update method. The Code Then Refresh Es the dataset from the database and re-binds the grid.editing multiple rows at ONCE

The standard way to edit rows in the DataGrid control - by adding an "Edit, Update, Cancel" button to the grid's columns -. Only allows users to edit one row at a time If users want to edit multiple rows, they must click the Edit Button, Make Their Changes, And The Click The Update Button for Each Row.

In some cases, a useful alternative is to configure the grid so that it is in edit mode by default In this scenario, the grid always displays editable data in text boxes or other controls;. Users do not explicitly have to put the grid into edit Mode. Typically, Users Make Whate Changes The Grid. Submit All Changes at ONCE. The page Might Look Something Like The Following: Figure 1

You can use this style of editing grid with any data model, WHETHER You are Working Against A DataSet or Directly Against The Data Source Using Data Commands.

To configure the grid for multiple-row edit, add the columns as you normally would and convert all editable columns to template columns. In the Columns tab of the grid's Property Builder, select the column and at the bottom of the window, choose Convert this COLUMN INTO A Template Column. To Edit The Templates, Right-Click The Grid and Choose Edit Template.

Add the edit controls to the ItemTemplate. Note that you are not adding them to the EditItemTemplate, as you normally would, because the rows will not be displayed in edit mode. That is, the ItemTemplate will contain editable controls.

SET UP DATA BINDING for the Grid Normally. You will NEED TO BIND Each Editable Control Individually. A Typical Data Binding Expression Will Look Like this:

DataBinder.eval (Container, "DataItem.title")

Loading the net..

The following example shows one possibility. In this case, it is assumed that you are using a data command (dcmdUpdateBooks) that contains a parameterized SQL Update statement. The code walks through the grid, item by item, extracts values ​​from the editable controls, And assigns the values ​​to command parameters. It Then Executes The Data Command ONCE for Each Grid Item. 'Visual Basic

Private sub btnupdate_click (Byval Sender as system.Object, _

Byval e as system.eventargs) Handles btnUpdate.click

DIM I as integer

DIM DGI As DataGridItem

Dim bookid as integer

Dim TextBoxTitle As Textbox

Dim CheckboxInstock As Checkbox

Dim TextBoxPrice As Textbox

Dim labelbookid as label

For i = 0 to DataGrid1.Items.count - 1

DGI = DataGrid1.Items (i)

Labelbookid = ctype (dgi.cells (0) .controls (1), label

Bookid = ctype (labelbookid.text, integer)

TextBoxTitle = CType (DGI.FindControl ("TextBoxTitle"), TextBox

CheckboxInstock = _

CType (DGI.FindControl ("CheckBoxInstock", Checkbox)

TextBoxPrice = CType (DGI.FindControl ("TextBoxPrice"), TextBox)

Me.dcmdupdateBooks.Parameters ("@ Bookid"). Value = BookID

Me.dcmdupdatebooks.Parameters ("@ title"). Value = TextBoxTitle.Text

Me.dcmdupdatebooks.Parameters ("@ instock"). Value = _

CheckboxInstock.checked

Me.dcmdupdatebooks.Parameters ("@ price"). Value = textBoxPrice.Text

Me.sqlConnection1.Open ()

Me.dcmdupdateBooks.executenonQuery ()

Me.sqlConnection1.close ()

NEXT

End Sub

// C #

Private void btnupdate_click (Object Sender, System.Eventargs E)

{

INT I;

DataGridItem DGI;

Int bookid;

Textbox textboxTitle;

Checkbox checkboxinstock;

Textbox textBoxprice;

For (i = 0; i <= DataGrid1.items.count -1; i ) {

DGI = DataGrid1.items [i];

Label labelbookid = (label) Dgi.cells [0] .controls [1];

Bookid = int.parse (labelbookid.text);

TextBoxTitle = (TextBox) DGI.FindControl ("TextboxTitle");

CheckBoxInstock = (Checkbox) DGI.FindControl ("CheckBoxInstock");

TextBoxPrice = (TextBox) DGI.FindControl ("TextBoxPrice");

This.dcmdupdatebooks.Parameters ["@ Bookid"]. value = bookid;

This.dcmdupdatebooks.Parameters ["@ Title"]. Value = textboxtitle.Text;

This.dcmdupdatebooks.Parameters ["@ instock"]. value =

Checkboxinstock.Checked;

This.dcmdupdatebooks.Parameters ["@ price"]. Value =

FLOAT.PARSE (TEXTBOXPRICE.TEXT);

THIS.SQLCONNECTION1.OPEN ();

THIS.DCMDUPDATEBOOKS.EXECUTENONQUERY ();

THIS.SQLCONNECTION1.CLOSE ();

}

}

Checking for change items

One disadvantage of the update strategy illustrated above is that it can be inefficient to send updates to the dataset or database for each grid row if there have been only a few changes. If you are working with a dataset, you can add logic to check for . changes between the controls in the grid and the corresponding columns in dataset rows If you are not using a dataset - as in the example above - you can not easily make this comparison, since it would involve a round trip to the database.

A strategy that works for both types of data sources is to establish a way to determine whether rows are "dirty" so you can check that before making an update. The definitive way to determine whether a row has been dirtied is to handle the changed event for the controls in a row. for example, if your grid row contains a TextBox control, you can respond to the control's TextChanged event. Similarly, for check boxes, you can respond to a CheckedChanged event.In the handler for these events, you maintain a list of the rows to be updated. Generally, the best strategy is to track the primary keys of the affected rows. For example, you can maintain an ArrayList object that contains the primary keys of the rows to update.

Imagine That You Want To Follow this Strategy for the Example Above. Create An Instance of an ArrayList Object As a Member of The Page Class:

'Visual Basic

Protected bookidlist as arraylist = new arraylist ()

// C #

Protected arraylist bookidlist = new arraylist ();

Then create a handler to add the book ID to the ArrayList object whenever a control is changed The following code shows a handler that can be invoked when a TextBox control raises its TextChanged event or when a CheckBox control raises its CheckedChanged event.:

'Visual Basic

Protected Sub Rowchanged (Byval Sender As Object, _

ByVal e as system.eventargs)

DIM DGI As DataGridItem = _

Ctype (CType (Sender, Control) .namingContainer, DataGridItem)

Dim Bookidlabel as label = ctype (DGI.cells (0) .controls (1), Label

Dim bookid as integer = ctype (BookidLabel.Text, Integer)

IF not (BookidList.Contains) THEN

BookidList.Add (Bookid)

END IF

End Sub

// C #

Protected Void Rowchanged (Object Sender, System.EventArgs E) {

DataGridItem DGI = (DataGridItem) ((Control) Sender .namingContainer;

Label bookidlabel = (label) DGI.cells [0] .controls [1];

INT bookid = int.parse (BookidLabel.Text);

IF (! bookidlist.contains)

{

BookidList.Add (Bookid);

}

}

Note The Method Cannot Be Private, or You Will Not Be Able To Bind To It Later.

It is helpful to understand that change events do not, by default, post the page back to the server. Instead, the event is raised only when the page is posted some other way (usually via a Click event). During page processing, the .................. ..

On to the RowChanged method illustrated above. The code needs to get the book ID out of the current item. The event does not pass the item to you (as it does for many DataGrid events, for example), so you have to work backwards . From the sendcontainer. From the name, you can drill back down to get the value of the book ID.

You need to check that the book ID is not already in the array. Each control in the row raises the event individually, so if there has been a change in more than one control, you could potentially end up adding the book ID to the array More Tan Once.

The change events for controls are always raised and handled before click events. Therefore, you can build the array list in the change event and know that it will be available when the event handler runs for the button click that posted the form (in this example , the btnUpdate_Click handler) .Now that you have the array list, you can make a minor modification to the handler that manages the update. In the btnUpdate_Click, when you iterate through the data grid items, add a test to see if the current book ID IS in the array list; if so, make the update.

'Visual Basic

Private sub btnupdate_click (Byval Sender as system.Object, _

Byval e as system.eventargs) Handles btnUpdate.click

DIM I as integer

DIM DGI As DataGridItem

'REST of Declarations Here

For i = 0 to DataGrid1.Items.count - 1

DGI = DataGrid1.Items (i)

Labelbookid = ctype (dgi.cells (0) .controls (1), label

IF BookidList.Contains (Bookid) THEN

TextBoxTitle = CType (DGI.FindControl ("TextBoxTitle"), TextBox

'REST OF Update Code Here

END IF

NEXT

End Sub

// C #

Private void btnupdate_click (Object Sender, System.Eventargs E)

{

INT I;

DataGridItem DGI;

Int bookid;

// REST of Declarations Here

For (i = 0; i <= DataGrid1.items.count -1; i )

{

DGI = DataGrid1.items [i];

Tablecell TC = DGI.Cells [0];

String s = dgi.cells [0] .TEXT;

Label labelbookid = (label) Dgi.cells [0] .controls [1];

Bookid = int.parse (labelbookid.text);

IF (BookidList.Contains (BookID))

{

// Update Code Here

}

}

}

One task is left:. Binding the handlers to the control events In Visual Studio, you can only do this in HTML view The controls are not explicitly instantiated in the code-behind file, so they are not supported by the code tools Switch.. The .aspx file to html view and in the declarative elements for each of the controls, add the following highlight syntax:

ID = textboxtitle runat = "server"

Text = '<% # DataBinder.eval (Container, "DataItem.title")%>'>

Runat = "server"

Checked = '<% # databinder.eval (Container, "DataItem.instock")%>>

Both the TextBox and CheckBox controls can call the same method from their respective change methods, because the signature for both event handlers is the same. That would be true also if you had a list box or drop-down list control, whose SelectedIndexChanged events likewise Pass the same arguments.

Selecting rows by clicking anywhere

The default model for selecting rows in the grid is for you to add a Select button (actually, a LinkButton control) whose CommandName property is set to "Select." When the button is clicked, the DataGrid control receives the Select command and automatically displays The row in successd mode.

Not everyone likes having an explicit Select button, and a common question is how to implement the feature where users can click anywhere in a grid row to select it. The solution is to perform a kind of sleight-of-hand in the grid. You add the Select LinkButton control as normal. Users can still use it, or you can hide it. In either event, you then inject some client script into the page that effectively duplicates the functionality of the Select button for the row as a whole.The example below shows how. in the grid's ItemDataBound handler, first make sure that you are not in the header, footer, or pager. Then get a reference to the Select button, which in this instance is assumed to be the first control in the first cell. you then call a little-known method called GetPostBackClientHyperlink. This method returns the name of the postback call for the designated control. in other words, if you pass in a reference to a LinkButton control, it returns the name of the client function Call th At Will Perform The Postback.

Finally, you assign the client-side method to the item itself. When the grid renders, it renders as an HTML table. By assigning the method to the item, it is the equivalent of adding client-side code to each row ( element) in the table. The grid's Item object does not directly support a way to assign client code to it, but you can do that by using its Attributes collection, which passes anything you assign to it through to the browser.

Note One Small Disadvantage of this Technique Is That Ids Somewhat To The Stream Rendered To The Browser, And It Adds Information.

'Visual Basic

Private sub DataGrid1_itemdatabase (Byval Sender As Object, _

Byval e as system.Web.ui.webcontrols.dataGriditemeventargs_Handles DataGrid1.itemDatabase

DIM ITEMTYPE As ListItemType = E.Item.ItemType

IF (itemType = ListItemType.Pager) OR_

(itemtype = listitemtype.header) OR_

(itemtype = listitemtype.footer).

Return

Else

Dim Button as linkbutton = _

CType (E.Item.cells (0) .controls (0), LinkButton

E.Item.attributes ("onclick" = _

Page.GetPostBackClienthyperLink (Button, "")

END IF

End Sub

// C #

Private void DataGrid1_itemdatabase (Object Sender,

System.Web.ui.WebControls.DataGriditeMeventargs E)

{

ListitemType ItemType = E.Item.ItemType;

IF (itemType == ListItemType.pager) ||

(itemtype == ListiteMTYPE.HEADER) ||

(itemtype == ListiteMType.footer))

{

Return;

}

LinkButton Button = (LinkButton) E.Item.cells [0] .controls [0];

E.Item.attributes ["onclick] =

Page.GetPostBackClienthyPerlink (Button, ");

}

From MSDN: http://msdn.microsoft.com/library/default.asp? Url = / library / en-us / dv_vstechart / html / vbtchtopquestionsAboutaspnetDataGridSerControl.asp

转载请注明原文地址:https://www.9cbs.com/read-24242.html

New Post(0)