简体   繁体   中英

How to configure the index of a datalist in asp.net ?

I develop a web application in visual studio that display rooms pictures and their names from the database in one page and a rate button beside each room all in a datalist

Then when the user click the rate button the room picture and its name should be transfered to the rate page but ,

What happens with me is that if I click any button only the first room picture and name displayed in the rate page :'( !

I think it corresponds with the index of the datalist , but I don't know how to deal with it !!

What should I do to fix it ?

Here is the code

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 code-behind file

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 code-behind file

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();

            }



        }
    }
}

You are redirecting in a foreach , you know that Response.Redirect redirects a client to a new URL immediately and throws a ThreadAbortException upon completion?

Instead you only need to use FindControl on the current item instead of all(actually only the first because the foreach is not fully enumerated), it's the button's 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");
}

As mentioned by Rahul in the comment section you should also not DataBind the DataList on every post back but only on the initial one. Therefore use IsPostBack to check it:

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

Otherwise all changes are lost and events aren't triggered. That applies only if ViewState is enabled which is default. It's also good practise to use the using -statement and a local variable for the connection instead of a field. That ensures that it gets closed even on error.

Why don't you try using DataList_ItemCommand event to Redirect to another page for the appropriate item that is clicked.

Here is what I propose you should try :

  1. Store PrimaryKey Id of every room into Command Argument property using a LinkButton instead of Button .
  2. On the code behind, create the DataList_ItemCommand event and fetch the Command Argument of the item that is clicked like this :

    var id = e.CommandArgument;

  3. Use Response.Redirect in that same function and pass this ID as a query string parameter or in Session like you are doing now and fetch that on the Redirecting page.

You can also take some reference for the DataList_ItemCommand event from this link : Pass Data to other Page using DataList and Querystring

Hope this helps.

Put in CommandName and CommandArgument properties of Button Control. Put primary key of record in CommandArgument and instead of using button's click event. Use button's Command event. In that event you will get an argument of type CommandEventArgs. And in this event you can get the primary key of the record being rated by using CommandEventArgs arguments "CommandArgument" property and then you can do whatever you want with this particular record.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM