C# dynamic GridView/DataTable set up

2019-04-13 02:02发布

问题:

I'm working on a table that's going to be completely dynamic for a company I work for. I hacked my way around getting the GridView to work the way I wanted.

But they changed it up a bit...

  • I have a GridView.
  • Every single column and row is going to be a TextBox that you put numbers into.
  • You start out with 1 column and you can add multiple ones at the push of a button.
  • There's a fixed amount of rows (23).

I tried adding the textbox to the data row like below, but it just shows the string of the namespaces that TextBox is in. What should I do? I'd like to avoid any ASP stuff, I don't have the slightest clue what it's doing

Here is what I have done so far.

DataTable dt = new DataTable();
DataColumn dc = new DataColumn("MICRONS",typeof(TextBox));

dt.Columns.Add(dc);

for (int i = 0; i < 23; ++i)
{
    TextBox tb = new TextBox();
    DataRow row = dt.NewRow();

    row["MICRONS"] = tb;
    dt.Rows.Add(row);
}
foreach (DataColumn col in dt.Columns)
{
    BoundField bField = new BoundField();
    bField.DataField = col.ColumnName;
    bField.HeaderText = col.ColumnName;
    GridView1.Columns.Add(bField);
} 

GridView1.DataSource = dt;

回答1:

ok according to your question and my sense it seems you want to add textbox dynamically. if so then create a class and write below code in that class:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.Collections;
/// <summary>
/// Summary description for DynamicTemplate
/// </summary>
public class DynamicTemplate : System.Web.UI.ITemplate
{
public String TableName { get; set; }

System.Web.UI.WebControls.ListItemType templateType;
System.Collections.Hashtable htControls = new System.Collections.Hashtable();
System.Collections.Hashtable htBindPropertiesNames = new System.Collections.Hashtable();
System.Collections.Hashtable htBindExpression = new System.Collections.Hashtable();

public DynamicTemplate(System.Web.UI.WebControls.ListItemType type)
{
    templateType = type;
}

public void AddControl(WebControl wbControl, String BindPropertyName, String BindExpression)
{
    htControls.Add(htControls.Count, wbControl);
    htBindPropertiesNames.Add(htBindPropertiesNames.Count, BindPropertyName);
    htBindExpression.Add(htBindExpression.Count, BindExpression);
}

public void AddControl(HtmlControl wbControl, String BindPropertyName, String BindExpression)
{
    htControls.Add(htControls.Count, wbControl);
    htBindPropertiesNames.Add(htBindPropertiesNames.Count, BindPropertyName);
    htBindExpression.Add(htBindExpression.Count, BindExpression);
}

public void InstantiateIn(System.Web.UI.Control container)
{
    PlaceHolder ph = new PlaceHolder();

    for (int i = 0; i < htControls.Count; i++)
    {
        //clone control 
        Control cntrl = CloneControl((Control)htControls[i]);

        switch (templateType)
        {
            case ListItemType.Header:
                break;
            case ListItemType.Item:
                ph.Controls.Add(cntrl);
                break;
            case ListItemType.AlternatingItem:
                ph.Controls.Add(cntrl);
                ph.DataBinding += new EventHandler(Item_DataBinding);
                break;
            case ListItemType.Footer:
                break;
        }
    }
    ph.DataBinding += new EventHandler(Item_DataBinding);
    container.Controls.Add(ph);
}
public void Item_DataBinding(object sender, System.EventArgs e)
{
    PlaceHolder ph = (PlaceHolder)sender;
    GridViewRow ri = (GridViewRow)ph.NamingContainer;
    for (int i = 0; i < htControls.Count; i++)
    {
        if (htBindPropertiesNames[i].ToString().Length > 0)
        {
            Control tmpCtrl = (Control)htControls[i];

            String item1Value = GetType(htBindExpression[i].ToString(), ri);

            //Guid value = new Guid(DataBinder.Eval(ri.DataItem, htBindExpression[i].ToString()).ToString());
            //String valueString = value.ToString();
            //item1Value = item1Value1.ToString();

            Control ctrl = ph.FindControl(tmpCtrl.ID);
            Type t = ctrl.GetType();
            System.Reflection.PropertyInfo pi = t.GetProperty(htBindPropertiesNames[i].ToString());
            if (pi != null)
            {
                pi.SetValue(ctrl, item1Value.ToString(), null);
            }
        }
    }
}

private String GetType(String ColumnName, GridViewRow row)
{
    String Result = "";
    clsSearch obj = new clsSearch();
    // i have set up the table name static as now we require to make search working for macintosh project only.
    // as per rakesh sir directed.
    Int32 Type = obj.GetNumberForDataTypeofColumn("tblProperty", ColumnName);
    switch (Type)
    {
        case 1:
            DateTime dtvalue = (DateTime)DataBinder.Eval(row.DataItem, ColumnName);
            Result = dtvalue.ToString();
            break;
        case 2:
            String svalue = (String)DataBinder.Eval(row.DataItem, ColumnName);
            Result = svalue;
            break;
        case 3:

            break;
        case 4:
            Int32 ivalue = (Int32)DataBinder.Eval(row.DataItem, ColumnName);
            Result = ivalue.ToString();
            break;
        case 5:
            Guid gvalue = (Guid)DataBinder.Eval(row.DataItem, ColumnName);
            Result = gvalue.ToString();
            break;
    }

    return Result;
}

private Control CloneControl(System.Web.UI.Control src_ctl)
{
    Type t = src_ctl.GetType();
    Object obj = Activator.CreateInstance(t);
    Control dst_ctl = (Control)obj;
    PropertyDescriptorCollection src_pdc = TypeDescriptor.GetProperties(src_ctl);
    PropertyDescriptorCollection dst_pdc = TypeDescriptor.GetProperties(dst_ctl);

    for (int i = 0; i < src_pdc.Count; i++)
    {
        if (src_pdc[i].Attributes.Contains(DesignerSerializationVisibilityAttribute.Content))
        {
            object collection_val = src_pdc[i].GetValue(src_ctl);
            if ((collection_val is IList) == true)
            {
                foreach (object child in (IList)collection_val)
                {
                    Control new_child = CloneControl(child as Control);
                    object dst_collection_val = dst_pdc[i].GetValue(dst_ctl);
                    ((IList)dst_collection_val).Add(new_child);
                }
            }
        }
        else
        {
            dst_pdc[src_pdc[i].Name].SetValue(dst_ctl, src_pdc[i].GetValue(src_ctl));
        }
    }

    return dst_ctl;

 }
}

ok now come to the method where you are binding the grid.before you bind the Grid means before yo specify the DataSource to Grid use the below code to add textboxes to according to your requirement. i am adding one for example.

    TemplateField t = new TemplateField();
    DynamicTemplate mt = new DynamicTemplate(ListItemType.Item);

    TextBox ibtnEdit = new TextBox();
    ibtnEdit.ID = "btnEdit";
    ibtnEdit.CssClass = "EditButton";
    ibtnEdit.ToolTip = "Name";
    mt.AddControl(ibtnEdit, "AlternateText", "Id");
    t.ItemTemplate = mt;
    t.HeaderText = "Activity";
    t.HeaderStyle.HorizontalAlign = HorizontalAlign.Left;
    GridView1.Columns.Add(t);
    GridView1.DataSource = datatable;
    GridView1.DataBind();

that's it.