asp.net 如何绑定gridview按钮点击作为空网格是绑定回发

qgelzfjb  于 2023-07-01  发布在  .NET
关注(0)|答案(1)|浏览(126)

我已经使用gridview的形式,我在运行时根据一些条件和按钮单击事件删除列,我通过填充数据表绑定gridview,但它只显示空网格和所有空行。
Gridview代码:

<asp:GridView ID="AccessControlGrid" GridLines="None" CssClass="wk-TableBorder" runat="server" 
                                        AutoGenerateColumns = "false" ShowHeaderWhenEmpty="True" EmptyDataText="There are no records.">
<Columns>
    <asp:TemplateField HeaderText="User No" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:Label ID="lblUserNo" runat="server" Text='<%# Eval("UserNo") %>'></asp:Label>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="User Name" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:Label ID="lbl_UserName" runat="server" Text='<%# Eval("UserName") %>'></asp:Label>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Submit Original" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:CheckBox ID="chk_FS_IsOriginal" AutoPostback = "True" OnCheckedChanged="Chk_CheckedChanged" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsOriginal")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Submit Continuation" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:CheckBox ID="chk_FS_IsContinuation" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsContinuation")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Submit Debtor Amendment" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:CheckBox ID="chk_FS_IsDebtorAmendment" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsDebtorAmendment")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Submit Secured Party Amendment" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:CheckBox ID="chk_FS_IsSecPartyAmendment" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsSecPartyAmendment")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Submit Partial Assignment" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:CheckBox ID="chk_FS_IsPartialAssignment" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsPartialAssignment")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Submit Full Assignment" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:CheckBox ID="chk_FS_IsFullAssignment" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsFullAssignment")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Submit Termination" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:CheckBox ID="chk_FS_IsTermination" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsTermination")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Submit Collateral Amendment" HeaderStyle-CssClass="SpacerColumn gridheader1 GridColumnSpacing" ItemStyle-CssClass="GridColumnSpacing" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
        <ItemTemplate>
            <asp:CheckBox ID="chk_FS_IsCollateralAmendment" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsCollateralAmendment")) %>' />
        </ItemTemplate>
    </asp:TemplateField>
</Columns>
</asp:GridView>

在页面加载时,我只需要根据某些条件删除不需要的列,然后隐藏网格:

protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //This action will be performed once based on access type.
                AccessControlGridColumnAdjustment();
                AccessControlGrid.Visible = false;
            }
        }

最后,单击按钮,我必须填充并显示网格:

protected void ImgBtnGo_Click(object sender, EventArgs e)
        {
            if (returnTable == null)
                returnTable = new DataTable("AccessControl");

            CreateAccessControlDataTable(ref returnTable, hdnAccessType.Value);
            LoadData();
            PopulateDataTable(ref returnTable, accessControlResultSet, hdnAccessType.Value);
            AccessControlGrid.DataSource = returnTable;
            AccessControlGrid.DataBind();
            AccessControlGrid.Visible = true;
        }

在CreateAccessControlDataTable中,我只是根据一些条件创建Datatable的结构:

public DataTable CreateAccessControlDataTable(ref DataTable returnTable, string accessType)
        {
            try
            {
                #region Creating DataTable Schema for different access types
                switch (accessType)
                {
                    case "FS":
                        returnTable.Columns.Add(new DataColumn("UserNo"));
                        returnTable.Columns.Add(new DataColumn("UserName"));
                        returnTable.Columns.Add(new DataColumn("IsOriginal"));
                        returnTable.Columns.Add(new DataColumn("IsContinuation"));
                        returnTable.Columns.Add(new DataColumn("IsDebtorAmendment"));
                        returnTable.Columns.Add(new DataColumn("IsSecPartyAmendment"));
                        returnTable.Columns.Add(new DataColumn("IsPartialAssignment"));
                        returnTable.Columns.Add(new DataColumn("IsFullAssignment"));
                        returnTable.Columns.Add(new DataColumn("IsTermination"));
                        returnTable.Columns.Add(new DataColumn("IsCollateralAmendment"));
                        break;
                    case "IPF":
                        returnTable.Columns.Add(new DataColumn("UserNo"));
                        returnTable.Columns.Add(new DataColumn("UserName"));
                        returnTable.Columns.Add(new DataColumn("IsInPrepFilingDeletion"));
                        break;
                    case "FLD":
                        returnTable.Columns.Add(new DataColumn("UserNo"));
                        returnTable.Columns.Add(new DataColumn("UserName"));
                        returnTable.Columns.Add(new DataColumn("FloodStopAccess"));
                        returnTable.Columns.Add(new DataColumn("FloodReIssueAccess"));
                        returnTable.Columns.Add(new DataColumn("FloodLifeOfLoan"));
                        returnTable.Columns.Add(new DataColumn("FloodBasicCertificate"));
                        break;
                }
                #endregion
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
            }
            return returnTable;
        }

在LoadData()和PopulateDataTable()函数中,我只是用来自后端的值填充空的Datatable,这工作正常,但最后我得到了带有多个空行的空网格,如下所示:

我已经检查了多个线程在这里,但没有在我的情况下工作。
注意:如果我在里面做同样的事情- if(!IsPostback){}然后gridview正确加载,但我不必这样做,我必须在回发时基于搜索条件加载网格。

i7uaboj4

i7uaboj41#

因为我们使用模板化列(不是自动生成)。然后我们需要处理我们“要隐藏”的列。
这也表明,至少对于我们隐藏的那些列,我们不能在标记中真正使用绑定表达式,因为给定的数据源将没有这些列,并且它们将在绑定时失败。
因此,这表明我们希望控制这些隐藏/显示列的绑定,以及从GV中隐藏/删除的绑定。
我还发现,当我们开始做这些事情的时候,当我们有很多模板化控件的时候,我建议使用列表视图来代替网格视图。(有很多原因,一个网格视图简单的原因是,标记变得不那么“杂乱”了,因为每个控件(标准asp.net控件)不需要模板化的标记部分,然后在此之上,你需要一个“项目模板”(这变得太乱太快!).
然而,让我们把这些原因放在一边,坚持使用gv。
所以,有了网格视图,这是一个有点熊骑和驯服,但这似乎是最可行的。
注意:标记中的任何可选列都没有数据绑定表达式(如果缺少数据列,则会失败)。
所以,这个标记:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
            DataKeyNames="ID" Width="40%" GridLines="None"
            CssClass="table table-hover table-striped" OnRowDataBound="GridView1_RowDataBound">
            <Columns>
                <asp:TemplateField HeaderText="First">
                    <ItemTemplate>
                        <asp:Label ID="lblFirst" runat="server"></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Last">
                    <ItemTemplate>
                        <asp:Label ID="lblLast" runat="server"></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>

                <asp:TemplateField HeaderText="City">
                    <ItemTemplate>
                        <asp:Label ID="lblCity" runat="server"></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Hotel Name">
                    <ItemTemplate>
                        <asp:Label ID="lblHotel" runat="server" 
                            Text='<%# Eval("HotelName") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Description">
                    <ItemTemplate>
                        <asp:Label ID="lblDesc" runat="server" 
                            Text='<%# Eval("Description") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>

            </Columns>
        </asp:GridView>

下面是要加载的代码:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadGrid();
    }

    void LoadGrid()
    {
        string strSQL = @"SELECT ID, FirstName, LastName, City, HotelName, Description
                        FROM tblHotelsA
                        ORDER BY HotelName";

        GridView1.DataSource = General.MyRst(strSQL);
        GridView1.DataBind();
    }

以及查找可选字段的行数据绑定。

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // all columns that are "optional" go here
    List<string> sOptional = 
        new List<string> { "FirstName:lblFirst:0", "LastName:lblLast:1", "City:lblCity:2" };

    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        DataRowView gBindData = (DataRowView)e.Row.DataItem;

        foreach (string sHide in sOptional)
        {
            string sField = sHide.Split(':')[0];
            string sCtrl = sHide.Split(':')[1];
            int gCol = Convert.ToInt32(sHide.Split(':')[2]);

            if (gBindData.Row.Table.Columns.Contains(sField))
            {
                Label lbl = (Label)e.Row.FindControl(sCtrl);
                lbl.Text = gBindData["FirstName"].ToString();
            }
            else
            {
                GridView1.Columns[gCol].Visible = false;
            }
        }
    }
}

因此,我们定义了可选列。对于可选列,我们不使用数据绑定表达式(我们按照上面的代码绑定它们。上面的显示如下:

但是,上面的按钮点击有这样的代码:

protected void cmdTest_Click(object sender, EventArgs e)
    {

        string strSQL = @"SELECT ID, HotelName, Description
                        FROM tblHotelsA
                        ORDER BY HotelName";

        GridView1.DataSource = General.MyRst(strSQL);
        GridView1.DataBind();

    }

因此,我们在数据源中省略了3个可选列。
结果是这样的:

因此,通过上面的设计,我们只需要从数据源中删除我们不想要的列,其余的代码应该可以正常工作。

编辑:第一页加载时不加载GV

为了更完整,我们有这样的代码:
注意:对行数据绑定进行了一个小的编辑(当我们重新绑定gv时,我们必须重新启用(visible = true)。
所以,假设我们现在在开始时有这个标记:

<asp:Button ID="cmdTest" runat="server" Text="Load data" 
            CssClass="btn"
            OnClick="cmdTest_Click"
            />
        <asp:Button ID="cmdTest2" runat="server" Text="Load Different data" 
            style="margin-left:20px"
            CssClass="btn"
            OnClick="cmdTest2_Click"
            />
        <br />

gv标记不变。
现在的代码其实是一样的,是这样的:

protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void cmdTest_Click(object sender, EventArgs e)
    {
        LoadGrid();
    }

    protected void cmdTest2_Click(object sender, EventArgs e)
    {
        string strSQL = @"SELECT ID, HotelName, Description
                        FROM tblHotelsA
                        ORDER BY HotelName";

        GridView1.DataSource = General.MyRst(strSQL);
        GridView1.DataBind();
    }
    void LoadGrid()
    {
        string strSQL = @"SELECT ID, FirstName, LastName, City, HotelName, Description
                        FROM tblHotelsA
                        ORDER BY HotelName";

        GridView1.DataSource = General.MyRst(strSQL);
        GridView1.DataBind();
    }

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        // all columns that are "optional" go here
        List<string> sOptional = 
            new List<string> { "FirstName:lblFirst:0", "LastName:lblLast:1", "City:lblCity:2" };

        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            DataRowView gBindData = (DataRowView)e.Row.DataItem;

            foreach (string sHide in sOptional)
            {
                string sField = sHide.Split(':')[0];
                string sCtrl = sHide.Split(':')[1];
                int gCol = Convert.ToInt32(sHide.Split(':')[2]);

                if (gBindData.Row.Table.Columns.Contains(sField))
                {
                    Label lbl = (Label)e.Row.FindControl(sCtrl);
                    lbl.Text = gBindData["FirstName"].ToString();
                    GridView1.Columns[gCol].Visible = true;
                }
                else
                {
                    GridView1.Columns[gCol].Visible = false;
                }
            }
        }
    }

结果是这样的

仔细注意:即使你对gv进行了一次完全的重新绑定,隐藏或显示列也会持续。(因为你的专栏是模板化的)。
这意味着如果您隐藏了一个列(由于一个数据源绑定),那么当您重新绑定时,这些列将保留它们的设置!
解决方案:隐藏列的代码也必须取消隐藏列!
因此,这个问题与gv是否在页面加载时加载无关。当然,问题是,如果你绑定gv,隐藏一些列,然后重新绑定?这些列将保持隐藏状态,并且不会在重新绑定时重新设置其可见性。

编辑2:获取用户选中的行

假设网格中有一个复选框。它可以绑定到数据,或者不绑定,都无所谓。
因此,将此标记添加到gv。

<asp:TemplateField HeaderText="Active" ItemStyle-HorizontalAlign="Center">
                    <ItemTemplate>
                        <asp:CheckBox ID="chkActive" runat="server"
                            checked='<%# Eval("Active") %>'
                            />
                    </ItemTemplate>
                </asp:TemplateField>

我们的数据源现在包括Active列:
例如:

protected void cmdTest_Click(object sender, EventArgs e)
    {
        LoadGrid();
    }

    protected void cmdTest2_Click(object sender, EventArgs e)
    {
        string strSQL = @"SELECT ID, HotelName, Description, Active
                        FROM tblHotelsA
                        ORDER BY HotelName";

        GridView1.DataSource = General.MyRst(strSQL);
        GridView1.DataBind();
    }
    void LoadGrid()
    {
        string strSQL = @"SELECT ID, FirstName, LastName, City, HotelName, Description, Active
                        FROM tblHotelsA
                        ORDER BY HotelName";

        GridView1.DataSource = General.MyRst(strSQL);
        GridView1.DataBind();
    }

在GV之后,假设我们有这个:

<asp:Button ID="cmdShowChecked" runat="server" Text="Get Selected" 
            style="margin-left:20px"
            CssClass="btn"
            OnClick="cmdShowChecked_Click"
            />
        <asp:Label ID="lblSelected" runat="server" Text=""
            style="margin-left:30px">
        </asp:Label>

结果是这样的

gv后所选按钮单击的代码如下:

protected void cmdShowChecked_Click(object sender, EventArgs e)
    {
        string sPKIDSelected = "";
        foreach (GridViewRow gRow in GridView1.Rows)
        {
            string sPK = GridView1.DataKeys[gRow.RowIndex]["ID"].ToString();

            CheckBox chkSel = (CheckBox)gRow.FindControl("chkActive");
            if (chkSel.Checked)
            {
                if (sPKIDSelected != "")
                    sPKIDSelected += ",";

                sPKIDSelected += sPK;
            }
        }

        string strSQL = $@"SELECT * FROM tblHotelsA
                        WHERE ID IN ({sPKIDSelected})
                        ORDER BY HotelName";

        DataTable MySelected = General.MyRst(strSQL);

        lblSelected.Text =
            $"PK database ID selected = {sPKIDSelected} Rows Selected = {MySelected.Rows.Count}";
        // do whatever with selected data table items
    }

相关问题