所以我在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!
}
}
}
}
很抱歉这很糟糕,但我不知道我做错了什么或在哪里。
答案 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; }
}
我必须创建自己的类来用作测试它的数据源。只需为您的解决方案删除这些代码。
如你所见,我做了一些改变:
AutoPostback="False"
。<Triggers>
元素,因为这仅适用于控件外部 UpdatePanel
。OnCheckedChanged="cbDelete_CheckedChanged"
元素。一些细微的变化,但没有一个值得一提。虽然我应该提到我不喜欢你这样做的方式,但它似乎确实有用。