问题
I need to update some table values using Checkboxes. The table consist of 3 simple columns: id, name and selected (bool).
I added a asp:CheckBoxList control to a form, bound it to a SqlDataSource. I added a button with the simple code MySqlDataSource.Update(); Then browse to the page.
I click a Checkbox, then click the button to Update the datasource and using the Sql Server Profiler I see this is what was sent to the database:
exec sp_executesql N'UPDATE [MyTable] SET [Name] = @Name, [Selected] = @Selected
WHERE [Id] = @Id',N'@Name nvarchar(4000),@Selected bit,
@Id int',@Name=NULL,@Selected=NULL,@Id=NULL
The problem is clear, the values are not being set.... but why?
I added a GridView, just for testing purposes, using the same exact SqlDataSource without moving a single bit from it, and I'm able to modify the records by clicking the "Edit" link, then the checkbox, then the "Update" link and that's it, that does save to the database, it correctly send the update command to Sql Server.
If I go to the UpdateQuery property of MyDataSource, I see there's an option to set the "Parameter Source", but I can't see in the dropdownlist one to set the parameter source of the same datasource. Seems like I'm missing something here.... but why the same SqlDataSource does work for the GridView ?
I spent several hours already searching for samples about using a CheckboxList to perform updates and I found a many sample but... most are just for displaying purpose. I wonder if the CheckboxList can really work for updates?
UPDATE
Followed the advise to set the Parameter source as the CheckBoxList. I set the parameter source for the Name and Selected columns to the property "SelectedValue". It changed the behavior, but it still works wrong, now the query sent to the database is:
exec sp_executesql N'UPDATE [MyTable] SET [Name] = @Name, [Selected] = @Selected WHERE [Id] = @Id',N'@Name nvarchar(5),@Selected bit,@Id int',@Name=N'False',@Selected=0,@Id=NULL
You can see now it sends "False" and "0" instead of nulls, but the Id is still being sent as "null".
So, I changed the pararmeters to set the ID with a Parameter source of type Control, then CheckboxList, then set Selected to the SelectedValue property. Now the error message is:
"Input string was not in a correct format."
I think it should be a way to get the underlying values from the "current" checkbox item, but I don't know why and I have still searching for examples.
回答1:
I have made a repeater construct that appears like a asp:CheckBoxList
, but with additional functionality. Here is what it looks like in a browser:
Here is the .aspx code:
<form id="form1" runat="server">
<div>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# (bool)Eval("Selected") %>' />
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Name")%>' AssociatedControlID="CheckBox1"></asp:Label>
<div style="clear:both;height:5px;"></div>
</ItemTemplate>
</asp:Repeater>
<div style="clear:both;height:45px;"></div>
<asp:Button ID="Update_Button" runat="server" Text="Update"
OnClick="Update_Button_Click" />
</div>
</form>
And the codebehind:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Fake DataTable below.
//SqlDataSource can be configured to generate a DataTable,
//Or you can use a DataAdapter
DataTable dt = new DataTable();
DataColumn dc1 = new DataColumn("Name");
DataColumn dc2 = new DataColumn("Id");
DataColumn dc3 = new DataColumn("Selected");
dc3.DataType = System.Type.GetType("System.Boolean");
dt.Columns.Add(dc1);
dt.Columns.Add(dc2);
dt.Columns.Add(dc3);
dt.Rows.Add(new object[] { "John Doe", "135681", true });
dt.Rows.Add(new object[] { "Billy Joe", "66541", false });
dt.Rows.Add(new object[] { "Joe Shmoe", "7783654", true });
dt.Rows.Add(new object[] { "Don Sean", "1332451", true });
dt.Rows.Add(new object[] { "Moe H", "632451", false });
dt.Rows.Add(new object[] { "Clicky", "0234354", true });
//Bind DataTable to Repeater
Repeater1.DataSource = dt;
Repeater1.DataBind();
}
}
protected void Update_Button_Click(object sender, EventArgs e)
{
List<Person> Listy = new List<Person>();
ControlCollection CC = Repeater1.Controls;
foreach (RepeaterItem RI in CC)
{
Person p = new Person();
foreach (Control c in RI.Controls)
{
if (c is System.Web.UI.WebControls.CheckBox)
{
if (((System.Web.UI.WebControls.CheckBox)c).Checked)
p.Selected = true;
else p.Selected = false;
}
if (c is System.Web.UI.WebControls.Label)
{
p.Name = ((System.Web.UI.WebControls.Label)c).Text;
}
}
Listy.Add(p);
}
UpdateDatabase(Listy);
}
protected void UpdateDatabase(List<Person> L)
{
foreach (Person p in L)
{
string update = "UPDATE [Table] SET [Selected] = " + p.Selected + "WHERE [Name] = " + p.Name;
// Execute statement
}
}
}
public class Person
{
public string Name { get; set; }
//public int ID { get; set; }
public bool Selected { get; set; }
}
And here is the debugger open at the update statement. All values are accurate!
Obviously there is much room for improvement, but hopefully this will give you a good idea of how to proceed!
回答2:
Make sure your ID column is unique (key + auto numbered) this way your "WHERE" will only refer to the ID column and the "SET" will refer to the true\false column (the column you checking).
UPDATE [dbo].[Table_1]
SET [CheckBoxCol] = @CheckBoxCol
WHERE (([id] = @Original_id))
In order to catch the "Checked" event you can use the following reffs: ASP.NET 2.0 Gridview CheckBox column How to add event for Checkbox click in Asp.net Gridview Column
You can use the DataSet.xsd for such simple queries, its easy drag and drop object to create databases queries.
来源:https://stackoverflow.com/questions/19192207/asp-net-checkboxlist-to-update-a-sqldatasource