【问题标题】:TextBox TextChanged Events and CheckBoc CheckedChanged Events not firing within a gridviewTextBox TextChanged 事件和 CheckBox CheckedChanged 事件未在网格视图中触发
【发布时间】:2010-01-08 12:28:35
【问题描述】:

所以我在 UpdatePanel 中有一个数据绑定网格视图。

这个想法是,用户可以更改网格视图中的数据,然后单击保存按钮来更新数据库中的数据。

但是,为了知道哪些行已更改,我有一个与每个文本框关联的 textChanged 事件,但该事件并未被触发。

这是 ASP 代码:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
    <span>To update your poducts simply change the details below and click Save...</span>
    <div class="ProductList">
        <asp:GridView ID="ProductList" runat="server" AllowPaging="True" AutoGenerateColumns="False"
            BackColor="#FFFBD6" BorderColor="#FFCC66" BorderStyle="None" BorderWidth="1px"
            CellPadding="3" OnPageIndexChanged="ProductList_PageIndexChanged" OnPageIndexChanging="ProductList_PageIndexChanging"
            PagerSettings-Mode="NumericFirstLast" PageSize="5">
            <FooterStyle BackColor="White" ForeColor="#990000" />
            <Columns>
                <asp:TemplateField HeaderText="Name">
                    <ItemTemplate>
                        <asp:TextBox ID="tbName" AutoPostBack="true" EnableViewState="true" runat="server" BorderStyle="None" OnTextChanged="TextBox_TextChanged"
                            Text='<%# Bind("productName") %>'></asp:TextBox>
                        <asp:HiddenField ID="HiddenField1" runat="server" Value='<%# Eval("productID") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Description">
                    <ItemTemplate>
                        <asp:TextBox ID="tbDesc" AutoPostBack="true" EnableViewState="true" runat="server" BorderStyle="None" OnTextChanged="TextBox_TextChanged"
                            Text='<%# Bind("productDesc") %>' TextMode="MultiLine"></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Price">
                    <ItemTemplate>
                        <asp:TextBox ID="tbPrice" AutoPostBack="true" EnableViewState="true" runat="server" BorderStyle="None" OnTextChanged="TextBox_TextChanged"
                            Text='<%# Bind("productPrice", "{0:C}") %>'></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Select">
                    <ItemTemplate>
                       <asp:CheckBox id="cbDelete"  AutoPostBack="true" EnableViewState="true" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <RowStyle ForeColor="#000066" />
            <SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="beige" ForeColor="#000066" HorizontalAlign="Left" />
            <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
        </asp:GridView>
    </div>
    <div class="ProductListButtons">
        <asp:ImageButton AlternateText="Add" ToolTip="Add New Product" Width="30px" Height="30px"
            ImageUrl="~/Images/Add.png" ID="AddBtn" runat="server" OnClick="AddBtn_Click" />
        <asp:ImageButton ID="DeleteBtn" runat="server" AlternateText="Delete" Height="30px"
            ImageUrl="~/Images/delete.png" ToolTip="Delete Selected" Width="30px" OnClick="DeleteBtn_Click" />
        <asp:ImageButton AlternateText="Save Changes" ToolTip="Save Changes" Width="30px"
            Height="30px" ImageUrl="~/Images/save-icon.png" ID="SaveBtn" runat="server" OnClick="SaveBtn_Click" />

    </div>
</ContentTemplate>
<Triggers>
    <asp:AsyncPostBackTrigger ControlID="ProductList" EventName="PageIndexChanged" />
    <asp:AsyncPostBackTrigger ControlID="DeleteBtn" EventName="Click" />
</Triggers>

这里是 C#:

using System;
using System.Data;
using BusinessLogicLayer; 
using DataAccessLayer.Objects;
using System.Web.UI.WebControls;

public partial class Controls_ProductList : System.Web.UI.UserControl
{
public int StallID { get; set; }
bool[] rowChanged;
bool[] rowDeleted;

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        StallID = Convert.ToInt16(ViewState["StallID"].ToString());
    }
    int totalRows = ProductList.Rows.Count;
    rowChanged = new bool[totalRows];
    rowDeleted = new bool[totalRows];
    BindList();
    ViewState.Add("StallID", StallID);
}

public void BindList()
{
    StallHandler handler = new StallHandler();
    DataTable productList = handler.GetProductsByID(StallID);
    ProductList.DataSource = productList;
    ProductList.DataBind();
}

protected void TextBox_TextChanged(object sender, EventArgs e)
{
    TextBox thisTextBox = (TextBox)sender;
    GridViewRow thisGridViewRow = (GridViewRow)thisTextBox.Parent.Parent;
    int row = thisGridViewRow.RowIndex;
    rowChanged[row] = true;
}

protected void cbDelete_CheckedChanged(object sender, EventArgs e)
{
    CheckBox thisCheckbox = (CheckBox)sender;
    GridViewRow thisGridViewRow = (GridViewRow)thisCheckbox.Parent.Parent;
    int row = thisGridViewRow.RowIndex;
    rowDeleted[row] = true;
}

protected void Page_PreRender(object sender, EventArgs e)
{
    if (Page.IsPostBack)
    {
        ProductList.DataBind();
    }
}

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

protected void ProductList_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    ProductList.PageIndex = e.NewPageIndex;
    ProductList.DataBind();
}

protected void AddBtn_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
    Response.Redirect("../StallHolder/AddProduct.aspx");
}

protected void DeleteBtn_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
    int totalRows = ProductList.Rows.Count;
    for (int r = 0; r < totalRows; r++)
    {
        if (rowDeleted[r])
        {
            GridViewRow thisGridViewRow = ProductList.Rows[r];
            HiddenField hf1 = (HiddenField)thisGridViewRow.FindControl("HiddenField1");
            string ID = hf1.Value;
            StallHandler handler = new StallHandler();
            handler.DeleteProduct(Convert.ToInt16(ID));
        }
    }       
    BindList();
}

protected void SaveBtn_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
    int totalRows = ProductList.Rows.Count;
    for (int r = 0; r < totalRows; r++)
    {
        if (rowChanged[r])
        {
            GridViewRow thisGridViewRow = ProductList.Rows[r];
            HiddenField hf1 = (HiddenField)thisGridViewRow.FindControl("HiddenField1");
            string ID = hf1.Value;
            TextBox tbName = (TextBox)thisGridViewRow.FindControl("tbName");
            string Name = tbName.Text;
            TextBox tbDesc = (TextBox)thisGridViewRow.FindControl("tbDesc");
            string Desc = tbDesc.Text;
            TextBox tbPrice = (TextBox)thisGridViewRow.FindControl("tbPrice");
            string Price = tbPrice.Text;
            //Code to update the database!
        }
    }
}

}

抱歉,代码很繁重,但我不知道我做错了什么或在哪里。

【问题讨论】:

  • 很抱歉提到可编辑的网格视图来自本教程wherecanibuyit.co.uk/ASP/fully_editable_gridview.html,但这并没有在更新面板中使用它
  • 所以如果你勾选了一些复选框,然后按下添加按钮,它不会在AddBtn_Click 之前调用cbDelete_CheckedChanged?对我来说似乎一切正常,让我构建一个示例项目并对其进行测试。
  • 没有复选框的想法是您可以选择产品,然后单击 DeleteBtn 删除它们,但是每当您单击复选框时 Checkbox_CheckedChanged 事件不会触发,因此我希望的产品删除不记录。
  • 我让你的代码在我的一个项目中工作。好吧,当我说工作时,我知道出了什么问题……我认为您对此考虑太多了,并且有一种更简单的方法可以做您想做的事。我会在几分钟内发布我的代码作为答案。

标签: c# asp.net


【解决方案1】:

好的,我在让它工作时发现了一些东西。看看代码sn-ps

平均售价:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <span>To update your poducts simply change the details below and click Save...</span>
        <div class="ProductList">
            <asp:GridView ID="ProductList" runat="server" AllowPaging="True" AutoGenerateColumns="False"
                BackColor="#FFFBD6" BorderColor="#FFCC66" BorderStyle="None" BorderWidth="1px"
                CellPadding="3" OnPageIndexChanged="ProductList_PageIndexChanged" OnPageIndexChanging="ProductList_PageIndexChanging"
                PagerSettings-Mode="NumericFirstLast" PageSize="5">
                <FooterStyle BackColor="White" ForeColor="#990000" />
                <Columns>
                    <asp:TemplateField HeaderText="Name">
                        <ItemTemplate>
                            <asp:TextBox ID="tbName" AutoPostBack="false" EnableViewState="true" runat="server" BorderStyle="None" OnTextChanged="TextBox_TextChanged"
                                Text='<%# Bind("productName") %>'></asp:TextBox>
                            <asp:HiddenField ID="HiddenField1" runat="server" Value='<%# Eval("productID") %>' />
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Description">
                        <ItemTemplate>
                            <asp:TextBox ID="tbDesc" AutoPostBack="false" EnableViewState="true" runat="server" BorderStyle="None" OnTextChanged="TextBox_TextChanged"
                                Text='<%# Bind("productDesc") %>' TextMode="MultiLine"></asp:TextBox>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Price">
                        <ItemTemplate>
                            <asp:TextBox ID="tbPrice" AutoPostBack="false" EnableViewState="true" runat="server" BorderStyle="None" OnTextChanged="TextBox_TextChanged"
                                Text='<%# Bind("productPrice", "{0:C}") %>'></asp:TextBox>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Select">
                        <ItemTemplate>
                           <asp:CheckBox id="cbDelete" OnCheckedChanged="cbDelete_CheckedChanged" AutoPostBack="false" EnableViewState="true" runat="server" />
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
                <RowStyle ForeColor="#000066" />
                <SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
                <PagerStyle BackColor="beige" ForeColor="#000066" HorizontalAlign="Left" />
                <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
            </asp:GridView>
        </div>
        <div class="ProductListButtons">
            <asp:ImageButton AlternateText="Add" ToolTip="Add New Product" Width="30px" Height="30px"
                ImageUrl="~/Images/Add.png" ID="AddBtn" runat="server" OnClick="AddBtn_Click" />
            <asp:ImageButton ID="DeleteBtn" runat="server" AlternateText="Delete" Height="30px"
                ImageUrl="~/Images/delete.png" ToolTip="Delete Selected" Width="30px" OnClick="DeleteBtn_Click" />
            <asp:ImageButton AlternateText="Save Changes" ToolTip="Save Changes" Width="30px"
                Height="30px" ImageUrl="~/Images/save-icon.png" ID="SaveBtn" runat="server" OnClick="SaveBtn_Click" />

        </div>
    </ContentTemplate>
</asp:UpdatePanel>

还有代码隐藏:

public partial class Controls_ProductList : System.Web.UI.UserControl
{
    public int StallID { get; set; }
    bool[] rowChanged;
    bool[] rowDeleted;

    // this allows me to test your code without your data source (C# 3.0 list constructor)
    private static List<Product> _productList = new List<Product>() { 
            new Product() { productID = 1, productName = "Product 1", productDesc = "This is product 1", productPrice = 1.0m },
            new Product() { productID = 2, productName = "Product 2", productDesc = "This is product 2", productPrice = 1.0m },
            new Product() { productID = 3, productName = "Product 3", productDesc = "This is product 3", productPrice = 1.0m }
        };

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            StallID = Convert.ToInt16(ViewState["StallID"].ToString());
        }
        else
        {
            // Only bind if this is not a postback
            BindList();
        }

        int totalRows = ProductList.Rows.Count;
        rowChanged = new bool[totalRows];
        rowDeleted = new bool[totalRows];

        ViewState.Add("StallID", StallID);

        foreach (GridViewRow row in ProductList.Rows)
        {
            var checkBox = row.FindControl("cbDelete");
            ScriptManager1.RegisterAsyncPostBackControl(checkBox);
        }
    }

    public void BindList()
    {
        //StallHandler handler = new StallHandler();
        //DataTable productList = handler.GetProductsByID(StallID);
        ProductList.DataSource = _productList;
        ProductList.DataBind();
    }

    protected void TextBox_TextChanged(object sender, EventArgs e)
    {
        TextBox thisTextBox = (TextBox)sender;
        GridViewRow thisGridViewRow = (GridViewRow)thisTextBox.Parent.Parent;
        int row = thisGridViewRow.RowIndex;
        rowChanged[row] = true;
    }

    protected void cbDelete_CheckedChanged(object sender, EventArgs e)
    {
        CheckBox thisCheckbox = (CheckBox)sender;
        GridViewRow thisGridViewRow = (GridViewRow)thisCheckbox.Parent.Parent;
        int row = thisGridViewRow.RowIndex;
        rowDeleted[row] = true;
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        //if (Page.IsPostBack)
        //{
        //  ProductList.DataBind();
        //}
    }

    protected void ProductList_PageIndexChanged(object sender, EventArgs e)
    {

    }

    protected void ProductList_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        ProductList.PageIndex = e.NewPageIndex;
        ProductList.DataBind();
    }

    protected void AddBtn_Click(object sender, System.Web.UI.ImageClickEventArgs e)
    {
        Response.Redirect("../StallHolder/AddProduct.aspx");
    }

    protected void DeleteBtn_Click(object sender, System.Web.UI.ImageClickEventArgs e)
    {
        int totalRows = ProductList.Rows.Count;
        for (int r = 0; r < totalRows; r++)
        {
            if (rowDeleted[r])
            {
                GridViewRow thisGridViewRow = ProductList.Rows[r];
                HiddenField hf1 = (HiddenField)thisGridViewRow.FindControl("HiddenField1");
                int ID = Convert.ToInt16(hf1.Value);
                //StallHandler handler = new StallHandler();
                //handler.DeleteProduct(Convert.ToInt16(ID));

                _productList = _productList.Where(a => a.productID != ID).ToList();
            }
        }
        BindList();
    }

    protected void SaveBtn_Click(object sender, System.Web.UI.ImageClickEventArgs e)
    {
        int totalRows = ProductList.Rows.Count;
        for (int r = 0; r < totalRows; r++)
        {
            if (rowChanged[r])
            {
                GridViewRow thisGridViewRow = ProductList.Rows[r];
                HiddenField hf1 = (HiddenField)thisGridViewRow.FindControl("HiddenField1");
                int ID = Convert.ToInt32(hf1.Value);
                TextBox tbName = (TextBox)thisGridViewRow.FindControl("tbName");
                string Name = tbName.Text;
                TextBox tbDesc = (TextBox)thisGridViewRow.FindControl("tbDesc");
                string Desc = tbDesc.Text;
                TextBox tbPrice = (TextBox)thisGridViewRow.FindControl("tbPrice");
                string Price = tbPrice.Text;
                //Code to update the database!

                var product = _productList.Where(a => a.productID == ID).First();
                product.productName = Name;
                product.productDesc = Desc;
                product.productPrice = decimal.Parse(Price, System.Globalization.NumberStyles.Currency);
            }
        }
        BindList();
    }
}

public class Product
{
    public int productID { get; set; }
    public string productName { get; set; }
    public string productDesc { get; set; }
    public decimal productPrice { get; set; }
}

我必须创建自己的类来用作数据源来测试它。只需为您的解决方案删除这些代码。

如您所见,我做了一些更改:

  1. 为复选框和文本框设置AutoPostback="False"。
  2. 删除了&lt;Triggers&gt; 元素,因为这仅适用于UpdatePanel 之外的控件。
  3. 在复选框中添加了OnCheckedChanged="cbDelete_CheckedChanged" 元素。

还有一些细微的变化,但没有值得一提的。虽然我应该提到我不喜欢你这样做的方式,但它似乎确实有效。

【讨论】:

  • 如果您认为有更好的方法,我愿意接受建议?感谢您的帮助,我将实施您的更改并告诉您我的进展情况。
  • 感谢您的帮助,我做出了您建议的更改,并且复选框删除功能现在可以完美运行,希望同样的方法可以保存对 gridview 中文本的更改。
  • 没问题。我用编辑文本测试了我粘贴的代码,这也适用于我对数据源所做的更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-12
  • 2011-02-27
相关资源
最近更新 更多