我是 asp.net 的新手。我在 sqlserver 中创建了一个包含 3 列的数据库表; ImageID、文件名和分数
。
文件名是 C:\pics\beads.png 或 C:\pics\moreimages\scenary.jpeg
。
我使用 C# asp.net 创建了一个 GridView。这个 Gridview 应该填充
(第 1 列)ImageID 并从文件名(第 2 列)获取图像,我创建了 2 个复选框列表,如下所示,它应该接受来自用户的图像分数并将其保存到数据库表中。
问题 1 .
我能够填充图像 ID,但图像没有被填充。
问题 2.
我不知道如何访问 checkboxlist
因为它在模板中。选中的是默认选择,即使我点击它也不会改变。应使用哪种方法/属性将选择保存到数据库中。这是我的代码
<form id="form1" runat="server">
<p style="height: 391px">
<asp:GridView ID="GridView1" runat="server" Caption="Logos" Height="299px" Width="577px" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="ImageID" HeaderText="ImageID" />
<asp:ImageField DataImageUrlField="FileName" ControlStyle-Width="100"
ControlStyle-Height="100" HeaderText="Image" AlternateText="No image">
<ControlStyle Height="100px" Width="100px"></ControlStyle>
</asp:ImageField>
<asp:TemplateField HeaderText="Score" AccessibleHeaderText="CheckBoxList" ValidateRequestMode="Enabled">
<ItemTemplate>
<asp:CheckBoxList runat="server" AutoPostBack="true" RepeatColumns="3" ID="test">
<asp:ListItem Selected="True" Value="5">Good</asp:ListItem>
<asp:ListItem Value="0">Not Good </asp:ListItem>
<asp:ListItem Value="3">OK</asp:ListItem>
</asp:CheckBoxList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Save" Width="130px" />
<asp:Button ID="Button2" runat="server" OnClientClick="javaScript:window.close(); return false;" Text="Exit" Width="102px" />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</p>
</form>
public string sqlSel = @"SELECT TOP 3 [ImageID],FileName FROM [db1].[ImagesTest] where [Score] is null";
protected void Page_Load(object sender, EventArgs e)
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
connection.Open();
SqlCommand cmdSel = new SqlCommand(sqlSel, connection);
SqlDataReader reader1 = cmdSel.ExecuteReader();
while (reader1.Read())
{
DataSet ds = GetData(sqlSel);
if (ds.Tables.Count > 0)
{
GridView1.DataSource = ds;
GridView1.DataBind();
}
else
{
Response.Write("Unable to connect to the database.");
}
}
}
}
private DataSet GetData(string cmdSel)
{
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString;
DataSet ds = new DataSet();
try
{
SqlConnection con = new SqlConnection(strConnString);
SqlDataAdapter sda = new SqlDataAdapter(cmdSel,con);
sda.Fill(ds);
}
catch (Exception ex)
{
Response.Write("IN EXCEPTION "+ex.Message);
return null;
}
return ds;
}
谢谢你的时间 拉什米
最佳答案
您的代码有几个问题,这里是应该修复的地方:
如何修复图片(问题1)
正如@Guilherme 在评论中所说,图像使用 URL 而不是磁盘路径。
替换图像磁盘路径 C:\pics\beads.png
或 C:\pics\moreimages\scenary.jpeg
类似于 Images/beads.png
和 Images/scenary.jpeg
.
为此,您需要有一个名为 Images
的文件夹在与您的 .aspx
相同的目录级别包含这两个文件文件。
在 ASPX 文件中调整您的 GridView1 声明
在您的 GridView1 声明中,您应该:
- 将处理程序附加到
OnRowDataBound
事件。这将允许您正确绑定(bind)Score
数据集列到Score
GridView 列 - 设置
DataKeyNames
将网格上的属性设置为图像表的主键(在本例中为DataKeyNames="ImageID"
) - 使用
RadioButtonList
而不是CheckboxList
, 因为根据你的数据集你只能设置一个值,这就是RadioButtonList
做。CheckboxList
通常在需要多选时使用。 - 将处理程序附加到
SelectedIndexChanged
RadioButtonList
上的事件.这将允许您将新值保存到数据库中(问题 2)
GridView 声明应如下所示:
<asp:GridView ID="GridView1" runat="server" Caption="Logos" Height="299px" Width="577px" AutoGenerateColumns="False" OnRowDataBound="GridView1_RowDataBound" DataKeyNames="ImageID">
<Columns>
<asp:BoundField DataField="ImageID" HeaderText="ImageID" />
<asp:ImageField DataImageUrlField="FileName" ControlStyle-Width="100"
ControlStyle-Height="100" HeaderText="Image" AlternateText="No image">
<ControlStyle Height="100px" Width="100px"></ControlStyle>
</asp:ImageField>
<asp:TemplateField HeaderText="Score" AccessibleHeaderText="RadioButtonList" ValidateRequestMode="Enabled">
<ItemTemplate>
<asp:RadioButtonList runat="server" AutoPostBack="true" RepeatColumns="3" ID="test" OnSelectedIndexChanged="test_SelectedIndexChanged">
<asp:ListItem Value="5">Good</asp:ListItem>
<asp:ListItem Value="0">Not Good </asp:ListItem>
<asp:ListItem Value="3">OK</asp:ListItem>
</asp:RadioButtonList>
<!-- UPDATED! - keep the old values in a hidden field -->
<asp:HiddenField runat="server" ID="hfOldScore" Value='<%# Eval("Score") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
调整 .ASPX.CS 文件中的代码隐藏值(问题 2)
在后面的代码中,您还需要:
- 确保在
Page_Load
中只绑定(bind)到 GridView 一次事件,通过检查IsPostBack
属性(property) - (可选,但推荐)将获取数据的逻辑(使用 SQLConnection 代码)移动到一个单独的方法中,该方法将仅处理数据检索
- 实现
OnRowDataBound
的处理程序事件。这将绑定(bind)来自Score
的任何值列到RadioButtonList
控制 - 实现
SelectedIndexChecked
的处理程序RadioButtonList
事件控制。这将允许您将新值保存到数据库中
最后,这是完整的代码隐藏代码:
protected void Page_Load(object sender, EventArgs e)
{
//bind only the first time the page loads
if (!IsPostBack)
{
DataSet ds = GetData(sqlSel);
if (ds.Tables.Count > 0)
{
GridView1.DataSource = ds;
GridView1.DataBind();
}
else
{
Response.Write("Unable to connect to the database.");
}
}
}
private DataSet GetData(string cmdSel)
{
//normally you should query the data from the DB
//I've manually constructed a DataSet for simplification purposes
DataSet ds = new DataSet();
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("ImageID", typeof(int)));
dt.Columns.Add(new DataColumn("FileName", typeof(string)));
dt.Columns.Add(new DataColumn("Score", typeof(int)));
dt.Rows.Add(100, @"Images/beads.png", 0);
dt.Rows.Add(200, @"Images/moreimages/scenary.jpeg", 3);
dt.Rows.Add(300, @"Images/moreimages/scenary.jpeg", 5);
ds.Tables.Add(dt);
return ds;
}
protected void Button1_Click(object sender, EventArgs e)
{
//UPDATED - iterate through all the data rows and build a dictionary of items
//to be saved
Dictionary<int, int> dataToUpdate = new Dictionary<int, int>();
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
int imageID = (int)GridView1.DataKeys[row.RowIndex].Value;
int oldScore;
int newScore;
int.TryParse((row.FindControl("hfOldScore") as HiddenField).Value, out oldScore);
int.TryParse((row.FindControl("test") as RadioButtonList).SelectedValue, out newScore);
if (oldScore != newScore)
{
dataToUpdate.Add(imageID, newScore);
}
}
}
//update only the images that were changed
foreach (var keyValuePair in dataToUpdate)
{
SaveToDB(keyValuePair.Key, keyValuePair.Value);
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//we are only interested in the data Rows
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRow dataRow = (e.Row.DataItem as DataRowView).Row;
//manually bind the Score column to the RadioButtonlist
int? scoreId = dataRow["Score"] == DBNull.Value ? (int?)null : (int)dataRow["Score"];
if (scoreId.HasValue)
{
RadioButtonList test = e.Row.FindControl("test") as RadioButtonList;
test.ClearSelection();
test.SelectedValue = scoreId.Value.ToString();
}
}
}
protected void test_SelectedIndexChanged(object sender, EventArgs e)
{
RadioButtonList test = sender as RadioButtonList;
GridViewRow gridRow = test.NamingContainer as GridViewRow;
//obtain the current image Id
int imageId = (int)GridView1.DataKeys[gridRow.RowIndex].Value;
//obtain the current selection (we will take the first selected checkbox
int selectedValue = int.Parse(test.SelectedValue);
//UPDATED! - saves are now handled on the Save button click
//SaveToDB(imageId, selectedValue);
}
private void SaveToDB(int imageId, int score)
{
//UPDATED!
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.Parameters.Add("@ImageID", imageId);
command.Parameters.Add("@Score", score);
command.CommandText = @"update [db1].[ImagesTest] set Score = @Score where [ImageID] = @ImageID";
command.ExecuteNonQuery();
}
}
}
已更新!
- 声明
GridView1
现在包含一个包含分数值的隐藏字段。您可以使用此隐藏字段来确定哪一行发生了更改,因此您可以仅在更改的行上触发保存 - 通过遍历网格的行并构建一个
Dictionary<int,string>
,现在单击“保存”按钮即可完成保存。只保留更改。 -
SaveToDB
方法应该有效,但我无法自己测试。
关于c# - 模板字段中的 ASP.NET c# 复选框列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21331085/