Create custom columns for ASP.NET DATAGRID

xiaoxiao2021-03-06  85

Marcie RobillarddataGridgirl.com September 2003 Abstract: ASP.NET DATAGRID is a powerful control that web developers can use. Learn how to enhance the functionality of the control by adding a custom column to more accurately display data more accurately. (This article contains links to English sites.) Applicable to: Microsoft® ASP.NET

Download the source code of this article

. (Note that in the sample file, the programmer's annotation is in English. This article is translated into Chinese to facilitate the reader understanding. DROPDOWNLIST's basis: DataGridColumn can reuse methods: Creating DropDownColumn has to recognize DropDownColumn Summary profiles, writing DataGrid code for Microsoft® ASP.NET, including a large number of repetitive work. Although I am deeply troubled by this control, I still have to find shortcuts that simplify such tasks. No one is willing to do repetitive work, right? In order to get rid of this annoying work, we have to package repeated code in multiple projects into a reusable package. This is the problem to be solved by object-oriented programming, and it is no exception to use DataGrid. For DataGrid controls, to implement this, you need to place a common code into a built-in column type (will be used in the first example) and then create a customized custom use in multiple DataGrid objects. Column type. This article describes the process of using the DROPDOWNLIST control in a DataGrid column using standard TemplateColumn, and then converts the logic to your custom DataGrid column type, I call it DropDownColumn. Some free DataGrid columns have been created for you, and you can download the desired type to Metabuilders.com. Reused case If your team is the same as many organizations, business logic and / or data access logics have been divided into separate components or component sets, while the remaining ASP.NET files, ASPX and their code only contain pure representations logic. . ("Pure" is a relatively word.) However, even if the logic of the layer is sometimes repeated, this, the next time a certain user is coming to you, "I want my app in 'finance. When you look like Susu, you can reuse some of the "Financial" application part indicates that the content quickly builds such an application. You may also want to pack some logic, sell it on the web or distribute it in your Web site. ASP.NET makes it easier to implement more than ever, because it allows you to create your own server control, or export column type from an existing type to get the required features. The DropDownList solution assumes that you are editing the Northwind database (or other work) in your local Microsoft SQL ServerTM, you want your users (we call ED, warehouse centers) to edit the Orders table. One of the fields contains transport information (Shipvia), and the ED is capable of modifying information about the field. In display mode, transportation companies should appear as plain text. When the ED clicks the Edit button, you don't just provide him with a TextBox to edit the transport mode code (1, 2 or 3), but also provide him with a DropDownList that you can select different transport companies. (Because ED can't remember which number of transportation companies correspond to, the DropDownList program can help him solve this problem.)

Figure 1: After selecting the built-in DataGrid column of the transport company to learn about the problem, now let's take a step back, look at the five DataGrid column types built in the ASP.NET and its parent type DataGridColumn. Boundcolumn. This is the standard display of the text field. It is displayed as plain text, but when the DataGrid is in "editing" mode, it will be converted to TextBox. You can also choose the formatting option. HyperlinkColumn. Used to display text data and represent a web address (URL). The URL can be the same as the display text, and they can be set separately. It is displayed as

Traditional method: DROPDOWNLIST in TemplateColumn

Before studying how to create a new column type, let's take a look at how to use DropDownList to use DropDownList directly to use DropDownList to solve the drop-down list without custom columns. ItemTemplate will only contain plain text representative of the current value, and EditItemTemplate contains a control that needs to be managed at runtime.

< asp: BoundColumn DataField = "OrderID" ReadOnly = "True" HeaderText = "Order ID" /> <% # Container.DataItem (" ShipVia ")%> Binding DataGrid code:

Sub BindGrid () Dim SQL As String = "SELECT OrderID, ShipName, ShipCountry, ShipVia FROM Orders" Dim DA As SqlDataAdapter = New SqlDataAdapter (SQL, ConnStr) Dim DS As New DataSet DA.Fill (DS, "Orders") DataGrid1. DataSource = DS.TABLES ("Orders"). DefaultView DataGrid1.Database () End Sub

The currently edited item is bound to DropDownlist when triggering a DataGrid ItemDatabase. When using the itemDatabase event, check the listitemType of the current project, otherwise you may find that you are using the HeaderItem or other non-applicable project types. Quote the DropDownList control for EditItem. In the following code, I use the cell control set directly (in order to keep the following examples), however, you can use a simple method to specify ID directly to the DROPDOWNLIST control, and use the DataGrid project's FindControl method locate control Quote. Since the DataGrid is bound to the DataTable default view, the element of the view is the DataRowView type, so you can convert the DataItem property of the current project to a DataRowView instance. This way, you can directly reference the fields in DataItem directly by field name. Using this method, save the current value of "ShipVia" into this record and use it to select the corresponding drop-down list item. Private Sub DataGrid1_ItemDataBound (ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) _ Handles DataGrid1.ItemDataBound If e.Item.ItemType = ListItemType.EditItem Then Dim DRV As DataRowView = CType (e.Item. DataItem, DataRowView) Dim CurrentShip As String = DRV ( "ShipVia") Dim DDL As DropDownList = _ CType (e.Item.Cells (4) .Controls (1), DropDownList) Dim SQL As String = _ "SELECT ShipperID, CompanyName FROM Shippers ORDER BY ShipperID "Dim DA As SqlDataAdapter = New SqlDataAdapter (SQL, ConnStr) Dim DS As New DataSet Dim item As ListItem dA.Fill (DS," Shippers ") DDL.DataSource = dS.Tables (" Shippers "). DefaultView DDL.DataTextField = "CompanyName" DDL.DatavalueField = "ShipperID" DDL.DataBind () item = DDL.Items.FindByvalue (CurrentShip) If Not item Is Nothing Then item.Selected = True End IfEnd Sub

Finally, write the code that retrieves the currently selected value from the DropDownList, and executes the database update:

Private Sub DataGrid1_UpdateCommand (ByVal source As Object, _ ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _ Handles DataGrid1.UpdateCommand Dim DDL As DropDownList = _ CType (e.Item.Cells (4) .Controls (1), DropDownList) Dim NewShip As Integer = DDL.Selectedvalue Dim OrderID As Integer = Int32.Parse (e.Item.Cells (1) .Text) Dim SQL As String = _ "UPDATE Orders SET ShipVia = @ Ship WHERE OrderID = @ ID" Dim Conn As SqlConnection = New SqlConnection (ConnStr) Dim Cmd As New SqlCommand (SQL, Conn) cmd.Parameters.Add (New SqlParameter ( "@ Ship", NewShip)) cmd.Parameters.Add (New SqlParameter ( "@ ID" , OrderID) Conn.open () cmd.executenononquery () CONN.Close () DataGrid1.edititeMindex = -1 BindGrid () End Sub All columns: DataGridColumn

We review all the parent types of the built-in type type DataGridColumn. (See Figure 1.) It contains properties and methods commonly used in all DataGrid columns. Types with star indicate that you want to use the type of custom column type.

DataGridColumn properties FooterStyle (TableItemStyle) FooterText (string) HeaderImageUrl (string) HeaderStyle (TableItemStyle) HeaderText (string) ItemStyle (TableItemStyle) SortExpression (string) the Visible (Boolean) DataGridColumn method Initialize InitializeCell LoadViewState OnColumnChanged SaveViewState TrackViewState

Reusable methods: Create DropDownColumn

First create a new category library in Microsoft® Visual Studio® .NET and name it MycustomColumn. Add a new class DROPDOWNCOLUMN and make sure you add a namespace in your class definition so your initial code is as follows:

Namespace MyCustomColumn Public Class DropDownColumn Inherits DataGridColumn Public DataSource As ICollection Public DataField As String Public DataTextField As String Public DatavalueField As String End ClassEnd Namespace I also declare four public properties, as follows:

[html]

  • DataSource . It is used to populate the DropDownList data set. Can be anything that implements the ICollection interface. In the examples of this article, I use ArrayList and dataview .

  • DataField . It is the field in the parent DataGrid data source, which corresponds to the data selected from the drop-down list. For example, if DataSource contains a status set, DataField will be similar to "Statecode", or you can use the status in the form.

  • DataTextField . This is the text to be displayed in the drop-down list, or it is not.

  • data

    Valuefield . This is the value indicating the special drop-down option. data

    Valuefield is usually an integer value or other code, and DataTextField is a text description of the user's more meaningful.

    [/ html]

    Next, override Initializecell, it is a natural event of the DataGrid column. All cells in the column will happen to INITIALIZECELL, which is very similar to the itemcreated events directly using DataGrid. You can use it to manage cell content, such as setting Headertext, add the DropDownList control you will add data. I have added a handler to the cell's DataBinding event, which needs to take different processing based on whether the current is currently editing. Each system.web.ui.control has a DataBinding event. When the data is bind to the control, you can access the underlying data here, this example is the TableCell object in the DataGrid.

    Public Overrides Sub InitializeCell (ByVal cell As TableCell, _ ByVal columnIndex As Integer, _ ByVal itemType As ListItemType) MyBase.InitializeCell (cell, columnIndex, itemType) Select Case itemType Case ListItemType.Header cell.Text = HeaderText Case ListItemType.Item, ListItemType .AlternatingItem AddHandler cell.DataBinding, AddressOf ItemDataBinding Case ListItemType.EditItem AddHandler cell.DataBinding, AddressOf EditItemDataBinding Dim DDL as New DropDownList cell.Controls.Add (DDL) End Select End Sub followed ItemDataBinding routine, when the Item of Datagrid The routine will be triggered when the AlternatingItem is data. You need to reference back to TableCell, you can directly convert the "sender" object that is passed to the event, and then use the Tablecell's NamingContainer attribute to reference the current DataGridItem. This can only display the contents of Datafield in plain text format, just like displayed in BoundColumn. Finally, if the user specified by the user does not exist, I will display more friendly error messages for the user, not only the "index beyond range".

    Private Sub ItemDataBinding (ByVal sender As Object, ByVal e As EventArgs) Dim cell As TableCell = CType (sender, TableCell) Dim DGI As DataGridItem = CType (cell.NamingContainer, DataGridItem) Try cell.Text = DGI.DataItem (DataField) Catch Rangeex As IndexOutofrangeException Throw New Exception ("Specified Datafield Was Not Found.") Catch Otherex As Exception Throw new exception (Otherex.innerexception.toString) End Try End Sub

    Next, write the code of the EditItemDataBinding event. When a row enters the Edit mode, the event will be triggered on our custom column cell. Retrieve the current cell again and insert the DROPDOWNLIST control when the Initializecell method is called. Add an empty project in DropDown to the first option, if the current data in the column does not match any items you choose from the DataSource collection and placed in the list, select this option.

    Then, you need to determine the type of the incoming collection. In this case, I will handle two cases: Passing a set of strings through ArrayList, or DataView in the data table, which is constructed by the DATAROWVIEW project. For string data, I will enter a new ListItem and set the value of the pull-up item and the text. Since both cases are the same, only the text is required here. But I will select the corresponding item to make a selection according to the value so as to be consistent with the next example, and the next example will set a separate value attribute. For the DataRowView project, in the previous example, DataRowViewInstance ("FieldName

    ") Returns an object indicating data in the field. You can search DataTextField and Data using the same method.

    Valuefields needed.

    Finally, some exceptions are throwing with common errors encountered when the developer uses columns, such as send invalid field names to the DataField property, or incompatible DataSource type. I have made hardcodes to the abnormal message to be popped, but I hope that you save these messages to a more configurable location in the actual application. For example, if you want to use your application within a global scale, you can save it to your web.config file or resource file. Similarly, you don't have to throw "Data Datafield" exceptions again, because it may have been captured in the ItemDataBinding event before the DataGrid is placed in the "Edit" mode.

    Private Sub EditItemDataBinding (ByVal sender As Object, _ByVal e As EventArgs) Dim cell As TableCell = CType (sender, TableCell) Dim DDL As DropDownList = _CType (cell.Controls (0), DropDownList) Dim DataSourceItem As Object Dim item As ListItem Dim DGI As DataGridItem 'add an empty first option DDL.Items.Add (New ListItem ( "")) For Each DataSourceItem In DataSource Select Case DataSourceItem.GetType.ToString Case "System.String"' is applied to ArrayList exemplary item = New ListItem ( DataSourceItem, DataSourceItem) DDL.Items.Add (item) Case "System.Data.DataRowView" Dim DRV As DataRowView = _ CType (DataSourceItem, DataRowView) item = new_ ListItem (DRV (DataTextField), DRV (DatavalueField)) DDL.Items .Add (item) Case ELS e Throw New Exception ( "Invalid DataSource type.") End Select Next Try DGI = CType (cell.NamingContainer, DataGridItem) item = DDL.Items.FindByvalue (DGI.DataItem (DataField)) Catch RangeEx As IndexOutOfRangeException Throw New Exception ( " Specified Datafield Was Not Found. ") Catch Otherex As Exception Throw new exception (Otherex.innerexception.tostring) End Try if not item is nothing kiln = truend SUB Using DropdownColumn

    The above is all the code you need to create a DROPDOWNCOLUMN class. Let's take a look at how to use the control in your application. If you are studying at home, but have not yet started, please compile the namespace created above to MyCustomColumn.dll and copy it to the / bin folder of the application you want to experiment. In this example, I created a new web application UsecustomColumn, and add a reference to my / bin directory mycustomcolumn.dll. At the top of the ASPX file, add @register instruction: <% @ register tagprefix = "dgg" namespace = "mycustomcolumn" assembly = "mycustomcolumn"%>

    Note that the new DataGrid column type does not appear in the Visual Studio .Net property generator for DataGrid, so you need to enter the HTML view and add a column declaration. Make sure the DataGrid declaration is located in a group of

    "Server

    "> ... tags, these tags are used to deal with the rest of the postback.aspx files as follows:

    ! <% @ Page Language = "vb" AutoEventWireup = "false" Codebehind = "WebForm1.aspx.vb" Inherits = "UseCustomColumn.WebForm1" Trace = "False" Debug = "True"%> Webform1 </ title> <link rel =" stylesheet "type =" text / css "href =" styles.css "> < meta name = "GENERATOR" content = "Microsoft Visual Studio.NET 7.0"> <meta name = "CODE_LANGUAGE" content = "Visual Basic 7.0"> <meta name = "vs_defaultClientscript" content = "Javascript"> <meta name = " vs_targetschema "content =" http://schemas.microsoft.com/intellisense/ie5 "> </ head> <body> <form id =" form1 "method =" post "runat =" server "> <ask: dataGrid ID = "DataGrid1" runat = "server" CssClass = "grid" AutoGenerateColumns = "False"> <Columns> <asp: EditCommandColumn EditText = "Edit" CancelText = "Cancel" UpdateText = "Update" /> <asp: BoundColumn DataField = "ORDERID" readonly = "True" Headertext = "Order ID" /> <ask: BoundColumn Datafield = "ShipName" Headertext = "ship to" readonly = "true" /> <ask: boundcolumn datafield = "</p> <p>ShipCountry "Headertext =" Country "readonly =" true "/> <dgg: DropdownColumn Datafield =" Shipvia "Headertext =" Ship method "/> </ color> </ asp: datagrid> </ form> </ body> < / Html> DataGrid is bound to the ORDERS table of the Northwind example, custom DropDownColumn is bound to the shipvia column. Now I only set the DataField property, because I just bind to a simple ArrayList, don't need DataTextField and Data</p> <p>Valuefield property. If you have a predefined constant list or you need a quick setup option, the ArrayList option is the simplest. Datasource DataSource DataSource is set in the code, first reference DropDownColumn:</p> <p>Dim DDC As MyCustomColumn.DropDownColumnDDC = CType (DataGrid1.Columns (4), MyCustomColumn.DropDownColumn) Dim AL As New ArrayList AL.Add ( "Shipping Company A") AL.Add ( "Shipping Company B") AL.Add ( " Shipping Company C ") DDC.DataSource = Al</p> <p>Below is the result of run this code:</p> <p>Figure 3: Using ArrayList</p> <p>Next, I need to convert the example to use the active table in the database. Shipvia is the foreign key to lookup Table Shippers, I specify it as Datasource for DROPDOWNCOLUMN. I also need to change the DROPDOWNCOLUMN statement to include DataTextField and Data matching the corresponding fields in the Shippers table.</p> <p>Valuefield Name:</p> <p><DGG: DropDownColumn Datafield = "Shipvia" DataTextField = "CompanyName" DataValuefield = "ShipperId" Headertext = "Ship method" /></p> <p>Then bind two ORDERS tables to the DataGrid, bind the shippers table to the custom column:</p> <p>Dim SQL As String = "SELECT OrderID, ShipName, ShipCountry, ShipVia FROM Orders" Dim DA As SqlDataAdapter = New SqlDataAdapter (SQL, ConnStr) Dim DS As New DataSet DA.Fill (DS, "Orders") 'Dim Cmd As SqlCommand = new SqlCommand (SQL, Conn) 'Conn.Open ()' DataGrid1.DataSource = _ cmd.ExecuteReader (CommandBehavior.CloseConnection) DataGrid1.DataSource = dS.Tables ( "Orders"). DefaultView SQL = "SELECT ShipperID, CompanyName" & _ "FROM Shippers ORDER BY ShipperID" DA.SelectCommand.CommandText = SQL dA.Fill (DS, "Shippers") DDC.DataSource = dS.Tables ( "Shippers"). DefaultView DataGrid1.DataBind () DataGridColumn using activity data, according to The value (1, 2 or 3) in the ORDERS table automatically selects the correct project, as shown below:</p> <p>Figure 4: Retrieve data from the database</p> <p>The last step using DropDownColumn is to retrieve the selected value to pass back the database update. To do this, just reference the DropDownList control in the cell, and determine its SELECTED</p> <p>Value Attribute:</p> <p>Private Sub DataGrid1_UpdateCommand (_ ByVal source As Object, _ ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _ Handles DataGrid1.UpdateCommand Dim CustomDDL As DropDownList = _CType (e.Item.Cells (4) .Controls (0), DropDownList) Dim NewShip As Integer = CustomDDL.Selectedvalue Dim OrderID As Integer = Int32.Parse (e.Item.Cells (1) .Text) Dim SQL As String = _ "UPDATE Orders SET ShipVia = @ Ship WHERE OrderID = @ ID" Dim Conn As SqlConnection = New SqlConnection (ConnStr) Dim Cmd As New SqlCommand (SQL, Conn) cmd.Parameters.Add (New SqlParameter ( "@ Ship", NewShip)) cmd.Parameters.Add (New SqlParameter ( "@ ID" , OrderID) Conn.open () cmd.executenonquery () ConnononQuery () CONN.Close () DataGrid1.edititeMindex = -1 bindgrid () End Sub Summary</p> <p>The above is an overview of how to create a new type with DataGridColumn for the parent type, how to make data bindings and how to apply it to the actual application. This is just an example of reusable DataGrid columns, so you need to check your own application to determine which repetition features can be encapsulated in their own custom DataGrid columns. You can develop your own columns to resolve common problems (for example, display DropDownList in columns) or meet your company's special needs. You also don't have to stick to this example. You can include a ASP.NET control in the custom column, you can write more complex structures, such as nesting a series of controls, third-party content, or the entire DataGrid control to column, Performing multi-layer information. In short, you can give full play to your imagination.</p> <p>5 built-in column types are very useful, which meets the needs of most of the cases that use the DataGrid control. There is no development of your own control now, just put some meaningful content in the templateColumn. Creating a custom column allows you to break through these restrictions, add a rich functionality in your DataGrid application.</p> <p>About the Author</p> <p>"DataGrid Girl" Marcie Robillard is the best ASP.NET expert in Microsoft, she is an independent ASP.NET consultant and trainer. ASP.NET DATAGRID is her profession, she also created a Web site DataGridgirl.com for this purpose. You can find the link of the excellent DataGrid article from this site, book review of DataGrid content, and increasing DataGrid FAQ. Marcie also spent a lot of time to host the ASP.NET Forum, answering questions about DataGrid. Marcie current tasks are to guide our company to develop their own .NET technology. If your organization needs this expertise or training, please contact marcie@dataGridgirl.com. Reference site:</p> <p>Metabuilders.com. Free custom DataGrid column, including source code (C #).</p> <p>DataGridgirl.com. Various resources for DataGrid.</p> <p>Scott Mitchell's "ASP.NET DATA Web Controls", SAMS published in 2003. ISBN 0672325012</p> <p><script language = javaScript></p> <p></ script></p></div><div class="text-center mt-3 text-grey"> 转载请注明原文地址:https://www.9cbs.com/read-105766.html</div><div class="plugin d-flex justify-content-center mt-3"></div><hr><div class="row"><div class="col-lg-12 text-muted mt-2"><i class="icon-tags mr-2"></i><span class="badge border border-secondary mr-2"><h2 class="h6 mb-0 small"><a class="text-secondary" href="tag-2.html">9cbs</a></h2></span></div></div></div></div><div class="card card-postlist border-white shadow"><div class="card-body"><div class="card-title"><div class="d-flex justify-content-between"><div><b>New Post</b>(<span class="posts">0</span>) </div><div></div></div></div><ul class="postlist list-unstyled"> </ul></div></div><div class="d-none threadlist"><input type="checkbox" name="modtid" value="105766" checked /></div></div></div></div></div><footer class="text-muted small bg-dark py-4 mt-3" id="footer"><div class="container"><div class="row"><div class="col">CopyRight © 2020 All Rights Reserved </div><div class="col text-right">Processed: <b>0.037</b>, SQL: <b>9</b></div></div></div></footer><script src="./lang/en-us/lang.js?2.2.0"></script><script src="view/js/jquery.min.js?2.2.0"></script><script src="view/js/popper.min.js?2.2.0"></script><script src="view/js/bootstrap.min.js?2.2.0"></script><script src="view/js/xiuno.js?2.2.0"></script><script src="view/js/bootstrap-plugin.js?2.2.0"></script><script src="view/js/async.min.js?2.2.0"></script><script src="view/js/form.js?2.2.0"></script><script> var debug = DEBUG = 0; var url_rewrite_on = 1; var url_path = './'; var forumarr = {"1":"Tech"}; var fid = 1; var uid = 0; var gid = 0; xn.options.water_image_url = 'view/img/water-small.png'; </script><script src="view/js/wellcms.js?2.2.0"></script><a class="scroll-to-top rounded" href="javascript:void(0);"><i class="icon-angle-up"></i></a><a class="scroll-to-bottom rounded" href="javascript:void(0);" style="display: inline;"><i class="icon-angle-down"></i></a></body></html><script> var forum_url = 'list-1.html'; var safe_token = 'Cte_2F0Dq3I4jTOIQIyOpSyximQI_2FDnA7EpmYfPVRCYhP7xQrPeU5YFtYcAd_2FfV0Fpzap1d3ZshijC_2B9peUjoCPQ_3D_3D'; var body = $('body'); body.on('submit', '#form', function() { var jthis = $(this); var jsubmit = jthis.find('#submit'); jthis.reset(); jsubmit.button('loading'); var postdata = jthis.serializeObject(); $.xpost(jthis.attr('action'), postdata, function(code, message) { if(code == 0) { location.reload(); } else { $.alert(message); jsubmit.button('reset'); } }); return false; }); function resize_image() { var jmessagelist = $('div.message'); var first_width = jmessagelist.width(); jmessagelist.each(function() { var jdiv = $(this); var maxwidth = jdiv.attr('isfirst') ? first_width : jdiv.width(); var jmessage_width = Math.min(jdiv.width(), maxwidth); jdiv.find('img, embed, iframe, video').each(function() { var jimg = $(this); var img_width = this.org_width; var img_height = this.org_height; if(!img_width) { var img_width = jimg.attr('width'); var img_height = jimg.attr('height'); this.org_width = img_width; this.org_height = img_height; } if(img_width > jmessage_width) { if(this.tagName == 'IMG') { jimg.width(jmessage_width); jimg.css('height', 'auto'); jimg.css('cursor', 'pointer'); jimg.on('click', function() { }); } else { jimg.width(jmessage_width); var height = (img_height / img_width) * jimg.width(); jimg.height(height); } } }); }); } function resize_table() { $('div.message').each(function() { var jdiv = $(this); jdiv.find('table').addClass('table').wrap('<div class="table-responsive"></div>'); }); } $(function() { resize_image(); resize_table(); $(window).on('resize', resize_image); }); var jmessage = $('#message'); jmessage.on('focus', function() {if(jmessage.t) { clearTimeout(jmessage.t); jmessage.t = null; } jmessage.css('height', '6rem'); }); jmessage.on('blur', function() {jmessage.t = setTimeout(function() { jmessage.css('height', '2.5rem');}, 1000); }); $('#nav li[data-active="fid-1"]').addClass('active'); </script>