I have a ListView on my checkout page with an ItemTemplate which build up a table of items ordered by customer. I want to add a total in the footer of the table, I have the following markup:
<asp:ListView ID="lvOrderSummary" runat="server">
<LayoutTemplate>
<table id="tblOrderSummary">
<tr>
<td><b>Title</b></td>
<td><b>Cost</b></td>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
<tr>
<td><b>Total Cost:</b></td>
<td><%# GetTotalCost().ToString()%></td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#Eval("Title") %></td>
<td><%#Eval("Cost") %> </td>
</tr>
</ItemTemplate>
</asp:ListView>
I have a server side method called GetTotalCost that return the value I require. The problem I'm having is that this method is never called.
I have also tried and instead of using:
<td><%# GetTotalCost().ToString()%></td>
I've tried using
<td id="tdTotal" runat="server"></td>
---------------
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
TableCell td = ((TableCell)this.FindControl("lvOrderSummary_tdTotal"));
}
}
Check this article for an example how to display a total in the ListView.
Basically you can add a label in the layout template:
<asp:ListView ID="lvOrderSummary" runat="server"
OnPreRender="lvOrderSummary_PreRender" ...>
<LayoutTemplate>
...
<td><asp:Label ID="lblTotalCost" runat="server" Text="Total"/></td>
..
</LayoutTemplate></asp:ListView>
And then you set the label's text in the PreRender event handler:
protected void lvOrderSummary_PreRender(object sender, EventArgs e)
{
Label lbl = lvOrderSummary.FindControl("lblTotalCost") as Label;
lbl.Text = GetTotalCost().ToString();
}
Try
Dim strcon As String = "Data Source=.\SQLEXPRESS;AttachDbFilename=D:\webarticles\App_Data\mydatabase.mdf;Integrated Security=True;User Instance=True"
Dim con As New SqlConnection(strcon)
con.Open()
Dim da As SqlDataAdapter
Dim ds As New DataSet
Dim sqlstring As String = "SELECT * FROM tblstudent "
da = New SqlDataAdapter(sqlstring, con)
da.Fill(ds)
DetailsView1.DataSource = ds.Tables(0)
DetailsView1.DataBind()
Catch ex As Exception
MsgBox("There is some Error")
End Try
Another data handeling control is DetailsView control which gives you the ability to display, delete, edit, insert a single record at a time from its associated data source. The DetailsView control does not support sorting.By default, the DetailsView control displays each field of a record on its own line.
Related
I am trying to design a notification section for my ASP.NET website.
My requirement is similar to this image layout.
I was able to implement this with the asp repeater control and binding it with database.
I have table in my DB that has image, name and comments as its columns.
So according to the no. of rows in the DB table, the repeater control will get me the contents in the defined layout.
But i also wanted to implement the close button ("X" - top right corner). this close button will just remove the particular comment (but it will not delete data in DB).
Could you please help me in achieving this ??
Also thanks to suggest any other possible option to acheive this.
PFB the code i have done so far
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<table>
<tr>
<td style="height:64px;width:64px">
<asp:Image ID="imgEmployee" CssClass="imgClass" ImageUrl='<%# Eval("ImagePath")%>'runat="server" />
</td>
<td>
<asp:Label runat="server" Text='<%# Eval("Name")%>'></asp:Label>
<p> <%# Eval("Comments")%></p>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
and code behind
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds = GetData();
Repeater1.DataSource = ds;
Repeater1.DataBind();
}
private DataSet GetData()
{
string CS = ConfigurationManager.ConnectionStrings["con"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
SqlDataAdapter da = new SqlDataAdapter("Select * from tblNotification", con);
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
}
And my table (tblNotification) has 3 columns - "ImagePath", "Name" and "Comments"
i have this code:
protected void Button1_Click(object sender, EventArgs e)
{
System.Data.SqlClient.SqlConnection sc = new System.Data.SqlClient.SqlConnection(GetConnectionString());
{
System.Data.SqlClient.SqlCommand cmd;
sc.Open();
cmd = new System.Data.SqlClient.SqlCommand("SET IDENTITY_INSERT Zapas OFF INSERT INTO Zapas (Zapas.Sezona,.....)SELECT Zapas.Sezona,... FROM Zapas WHERE ID_zapas=#ID;", sc);
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("#ID", System.Data.SqlDbType.Text)).Value = (TextBox)ListView1.FindControl("box1");
cmd.ExecuteNonQuery();
sc.Close();
Response.Redirect("~/Zapasy_seznam.aspx");
}
}
I need take value ID from listview, but with this code I have this error:
...expects the parameter '#ID', which was not supplied....
This part of my listview...
<asp:ListView ID="ListView1" runat="server" DataKeyNames="ID_zapas" DataSourceID="SqlDataSource1" style="text-align: center ">
<AlternatingItemTemplate>
<tr style="background-color: #e9ffe9;color: #284775;text-align:center">
<td>
<asp:TextBox ID="box1" runat="server" Text='<%# Eval("ID_zapas") %>' Visible="false" />
...
<td style="width:50px;background-color:white">
<asp:LinkButton ID="Button1" runat="server" OnClick="Button1_Click" Visible='<%# HttpContext.Current.User.IsInRole("admin") %>' CausesValidation="False" OnClientClick="javascript: return confirm('Opravdu chcete zápas zkopírovat?');">
<asp:Image ID="Image2" runat="server" ImageUrl="~/Icons/copy.png" Width="29px" Height="29px" ToolTip="Zkopírovat zápas" />
</asp:LinkButton>
</td>
</tr>
</AlternatingItemTemplate>
Have you some idea?
As per comments, please try this:
using System.Data.SqlClient;
protected void Button1_Click(object sender, EventArgs e)
{
var box1 = (TextBox)((LinkButton)sender).Parent.FindControl("box1");
using (var sc = new SqlConnection(GetConnectionString()))
{
using (var cmd = sc.CreateCommand())
{
sc.Open();
cmd.CommandText = "SET IDENTITY_INSERT Zapas OFF INSERT INTO Zapas (Zapas.Sezona,.....)SELECT Zapas.Sezona,... FROM Zapas WHERE ID_zapas=#ID;";
cmd.Parameters.AddWithValue("#ID", box1.Text);
cmd.ExecuteNonQuery();
sc.Close();
Response.Redirect("~/Zapasy_seznam.aspx");
}
}
}
When using data-aware controls such as a ListView here, the controls are created with automatic unique IDs per data item. This means that you can have more than 1 of the same control (such as "box1" in this case) within the page that should be referenced by the data item (((LinkButton)sender).Parent which is ListViewDataItem, representing the row).
ListViewDataItem.FindControl will find controls of a specific server ID within its own child scope, allowing you to get values for controls within the same row of the button that is being clicked.
<form>
<asp:Repeater id="rptComments" runat="server">
<HeaderTemplate>
<table class="detailstable FadeOutOnEdit">
<tr>
<th style="width:200px;">Answers</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<th style="width:200px;"><asp:DropDownList ID="dropDownForChecklistAnswers" runat="server" /></th>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
<asp:Button id="button" text="Submit" OnClick="Page_Load" runat="server" />
</FooterTemplate>
</asp:Repeater>
</form>
Code Behind:
List<Checklist_Record_Choice> CLRC =
(from choice in db.Checklist_Record_Choices
select choice).ToList();
dropDownForChecklistAnswers.DataSource = CLRC;
DropDownList1.DataTextField = Text;//Text being the name of column2 in the table (which contains yes, no, n/a)
dropDownForChecklistAnswers.DataBind();
ERROR: dropDownForChecklistAnswers does not exist in the current context???
please advise
EDIT;
thanks for reply. I have
public void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
ClarkeDBDataContext db1 = new ClarkeDBDataContext();
List<string> CLRC =
(from choice in db1.Checklist_Record_Choices
select choice.Text).ToList();
DropDownList ddl = (DropDownList)e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = CLRC;
}
but DropDownList ddl is coming back as object ref not set to instance of an object...why is it null??
You need to use FindControl to access a control which is part of a Repeater's template.
Subscribe to the OnItemDataBound of the Repeater (set the attribute OnItemDataBound="OnReptDataBound")
And then in your code behind do the following
void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item)
{
DropDownList ddl = (DropDownList )e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = ....
Sort listview using column headings in the LayoutTemplate
I am able to sort a basic list view using asp:SqlDataSource and setting the list view property DataSourceID by pointing it to the asp:SqlDataSource ID. I am having an issue when sorting when not using the asp:SqlDataSource and just DataBinding from the code behind.
SqlDataSource Example:
<asp:ListView ID="ContactsListView" DataSourceID="ContactsDataSource" runat="server">
<LayoutTemplate>
<table width="640px" runat="server">
<tr class="header" align="center" runat="server">
<td>
<asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
</LayoutTemplate>
....
</asp:ListView>
<asp:SqlDataSource ID="ContactsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:MainConnString %>"
SelectCommand="SELECT * FROM TableName">
</asp:SqlDataSource>
DataBind Example:
<asp:ListView ID="ContactsListView" DataSourceID="ContactsDataSource" runat="server">
<LayoutTemplate>
<table width="640px" runat="server">
<tr class="header" align="center" runat="server">
<td>
<asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
</LayoutTemplate>
....
</asp:ListView>
protected void Page_Load(object sender, EventArgs e)
{
String SQL = "SELECT * FROM Customer";
SqlDataAdapter da= new SqlDataAdapter(SQL, ConnStr);
DataSet ds = new DataSet();
da.Fill(ds);
ContactsListView.DataSource = ds.Tables[0];
ContactsListView.DataBind();
}
Both code samples populate the list view, but the second example data binding does not work for sorting. With the first example, the sorting just works with the added asp:LinkButton in the LayoutTemplate adding the CommandName="sort" and setting the CommandArugment="ColumnName", but it does not work with the second example.
Can anyone please explain why and how to get the sorting working using the code behind DataBind method?
Thanks!
I solved my issue.
I added an event to handle the sorting. The event grabs the command name (Data column) and passes it and the sorting direction into a function which will make another call to the database sort the returned results and rebind to the List View.
I had to create a view state to hold the List View Sort Direction because for some reason, the onsorting event handler kept saying that the sort direction was ascending.
Front End
<asp:ListView ID="ContactsListView" OnSorting="ContactsListView_Sorting" runat="server">
<LayoutTemplate>
<table width="640px" runat="server">
<tr class="header" align="center" runat="server">
<td>
<asp:LinkButton runat="server" ID="SortByFirstNameButton" CommandName="Sort" Text="First Name" CommandArgument="FirstName" />
</LayoutTemplate>
....
</asp:ListView>
Back End
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindContacts(string.Empty);
}
}
protected SortDirection ListViewSortDirection
{
get
{
if (ViewState["sortDirection"] == null)
ViewState["sortDirection"] = SortDirection.Ascending;
return (SortDirection)ViewState["sortDirection"];
}
set { ViewState["sortDirection"] = value; }
}
protected void ContactsListView_Sorting(Object sender, ListViewSortEventArgs e)
{
BindContacts(e.SortExpression + " " + ListViewSortDirection.ToString());
// Check the sort direction to set the image URL accordingly.
string imgUrl;
if (ListViewSortDirection == SortDirection.Ascending)
ListViewSortDirection = SortDirection.Descending;
else
ListViewSortDirection = SortDirection.Ascending;
}
private void BindContacts(string sortExpression)
{
sortExpression = sortExpression.Replace("Ascending", "ASC");
sortExpression = sortExpression.Replace("Descending", "DESC");
using (SqlConnection conn = new SqlConnection(_connStr))
{
conn.Open();
using (SqlDataAdapter dAd = new SqlDataAdapter("SELECT * FROM Customer", conn))
{
DataTable dTable = new DataTable();
dAd.Fill(dTable);
// Sort now
dTable.DefaultView.Sort = sortExpression;
// Bind data now
ContactsListView.DataSource = dTable;
ContactsListView.DataBind();
}
conn.Close();
}
}
I guess you could try to add a handler for ListView's Sorting event. There you are given the sorting column and the sort order in the event arguments. This could be easily usable to build a specific query and bind it to the list.
Because depending on the sort expression (which you defined in your markup) SqlDataSource will very likely do something like this (I'm not sure this is exactly what it does) for you behind the scenes:
Expression<Func<DataRow,object>> myExpression = row => row["SortExpressionYouDefinedForTheColumn"];
IEnumerable<DataRow> ex = ds.Tables[0].AsEnumerable().OrderBy(myExpression.Compile());
Or SqlDataSource may be using a DataView to sort the DataTable.
SqlDataSource can do this because by default it uses a DataSet to store the result set (or so says the documentation):
The data retrieval mode identifies how a SqlDataSource control retrieves data from the underlying database.
When the DataSourceMode property is set to the DataSet value, data is
loaded into a DataSet object and stored in memory on the server. This
enables scenarios where user interface controls, such as GridView,
offer sorting, filtering, and paging capabilities..
Since you chose to bind manually to a DataSet, you need to do the "magic" yourself; in other words, you handle the OnSort command, get the sort expression, get your data source again (however you do it, from Session or by calling the database again) and do your sort similarly to the lines shown above and rebind to your Gridview.
I want to bind my Listview but I can't. I dont know what I am doing wrong here. When I press ctrl+f5, the page is empty.
My Code is:
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:ListView ID="ListView1" runat="server" DataKeyNames="Student_ID">
<LayoutTemplate>
<table id="itemplaceholderContainer" runat="server">
<tr id="itemplaceholder">
<td>
Student ID :
</td>
<td>
Registration Number :
</td>
<td>
Student Name :
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
StudentID:
<asp:Label ID="LabelID" runat="server" Text='<%Eval("Student_ID") %>'></asp:Label>
StudentRegistrationNumber:<asp:Label ID="LabelNumber" runat="server" Text='<%Eval("StudentRegistrationNumber") %>'></asp:Label>
StudentName:<asp:Label ID="LabelName" runat="server" Text='<%Eval("Name") %>'></asp:Label>
</ItemTemplate>
</asp:ListView>
</asp:Content>
Codebehind is :
protected void Page_Load(object sender, EventArgs e)
{
SqlConnection cn = new SqlConnection(#"Data Source=LOCALHOST;Initial Catalog=ITCF;Integrated Security=True");
SqlCommand cmd = new SqlCommand("Select * from Student", cn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.fill(dt);
ListView1.DataSource = dt;
ListView1.DataBind();
}
try this:
first your item template is worng, and also you need to fill the data adabter form the Data Table
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:ListView ID="ListView1" runat="server" DataKeyNames="Student_ID">
<LayoutTemplate>
<table id="itemplaceholderContainer" runat="server">
<tr id="itemplaceholder">
<td>
Student ID :
</td>
<td>
Registration Number :
</td>
<td>
Student Name :
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
StudentID:
<asp:Label ID="LabelID" runat="server" Text='<%# Eval("Student_ID") %>'></asp:Label>
StudentRegistrationNumber:<asp:Label ID="LabelNumber" runat="server" Text='<%# Eval("StudentRegistrationNumber") %>'></asp:Label>
StudentName:<asp:Label ID="LabelName" runat="server" Text='<%# Eval("Name") %>'></asp:Label>
</ItemTemplate>
</asp:ListView>
</asp:Content>
Codebehind is :
protected void Page_Load(object sender, EventArgs e)
{
SqlConnection cn = new SqlConnection(#"Data Source=LOCALHOST;Initial Catalog=ITCF;Integrated Security=True");
SqlCommand cmd = new SqlCommand("Select * from Student", cn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
ListView1.DataSource = dt;
ListView1.DataBind();
}
The last 3 lines of code in your code-behind tell the whole story:
DataTable dt = new DataTable();
ListView1.DataSource = dt;
ListView1.DataBind();
You're instantiating a new, empty DataTable and binding ListView1 to it. Thus, behaving correctly and exactly as designed, your ListView is displaying zero records from the empty DataTable.
You'll want to fetch the data from the DataAdapter before you bind anything to it. Something like this:
var students = new DataSet();
da.Fill(students, "Student");
if (students.Tables.Count == 1)
{
ListView1.DataSource = students.Tables[0];
ListView1.DataBind();
}
Note: There may be a more direct way to fetch the DataTable. I haven't worked with DataSets and DataTables in a long time, but .Fill() may be able to directly use a DataTable and skip my checking of a valid table in the DataSet above.)
Your datatable is never getting populated. Have a look at the following:
http://msdn.microsoft.com/en-us/library/bh8kx08z.aspx