Search This Blog

Monday, September 20, 2010

TextBox TextChanged Events and CheckBox CheckedChanged Events not firing within a gridview



I found when getting this to work. Have a look at the code snippets
<div>
<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>
</div>



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; } 

I had to create my own class to use as the data source to test this. Just remove those bits of code for your solution.
As you can see, I've made some changes:
  1. Set AutoPostback="False" for the check box and text boxes.
  2. Removed the <Triggers> element, as this only applies to controls outside the UpdatePanel.
  3. Added the OnCheckedChanged="cbDelete_CheckedChanged" element to the check box.
Some minor changes also but none worth mentioning. Although I should mention I'm not a fan of the way you have done this, but it does seem to work.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.