TextBox TextChanged事件和CheckBox CheckedChanged事件未在gridview中触发

时间:2010-01-08 12:28:36

标签: c# asp.net

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

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

但是,为了知道哪些行已被更改,我有一个与每个文本框关联的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!
        }
    }
}

}

很抱歉这很糟糕,但我不知道我做错了什么或在哪里。

1 个答案:

答案 0 :(得分:1)

好的,在我开始工作时我找到了一些东西。看一下代码片段

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="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. 删除了<Triggers>元素,因为这仅适用于控件外部 UpdatePanel
  3. 在复选框中添加了OnCheckedChanged="cbDelete_CheckedChanged"元素。
  4. 一些细微的变化,但没有一个值得一提。虽然我应该提到我不喜欢你这样做的方式,但它似乎确实有用。