Search code examples
c#asp.netdetailsview

DetailsView in ASP.Net - How to add another column on the side/add a control in each row?


I have a DetailsView control on my page used to edit various fields of a record, which works well in this respect.

I am looking for a way to add one column (and if that works, why not more) to the right, which will be absolutely read-only, to show the same fields of another record for comparison purposes.

I am aware there is no obvious way to do such thing out of the box with DetailsView. I have looked into other controls (transposed GridView, someone recommended FormView, ListView), but nothing satisfies. I have some very special data binding setup using the DetailsView and I can't get out of it without losing some features.

Anyone on how to "hack in" additional columns (for display only) on a DetailsView ?


Solution

  • The solution I have now, is to use a second DetailsView, with Visible set to False in my aspx. In the code, I make sure to DataBind the hidden DetailsView that hosts the data for my third column first, then the initial DetailsView named ItemDetails.

    And in the item created event, I pass to a third column the html rendering of my hidden controls (in the last code block) :

    protected void ItemDetails_ItemCreated(object sender, EventArgs e)
            {
                if (dataItem2 != null) //compare enabled
                {
                    var headerRow = ((DetailsView)sender).HeaderRow;
                    var headerL = new Label();
                    headerL.Text = header2;
                    headerL.Style.Add("font-weight", "bold");
                    var headerCell = new TableCell();
                    headerCell.Controls.Add(headerL);
                    headerCell.Style.Add("text-align", "right");
                    headerRow.Cells.Add(headerCell);
                    if (string.IsNullOrEmpty(header1) && string.IsNullOrEmpty(header2)) ((DetailsView)sender).HeaderRow.Visible = false;
                }
                else
                {
                    ((DetailsView)sender).HeaderRow.Visible = false;
                }
                foreach (DetailsViewRow r in ItemDetails.Rows)
                {
                    if (r.RowType == DataControlRowType.DataRow)
                    {
                        // Assume the first cell is a header cell        
                        var dataCell = (DataControlFieldCell)r.Cells[0];
                        string dataFieldName = null;
                        if (dataCell.ContainingField is CustomBoundField) dataFieldName = ((CustomBoundField)dataCell.ContainingField).GetDataFieldName();
                        else if (dataCell.ContainingField is BoundField) dataFieldName = ((BoundField)dataCell.ContainingField).DataField;
                        if (dataItem2 != null) //compare enabled
                        {
                            if (!string.IsNullOrEmpty(dataFieldName)) //it's a field, copy boundField from hidden DetailsView
                            {
                                var ct = new TableCell();
                                var text = new StringWriter();
                                var html = new HtmlTextWriter(text);
                                dict[dataFieldName].RenderControl(html);
                                ct.Text = text.ToString().Replace("<td>", String.Empty).Replace("</td>", String.Empty);
                                r.Cells.Add(ct);
                            }
                        }
                    }
                } 
            }