如何在 asp.net 中配置数据列表的索引?
How to configure the index of a datalist in asp.net ?
我在 visual studio 中开发了一个 Web 应用程序,它在一页中显示数据库中的房间图片及其名称,每个房间旁边都有一个费率按钮,所有这些都在数据列表中
然后,当用户点击房价按钮时,房间图片及其名称应该会传送到房价页面,但是,
我遇到的情况是,如果我单击任何按钮,价格页面中只会显示第一个房间图片和名称:'( !
我觉得是对应datalist的索引,但是不知道怎么处理!!
我应该怎么做才能解决它?
这是代码
webform1.aspex
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="HotelG.WebForm1" EnableEventValidation="false" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DataList ID="DataList1" runat="server" Width="615px" Height="439px" >
<ItemTemplate>
<table>
<tr>
<td><asp:Image ID="Img1" runat="server" ImageUrl=<%# Eval("Picture")%> Height="100" style="position: relative; top: 0px; left: 98px; width: 100" /> </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<asp:Label ID="Label1" runat="server" Text=<%# Eval("Room_Type")%>></asp:Label>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><asp:Button ID="btn1" runat="server" Text="Rate" OnClick="Button1_Click" /></td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
<br />
</div>
</form>
</body>
</html>
webform1 代码隐藏文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
namespace HotelG
{
public partial class WebForm1 : System.Web.UI.Page
{
SqlConnection con = new SqlConnection(@"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename=C:\Users\user\Desktop\database\Golden_Rose.mdf;Integrated Security = True; Connect Timeout = 30");
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
string sel = "select Room_Type , Picture from room_details";
SqlCommand cmd = new SqlCommand(sel, con);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
DataList1.DataSource = dt;
DataList1.DataBind();
con.Close();
}
protected void Button1_Click(object sender, EventArgs e)
{
foreach (DataListItem li in DataList1.Items)
{
Image img = (Image)li.FindControl("Img1");
Label lbl = (Label)li.FindControl("Label1");
string labeltext = lbl.Text;
string url = img.ImageUrl;
Session["type"] = labeltext;
Session["img"] = url;
Response.Redirect("WebForm2.aspx");
}
}
}
}
webform2 代码隐藏文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace HotelG
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Session["type"] != null)
{
Label1.Text = Session["type"].ToString();
Label5.Text = Session["type"].ToString();
}
if (Session["img"] != null)
{
Image1.ImageUrl = Session["img"].ToString();
Label4.Text = Session["img"].ToString();
}
}
}
}
您正在 foreach
中重定向,您知道 Response.Redirect
会立即将客户端重定向到新的 URL 并在完成时抛出 ThreadAbortException
吗?
相反,您只需要在 current 项上使用 FindControl
而不是所有项(实际上只有第一个,因为 foreach
未完全枚举) , 就是按钮的 NamingContainer
:
protected void Button1_Click(object sender, EventArgs e)
{
DataListItem currentItem = (DataListItem)((Button) sender).NamingContainer;
Image img = (Image)currentItem.FindControl("Img1");
Label lbl = (Label)currentItem.FindControl("Label1");
string labeltext = lbl.Text;
string url = img.ImageUrl;
Session["type"] = labeltext;
Session["img"] = url;
Response.Redirect("WebForm2.aspx");
}
正如 Rahul 在评论部分提到的,您也不应该 DataBind
每个 post 后面的 DataList
,而应该只在第一个后面。因此使用 IsPostBack
来检查它:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
con.Open();
string sel = "select Room_Type , Picture from room_details";
SqlCommand cmd = new SqlCommand(sel, con);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
DataList1.DataSource = dt;
DataList1.DataBind();
con.Close();
}
}
否则所有更改都将丢失并且不会触发事件。这仅适用于默认启用 ViewState
的情况。使用 using
语句和局部变量而不是字段进行连接也是一种很好的做法。这确保它即使在出错时也能关闭。
您为什么不尝试使用 DataList_ItemCommand
事件重定向到被单击的相应项目的另一个页面。
以下是我建议您尝试的方法:
- 使用
LinkButton
而不是 Button
. 将每个房间的主键 ID 存储到 Command Argument
属性
在后面的代码中,创建 DataList_ItemCommand
事件并获取被单击项目的命令参数,如下所示:
var id = e.CommandArgument;
在同一个函数中使用 Response.Redirect
并将此 ID 作为查询字符串参数传递,或者像您现在所做的那样在 Session 中传递并在重定向页面上获取它。
您还可以从这个link中获取一些关于DataList_ItemCommand
事件的参考:Pass Data to other Page using DataList and Querystring
希望对您有所帮助。
输入按钮控件的 CommandName 和 CommandArgument 属性。将记录的主键放在 CommandArgument 中,而不是使用按钮的点击事件。使用按钮的命令事件。在那种情况下,您将获得 CommandEventArgs 类型的参数。在这种情况下,您可以使用 CommandEventArgs 参数 "CommandArgument" 属性 获取被评级记录的主键,然后您可以对该特定记录做任何您想做的事情。
我在 visual studio 中开发了一个 Web 应用程序,它在一页中显示数据库中的房间图片及其名称,每个房间旁边都有一个费率按钮,所有这些都在数据列表中
然后,当用户点击房价按钮时,房间图片及其名称应该会传送到房价页面,但是,
我遇到的情况是,如果我单击任何按钮,价格页面中只会显示第一个房间图片和名称:'( !
我觉得是对应datalist的索引,但是不知道怎么处理!!
我应该怎么做才能解决它?
这是代码
webform1.aspex
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="HotelG.WebForm1" EnableEventValidation="false" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DataList ID="DataList1" runat="server" Width="615px" Height="439px" >
<ItemTemplate>
<table>
<tr>
<td><asp:Image ID="Img1" runat="server" ImageUrl=<%# Eval("Picture")%> Height="100" style="position: relative; top: 0px; left: 98px; width: 100" /> </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<asp:Label ID="Label1" runat="server" Text=<%# Eval("Room_Type")%>></asp:Label>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><asp:Button ID="btn1" runat="server" Text="Rate" OnClick="Button1_Click" /></td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
<br />
</div>
</form>
</body>
</html>
webform1 代码隐藏文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
namespace HotelG
{
public partial class WebForm1 : System.Web.UI.Page
{
SqlConnection con = new SqlConnection(@"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename=C:\Users\user\Desktop\database\Golden_Rose.mdf;Integrated Security = True; Connect Timeout = 30");
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
string sel = "select Room_Type , Picture from room_details";
SqlCommand cmd = new SqlCommand(sel, con);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
DataList1.DataSource = dt;
DataList1.DataBind();
con.Close();
}
protected void Button1_Click(object sender, EventArgs e)
{
foreach (DataListItem li in DataList1.Items)
{
Image img = (Image)li.FindControl("Img1");
Label lbl = (Label)li.FindControl("Label1");
string labeltext = lbl.Text;
string url = img.ImageUrl;
Session["type"] = labeltext;
Session["img"] = url;
Response.Redirect("WebForm2.aspx");
}
}
}
}
webform2 代码隐藏文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace HotelG
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Session["type"] != null)
{
Label1.Text = Session["type"].ToString();
Label5.Text = Session["type"].ToString();
}
if (Session["img"] != null)
{
Image1.ImageUrl = Session["img"].ToString();
Label4.Text = Session["img"].ToString();
}
}
}
}
您正在 foreach
中重定向,您知道 Response.Redirect
会立即将客户端重定向到新的 URL 并在完成时抛出 ThreadAbortException
吗?
相反,您只需要在 current 项上使用 FindControl
而不是所有项(实际上只有第一个,因为 foreach
未完全枚举) , 就是按钮的 NamingContainer
:
protected void Button1_Click(object sender, EventArgs e)
{
DataListItem currentItem = (DataListItem)((Button) sender).NamingContainer;
Image img = (Image)currentItem.FindControl("Img1");
Label lbl = (Label)currentItem.FindControl("Label1");
string labeltext = lbl.Text;
string url = img.ImageUrl;
Session["type"] = labeltext;
Session["img"] = url;
Response.Redirect("WebForm2.aspx");
}
正如 Rahul 在评论部分提到的,您也不应该 DataBind
每个 post 后面的 DataList
,而应该只在第一个后面。因此使用 IsPostBack
来检查它:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
con.Open();
string sel = "select Room_Type , Picture from room_details";
SqlCommand cmd = new SqlCommand(sel, con);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
DataList1.DataSource = dt;
DataList1.DataBind();
con.Close();
}
}
否则所有更改都将丢失并且不会触发事件。这仅适用于默认启用 ViewState
的情况。使用 using
语句和局部变量而不是字段进行连接也是一种很好的做法。这确保它即使在出错时也能关闭。
您为什么不尝试使用 DataList_ItemCommand
事件重定向到被单击的相应项目的另一个页面。
以下是我建议您尝试的方法:
- 使用
LinkButton
而不是Button
. 将每个房间的主键 ID 存储到 在后面的代码中,创建
DataList_ItemCommand
事件并获取被单击项目的命令参数,如下所示:var id = e.CommandArgument;
在同一个函数中使用
Response.Redirect
并将此 ID 作为查询字符串参数传递,或者像您现在所做的那样在 Session 中传递并在重定向页面上获取它。
Command Argument
属性
您还可以从这个link中获取一些关于DataList_ItemCommand
事件的参考:Pass Data to other Page using DataList and Querystring
希望对您有所帮助。
输入按钮控件的 CommandName 和 CommandArgument 属性。将记录的主键放在 CommandArgument 中,而不是使用按钮的点击事件。使用按钮的命令事件。在那种情况下,您将获得 CommandEventArgs 类型的参数。在这种情况下,您可以使用 CommandEventArgs 参数 "CommandArgument" 属性 获取被评级记录的主键,然后您可以对该特定记录做任何您想做的事情。