Build Listview from Code behind - c#

I have a large table that can have many null, empty or false columns. I only want to show the columns that are worth showing.
Here is a sample of the query and how I am trying to build up the listview:
var query = (from q in db.tblIncidents
where q.Id == searchQuery
select new
{
q.victim,
q.reportedByVictimPostCode
}).ToList();
lst_Results.DataSource = query;
lst_Results.DataBind();
foreach (var colitem in query)
{
if (!colitem.victim == false)
{
** Help required here please **
lst_Results.Items.Add(new ListViewDataItem(0,1));
}
}
I did start off building my list view on the aspx page, but realised that the result would be lots of empty fields and a waste of time for the user seeing nothing if the user hadn't entered any thing.
What I want to do is achieve this but in the code behind by querying if there is a result to display.
<ItemTemplate>
<tr>
<td>Incident Id:</td>
<td>
<asp:Label ID="lbl_CustomerId" runat="server" Text='<%# Eval("Id") %>' />
</td>
</tr>
<tr>
<td>Reported by the Victim:</td>
<td>
<asp:Label ID="lbl_victim" runat="server" Text='<%# Eval("victim") %>' />
</td>
</tr>
</ItemTemplate>
Would I use something like so?
lst_Results.InsertItem.DataItem(colitem.victim);
Which I get the error method delegate or event expected?
Does it know to insert into the listItem template?
I have a layout template with the itemPlaceholder. The listview works ok just want to target it from code behind.

Related

Get specific item from Repeater in code behind

I have an ASP.NET WebForms project that displays data read from a database via a Repeater. The code for the repeater looks like this:
<asp:Repeater ID="repRMAproduct" runat="server">
<ItemTemplate>
<tr>
<td>
<%# Eval("Description") %>
</td>
<td>
<%# Eval("Qty") %>
</td>
<td>
<asp:TextBox ID="tbNewQty" runat="server"></asp:TextBox>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
What I want is for the user to enter a new Quantity only on the rows that he wants to enter. Then, when he clicks the save button, I can read these new Quantities along with their associated Descriptions.
In MVC I should build the URL using jQuery and pass it to the Controller. But in WebForms it seems less intuitive. Where do I go from here?
In your save-button-click event handler you can loop all items and get the TextBox with FindControl:
foreach(RepeaterItem item in repRMAproduct.Items)
{
TextBox tbNewQty = (TextBox) item.FindControl("tbNewQty");
string newQuantity = tbNewQty.Text.Trim();
int quantity;
if(int.TryParse(newQuantity, out quantity))
{
SaveNewRmaQuantity(product, quantity);
};
}
If you'd use a Label for your product-description you can use FindControl("LblDescriptionId") to get it and to pass it's Text to SaveNewRmaQuantity. You can also use invisible controls(Visible=false), f.e. a Label, to store the ProductId.

Use ListView control to display data but join a reference table

I'm really new to ASP.NET and I've looked at countless tutorials trying to figure this out but can't seem to get my head around it. I can successfully output records from tbProject using ListView and the Entity Framework but instead of the refDepartmentID, I want to display refDepartmentValue from the refDepartment table. Here is a quick table structure.
tbProject
-ProjectID
-refDepartmentID
-ProjectName
refDepartment
-refDepartmentID
-refDeparmentValue
I can write this in SQL no problem with a JOIN but I don't know where I'd put it. I've played around with LINQ a bit and it seems like this is how I'm going to accomplish this. Maybe write the LINQ in the code behind file then bind it to the ListView control, maybe?
Here's the ListView control:
<asp:ListView runat="server"
DataSourceID="EntityDataSource1">
<ItemTemplate>
<tr style="">
<td>
<asp:Label ID="ProjectIDLabel" runat="server" Text='<%# Eval("ProjectID") %>' />
</td>
<td>
<asp:Label ID="refDepartmentIDLabel" runat="server"
Text='<%# Eval("refDepartmentID") %>' />
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table runat="server">
<tr runat="server">
<td runat="server">
<table ID="itemPlaceholderContainer" runat="server" border="0" style="">
<tr runat="server" style="">
<th runat="server">
ProjectID</th>
<th runat="server">
refDepartmentID</th>
</tr>
<tr ID="itemPlaceholder" runat="server">
</tr>
</table>
</td>
</tr>
<tr runat="server">
<td runat="server" style="">
</td>
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
Here's how I'm using the EF to populate a dropdownlist so you can at least refer to how things are named.
// populates Departments dropdownlist
using (dbOrganizationEntities1 myEntities = new dbOrganizationEntities1())
{
var allDepartments = from refDepartments in myEntities.refDepartments
select refDepartments;
ddlDepartments.DataSource = allDepartments;
ddlDepartments.DataValueField = "refDepartmentID";
ddlDepartments.DataTextField = "refDepartmentValue";
ddlDepartments.DataBind();
}
Any help would be appreciated. Thanks!
Disclaimer, I did this in my head without Visual Studio, so it might have a minor syntax error. Let me know if it does.
You need to do two things, First you must join your tbProject to refDepartments Entites using an inner (or outer) join as needed, depending on your desired behavior. One you have the two tables joined in LINQ, you want to create a new anonymous class using "select new" operator which creates it. The members of this new class will be created based on the datatypes of the Entities they are selected from.
using (dbOrganizationEntities1 myEntities = new dbOrganizationEntities1())
{
var allDepartments = (from tbProject in myEntities.tbProjects
// inner join to department lookup table
from refDepartments in myEntities.refDepartments.Where(x=>x.refDepartmentID == tbProject.refDepartmentID) // to do a left join instead of an inner, append .DefaultIfEmpty() after this where clause
// select new anon type
select new {
refDepartmentID = tbProject.refDepartmentID,
ProjectName = tbProject.ProjectName,
refDepartmentValue = refDepartments.refDepartmentValue,
}).ToList(); // I chose to turn the result into a list to demonstrate something below, you can leave it as an enumerable.
// you can access the properties of the anon type like so
System.Diagnostics.Debug.Print(allDepartments[0].refDepartmentID);
System.Diagnostics.Debug.Print(allDepartments[0].refDepartmentValue);
// bind to your listview, make sure control name is accurate and ItemTemplates are defined for each data column.
MyListView.DataSource = allDepartments;
MyListView.DataBind();
}

Populating a listbox control in asp.net

I have a code block that returns a list of employee object.
The resultset contains more than one employee record. One of the elements, is EmployeeID.
I need to populate listview (lstDepartment) with only the EmployeeID. How can I do that?
lstDepartment.DataSource = oCorp.GetEmployeeList(emp);
lstDepartment.DataBind()
You have to also specify this:
lstDepartment.DataSource = oCorp.GetEmployeeList(emp);
lstDepartment.DataTextField = "EmployeeID";
lstDepartment.DataValueField = "EmployeeID";
lstDepartment.DataBind()
One way would be to use an anonymous type:
lstDepartment.DataSource = oCorp.GetEmployeeList(emp)
.Select(emp => new { emp.EmployeeID });
lstDepartment.DataBind();
Edit: But you also could select all columns but diplay only one. A ListView is not a ListBox or DropDownList. Only what you use will be displayed. So if you're ItemTemplate looks like:
<ItemTemplate>
<tr runat="server">
<td>
<asp:Label ID="LblEmployeeID" runat="server" Text='<%# Eval("EmployeeID") %>' />
</td>
</tr>
... only the EmployeeID is displayed, no matter whatelse is in your DataSource.
You may mention what to display in your ItemTemplate of ListView
<asp:ListView ID="lstDepartment" runat="server">
<ItemTemplate>
<p> <%#Eval("EmployeeID") %> </p>
</ItemTemplate>
</asp:ListView>

ItemCommand event doesn't fire with repeater control

I am building a website whereby people, before checking out of the shopping cart (and transferring to the payment iframe) can select which items from the shopping cart list to delete. The results from the shopping card are listed in a Repeater control. There is a Button in the Repeater which deletes a record from the database (used LINQ to SQL to do that.)
The problem is that the ItemCommand event doesn't fire when i click the button. I tried response.write(test) and it still would not work.
It is as if the repeater cannot interact with the commands. It does render the results though.
<asp:Repeater ID="RepeaterKoshnichka"
runat="server" OnItemCommand="RepeaterKoshnichka_ItemCommand"
DataSourceID="LinqDataSource1">
<ItemTemplate>
<tr>
<td background="images/message-bar.gif">
<div class="message_head" style="float:left"><cite>Производ: <asp:Label ID="lblProizvod" CssClass="red_tx" Text='<%# Eval("Proizvod") %>' runat="server"></asp:Label> / Тип на Претплата: <asp:Label ID="lblPretplata" runat="server" Text='<%# Eval("Tip") %>' CssClass="red_tx"></asp:Label></cite></div>
<div class="message_head" style="float:right"><cite>Цена: <asp:Label ID="lblCena" CssClass="red_tx" Text='<%# Eval("Cena") %>' runat="server"></asp:Label>
<asp:Button ID="Button2" CssClass="main_tx" CommandName="Delete" CommandArgument='<%# Eval("NDetID") %>' runat="server" Text="Отстрани" /></cite>
</div>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
protected void RepeaterKoshnichka_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
if (Request.Form[e.CommandArgument.ToString()] != null)
{
if (Page.User.Identity.IsAuthenticated)
{
var nar = new DataClasses1DataContext();
Guid detnar = new Guid(e.CommandArgument.ToString());
var query = from c in nar.Naracka_Dets
where c.NDetID == detnar
select c;
foreach (var c in query)
{
nar.Naracka_Dets.DeleteOnSubmit(c);
}
nar.SubmitChanges();
lblSuma.Text = ((Button)e.CommandSource).ToString();
}
}
}
}
Likely an <asp:GridView> would be a better server control for what you're working on.
As an aside, consider making a small change to your code. To help make it more readable, combine your 3 conditions into one if:
if (e.CommandName == "Delete" &&
Request.Form[e.CommandArgument.ToString()] != null &&
Page.User.Identity.IsAuthenticated)
{
//delete things.
}
If you are not tied to using a Repeater you should switch to DataGrid and use a ButtonColumn for this feature - it will make life easier for you handling Item events.

textbox not displaying in code behind c# file

I have a sales simulator written in C#. I did not write this however I am currently modifying it to suit different requirements.
It basically displays a list of products from a database, and has a textbox for each product where you can enter in the quantity sold. The quantity sold is calculated based on it's price in the database.
Now it's all working fine, however there is one SMALL issue. When "Buy" is clicked, it returns me back to the list of products which IS correct, however the quantity I have entered for the previous product remains.
I would like to know how to restore the text boxes to their default value when the after the data is submitted to the database.
I always thought the way to do this would be in the .cs code behind file
txtQuantity.Text = "";
However, for some odd reason, txtQuantity will not show up.
Can anyone think of anything I am doing wrong? Here is a snippet of code from the aspx file.
<form id="form1" runat="server">
Date:
<asp:TextBox ID="txtDate" runat="server" />
Retailer:
<asp:DropDownList ID="dlStore" runat="server"
onselectedindexchanged="dlStore_SelectedIndexChanged" />
<asp:ListView ID="lbProducts" runat="server">
<LayoutTemplate>
<layouttemplate>
<table border="1" cellpadding="1" style="width:800px">
<tr style="background-color:#E5E5FE">
<th>ID</th>
<th>ProductCode</th>
<th>Product Title</th>
<th>RRP $</th>
<th>Quantity</th>
<th>Sale Price $</th>
</tr>
<tr id="itemPlaceholder" runat="server"></tr>
</table>
</layouttemplate>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td style="width: 50px;">
<%#Eval("ProductID") %>
</td>
<td>
<%#Eval("ProductCode") %>
</td>
<td>
<%#Eval("ProductTitle") %>
</td>
<td>
<%#Eval("USListPrice") %>
</td>
<td style="width: 50px;">
<asp:TextBox ID="txtQuantity" runat="server" Text="0" />
</td>
<td style="width: 50px;">
<asp:TextBox ID="txtSalePrice" runat="server" Text="0.00" />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:Button ID="btnBuy" Text="Buy These Items" runat="server" OnClick="btnBuy_Click" />
<asp:Button ID="btnClear" Text="Clear Existing Sales" runat="server"
onclick="btnClear_Click" />
</form>
There's a lot going on in the code behind file and I wouldn't expect anyone to go through it, but how I collect the data from txtQuantity is done with the following line of code:
Int32 quantity = Int32.Parse(((TextBox)item.FindControl("txtQuantity")).Text);
So what I want to be able to do is set this textbox either to be empty, or back to zero.
Any help is appreciated, thanks.
Because that txtQuantity control is within a ListView, there could be any number of instances of that control generated. So you can't access all of them through a single variable.
You will need to look through all controls within that ListView (and several levels deep) to find all your txtQuantity controls.
The same of course for the txtSalePrice control.
EDIT
You could find those textboxes with code like (untested)
public IEnumerable<TextBox> FindTextBoxes(Control parent)
{
if (parent == null) yield break;
foreach (Control child in parent.Controls)
{
TextBox tb = child as TextBox;
if (tb != null)
yield return tb; // found one!
else
foreach(TextBox tb in FindTextBoxes(child))
yield return tb; // found it deeper
}
}
and call it like:
foreach(TextBox tb in FindTextBoxes(lbProducts)
{
if (tb.Name == "txtQuantity")
{
// found a quantity
}
else if (tb.Name == "txtSalePrice")
{
// found the salesprice
}
}

Categories