【问题标题】:Remove TemplateField during page load or before databind在页面加载期间或数据绑定之前删除 TemplateField
【发布时间】:2015-04-23 08:51:36
【问题描述】:

我想在页面加载期间或数据绑定到 GridView 之前从 gridview 中删除模板字段。我有 2 个用于检索数据的数据源。从数据源之一检索的数据没有 ExpireDate 和 ExpireDays 列。

因此,如果从没有这两个字段的数据源填充 GridView,我想删除与 Ex​​pireDate 和 ExpireDays 对应的模板字段。

将可见性设置为 false 仍然会出现 DataRowView 不包含属性名称 ExpireDate 和 ExpireDays 的错误。

标记

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound">
 <Columns>
    <asp:BoundField DataField="ID" HeaderText="No."/>
    <asp:BoundField DataField="Name" HeaderText="Name"/>
    <asp:BoundField DataField="CourseName" HeaderText="Course Enroll" />
    <asp:BoundField DataField="SubMember" HeaderText="ChildMember" />
    <asp:TemplateField HeaderText="Expiry Days">
        <ItemStyle HorizontalAlign="Center" />
        <ItemTemplate>
            <asp:Label runat="server" ID="expDsL" Text=' <%# Eval("ExpiryDays") %>'>
            </asp:Label>
        </ItemTemplate>
        </asp:TemplateField>
    <asp:TemplateField HeaderText="Expiry On">
        <ItemStyle HorizontalAlign="Center" />
            <ItemTemplate>
            <asp:Label runat="server" ID="expDeL" Text=' <%# Eval("ExpiryDate") %>'>
            </asp:Label>
       </ItemTemplate>
   </asp:TemplateField>
   <asp:TemplateField HeaderText="Function">
           <ItemStyle HorizontalAlign="Center" Width="100px"></ItemStyle>
           <ItemTemplate>
                  <asp:ImageButton ImageUrl="~/Images/editB.gif" ID="btnEdit" runat="server" ToolTip="Edit" CommandName="Edit"  CommandArgument='<%# Eval("ID") %>' />
                  <asp:ImageButton ImageUrl="~/Images/delB.gif" ID="btnDelete" runat="server" ToolTip="Delete" CommandName="Delete"  CommandArgument='<%# Eval("ID") %>' />
          </ItemTemplate>
   </asp:TemplateField>
 </Columns>
</asp:GridView>

代码背后

protected void Page_Load(object sender, EventArgs e)
{
     if(Class.ToLower() != "classAA")
     { 
        // using naveen answer can remove the column.
        var expiryDateF = ((DataControlField)GridView1.Columns.Cast<DataControlField>().Where(fid => fid.HeaderText == "Expiry Days").SingleOrDefault());
        var expiryDaysF = ((DataControlField)GridView1.Columns.Cast<DataControlField>().Where(fid => fid.HeaderText == "Expiry On").SingleOrDefault());

        if (expiryDateF != null)
        {
            GridView1.Columns.Remove(expiryDateF);
        }

        if (expiryDaysF != null)
        {
            GridView1.Columns.Remove(expiryDaysF);
        }
     } 

    if(!this.IsPostBack)
    {
         BindData();
    }
}

protected void SaveMember(object sender, EventArgs e)
{
    //getting member information and perform checking.

    bool success = dbbb.AddMem(memberdetails);
    if(success == true)
    {
        BindData();
    }
    else
    {
         //prompt fail message.
    }
}

protected void BindData()
{
    DataTable dt = dbbb.RetrieveList(); 
    if(dt != null)
    {
         GridView1.DataSource = dt;
         GridView1.DataBind();
    }
}

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if(e.Row.RowType == DataControlRowType.DataRow)
    {
        ImageButton btnDel = (ImageButton)e.Row.FindControl("btnDelete");
        btnDel.Attributes.Add("onclick", "return confirm('Are you sure you want to delete this member?')");
    }
}

如何删除该列?

【问题讨论】:

    标签: asp.net gridview


    【解决方案1】:

    两种方法来实现这一点

    方法 1 - 按索引删除

    if(!table.Columns.Contains("CustomerID1"))
    {
        //seven is the column index here. ie, 8th column
        CustomersGrid.Columns.RemoveAt(7);
    }
    

    方法 2 - 使用列标题文本删除

    var expiryDateField= ((DataControlField)CustomersGrid.Columns
            .Cast<DataControlField>()
            .Where(fld => fld.HeaderText == "Expiry Date")
            .SingleOrDefault());
    if(expiryDateField != null)
    {
        CustomersGrid.Columns.Remove(expiryDateField);
    }
    

    请不要这样

    1. CustomersGrid 是此处asp:GridView 的名称。
    2. tableDataTable,充当 DataSourceGridView
    3. 代码应该在GridViewDataBind之前调用

    【讨论】:

    • 方法 2 成功删除到期日和到期日。但是,在我尝试添加新成员、触发 SaveMember 然后再次绑定最新数据后,又出现了另一个问题。在 RowDataBound 期间,imagebutton btnDelete 变为空值。页面加载时没有问题。如果我在 .aspx 中注释到期日和到期日列并删除方法 2,则在 RowDataBound 期间它没有问题,并且可以找到 btnDelete。方法2会不会导致gridview中的ImageButton丢失?
    • GridView1 中的所有 itemTemplate 都将丢失,而不仅仅是 btnDelete。
    • 解决了,如果gridview有templatefield需要关闭ViewState。谢谢。
    • 将 Gridview 的 ViewState 设置为 false 确实有助于保留 itemtemplate 并且 Save 方法可以正常工作,但是 imagebutton 不能再进行回发以触发 OnRowCommand 中的删除或编辑。任何想法保留模板字段,允许回发和图像按钮仍然可以触发?
    【解决方案2】:

    附加到网格的rowDataBound事件,可以动态设置。

    您必须知道要隐藏的字段的数据源名称, 例如,单元格的 headertext 是“SomeHeader”,但该单元格的数据绑定字段名称是

    “其他名字”

    然后你必须像这样检查它(通过 GetColumnIndexByName 调试)和 检查

    的值

    ((BoundField)cell.ContainingField).DataField

    int GetColumnIndexByName(GridViewRow row, string columnName)
    {
        int columnIndex = 0;
        foreach (DataControlFieldCell cell in row.Cells)
        {
            if (cell.ContainingField is BoundField)
                if (((BoundField)cell.ContainingField).DataField.Equals(columnName))
                    break;
            columnIndex++; // keep adding 1 while we don't have the correct name
        }
        return columnIndex;
    }
    
    remember that the code above will use a BoundField... then use it like:
    
    protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            int index = GetColumnIndexByName(e.Row, "SomeOtherName");
            string columnValue = e.Row.Cells[index].Text;
        }
    }
    

    【讨论】:

    • 抱歉没有解释清楚。 gridview 中的templatefield 更多,而不仅仅是提到的2 个,是否可以通过标题文本检索所需的索引?
    • 使可见性为假无济于事。仍然错误说“System.Data.DataRowView”不包含名为“ExpiryDays”的属性。
    • 还有把你绑定到网格的数据贴出来,我想看看它长什么样子,还有你怎么绑定的。
    猜你喜欢
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多