Databinding in C# - c#

Can someone help me databind? I'm new to .net and c# and am following tutorials that are only getting me half way there. The aspx is the following:
<asp:Repeater ID="rptContent" runat="server">
<HeaderTemplate>
<table>
<thead>
<tr>
<th>T</th>
<th>L</th>
<th>S</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("T") %></td>
<td><%# Eval("L")%></td>
<td><%# Eval("S")%></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
But on the back end I don't know how to actually bind the data. If there is a tutorial someone can send me to follow for this part I'd appreciate it or if you can explain that would be great.
public List<Sample> Results()
{
List<Sample> List = new List<Sample>();
myList.Add(new Sample { Title = "Title
1", Link = "/item.aspx?id=1", Summary = "summary
for Item 1" });
return List;
}
public class Content
{
public string T
{
get;
set;
}
public string L
{
get;
set;
}
public string S
{
get;
set;
}
}

Can you bind directly the list of Sample? or you do need to bind it to the class Content?
The important here is: in the markup, when you use Eval(""), you have to provide the exact name of the property of the object you are binding.
If you can use the list of Sample I would do the following
ASPX:
<asp:Repeater ID="rptContent" runat="server">
<HeaderTemplate>
<table>
<thead>
<tr>
<th>T</th>
<th>L</th>
<th>S</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("Title") %></td>
<td><%# Eval("Link")%></td>
<td><%# Eval("Summary")%></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
and in Code-Behind:
protected void Page_Load(object sender, EventArgs e)
{
rptContent.DataSource = Results();
rptContent.DataBind();
}
public List<Sample> Results()
{
List<Sample> List = new List<Sample>();
myList.Add(new Sample { Title = "Title
1", Link = "/item.aspx?id=1", Summary = "summary
for Item 1" });
return List;
}

The collection you assign to the data source of your repeater needs to be a collection of items containing the properties you're intending to bind to.
The individual items in your Results collection do not directly possess L, T, & S properties so in binding this collection to your repeater, the repeater cannot find those properties. In your case, you'll need to bind to a collection of Content objects:
List<Content> contentResults = new List<Content>();
contentResults.Add(new Content(){L="el", T="tee", S="es"});
rptContent.DataSource = contentResults;
rptContent.DataBind();

Related

ListView DataBind Sorting Values

I want to have a DropdownMenu from which i can choose how i want to sort my ListView.
This is my current code for it :
<asp:DropDownList ID="DropDownSelect" runat="server" AutoPostBack="True"
OnSelectedIndexChanged="GetProducts">
<asp:ListItem Selected="True" Value="DesDate"> Descending Date </asp:ListItem>
<asp:ListItem Value="AsDate"> Ascending Date </asp:ListItem>
<asp:ListItem Value="AsAlp"> Ascending Alphabetical </asp:ListItem>
<asp:ListItem Value="DesAlp"> Decentind Alphabetical </asp:ListItem>
</asp:DropDownList>
And I have this ListView to display my data:
<asp:ListView ID="productList" runat="server"
DataKeyNames="NewsID" GroupItemCount="1"
ItemType="SiteStiri.Models.News" SelectMethod="GetProducts">
<EmptyDataTemplate>
<table>
<tr>
<td>No data was returned.</td>
</tr>
</table>
</EmptyDataTemplate>
<EmptyItemTemplate>
<td/>
</EmptyItemTemplate>
<GroupTemplate>
<tr id="itemPlaceholderContainer" runat="server">
<td id="itemPlaceholder" runat="server"></td>
</tr>
</GroupTemplate>
<ItemTemplate>
<td runat="server">
<table>
<tr>
<td>
<a href="NewsDetails.aspx?newsID=<%#:Item.NewsID%>">
<img src="/Catalog/Images/Thumbs/<%#:Item.ImagePath%>"
width="100" height="75" style="border: solid" /></a>
</td>
</tr>
<tr>
<td>
<a href="NewsDetails.aspx?newsID=<%#:Item.NewsID%>">
<p style="color: black;">
<%#:Item.NewsTitle%>
</p>
</a>
</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
</p>
</td>
</ItemTemplate>
<LayoutTemplate>
<table style="width:100%;">
<tbody>
<tr>
<td>
<table id="groupPlaceholderContainer" runat="server"
style="width:100%">
<tr id="groupPlaceholder"></tr>
</table>
</td>
</tr>
<tr>
<td></td>
</tr>
<tr></tr>
</tbody>
</table>
</LayoutTemplate>
</asp:ListView>
The thing that i have no idea how to do is:
After selecting a sorting rule from the dropdown menu, i can't figure out how to write(or where to write) the method that would update my ListView as it should. My attemp is :
public IQueryable<News> GetProducts()
{
var _db = new SiteStiri.Models.NewsContext();
IQueryable<News> query = _db.News;
if (("DesDate").Equals(DropDownSelect.SelectedItem.Value))
{
query.OrderByDescending(u => u.ReleaseDate);
}
if (("AsDate").Equals(DropDownSelect.SelectedItem.Value))
{
query.OrderBy(u => u.ReleaseDate);
}
if (("AsAlp").Equals(DropDownSelect.SelectedItem.Value))
{
query.OrderBy(u => u.NewsTitle);
}
if (("DesApl").Equals(DropDownSelect.SelectedItem.Value))
{
query.OrderByDescending(u => u.NewsTitle);
}
return query;
}
which gives me a bunch of errors and it doesn't even work .... a little bit of help please? I am new to this (2 days).
Let's fix your code step by step.
Event handlers need to have a certain signature. In case of every ASP.NET control I can remember of, they need to receive two parameters, event arguments and event source object, and return void. Also note that just calling GetProduct is not going to update ListView, we need to trigger databinding for the control itself. We'll get to that later. For now let's introduce a proper handler:
public void DropDownSelect_SelectedIndexChanged(object sender, EventArgs e)
Don't forget to update markup as well:
OnSelectedIndexChanged="DropDownSelect_SelectedIndexChanged"
The conditions on how you show data in the ListView have changed. That means that you need to rebind it with calling DataBind, which should call GetProducts (as a one specified in SelectMethod):
public void DropDownSelect_SelectedIndexChanged(object sender, EventArgs e)
{
productList.DataBind();
}
Finally in GetProducts note that LINQ calls do not update the current object, but rather they produce new one every time. So you should have something like this:
if ("DesDate".Equals(DropDownSelect.SelectedItem.Value))
{
query = query.OrderByDescending(u => u.ReleaseDate);
}
I am guessing you want the data and not the query right? That code would look like this, all you have to do is parse the selected value and pass it into the method. If the ListView is bound to the data (and it should be) you're all set. This example shows the separation of concerns, whereby the view is just a framework for HOW to show the data, and the code behind is a framework for WHAT data is supplied based on triggers from the view. The trigger in this case is the "filter" parameter.
List<News> query = _db.News.ToList();
public List<News> GetProduct(string filter) {
if (filter == "DesDate") return query.OrderByDescending(u => ReleaseDate).ToList();
}
One last note: IQueryable is a class that lets you pass queries around, you can alter the query itself from method to method. But this class does not produce results until it is told to do so by using any of the To methods like ToList(), ToArray(), ToLookup() and or any attempt to iterate over it such as:
Foreach(var thing in MyQuerable){ //results are here }

Filtering values from a Datatable to be transferred to another Datatable

I have a Datatable that has a checkbox and a value, What I want is that when I click a button it would get all the checked boxes and their corresponding value and Add them to a blank Datatable. I not planning to save the data moved from 1 list to another, as there will be another functionality to confirm if I want to save the changes(not being asked in this question).
This is my html code:
<asp:ListView runat="server" ID="uoListViewAirportSaved" EmptyDataText="No Data Found">
<LayoutTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="500px">
<tr>
<th runat="server"> </th>
<th runat="server">Airport</th>
</tr>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td class="leftAligned">
<asp:CheckBox ID="uoCheckBoxSelect" runat="server" />
</td>
<td class="leftAligned">
<asp:HiddenField ID="uoHiddenFieldAirport" runat="server" Value='<%# Eval("ColAirportCodeVarchar") %>' />
<asp:Label ID="uoLabelAirport" runat="server" Text='<%# Eval("colAirportFullName")%>' />
</td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="500px">
<tr>
<td>Airport</td>
</tr>
<tr>
<td colspan="3" class="leftAligned">No Record</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:ListView>
And the code when I click the add button:
private void AddAirport() {
CheckBox uoCheckBoxSelect;
HiddenField uoHiddenFieldAirport;
Label uoLabelAirport;
DataTable dt = new DataTable();
DataTable dt2 = new DataTable();
DataTable dt3 = new DataTable();
string serviceProvider = GlobalCode.Field2String(Request.QueryString["pid"]);
///datatable with all list of airports
dt = VendorMaintenanceBLL.GetServiceProviderAirportbyBrand(serviceProvider);
///datatable with provider's current airports
dt2 = VendorMaintenanceBLL.GetServiceProviderAirportbyVendor(serviceProvider);
foreach(ListViewItem item in uoListViewAirport.Items)
{
uoCheckBoxSelect = (CheckBox)item.FindControl("uoCheckBoxSelect");
if (uoCheckBoxSelect.Checked == true)
{
uoHiddenFieldAirport = (HiddenField)item.FindControl("uoHiddenFieldAirport");
uoLabelAirport = (Label)item.FindControl("uoLabelAirport");
/// my new list should contain the values from the checked values of the checkboxes
???
}
}
}
My Datatable contains the AirportID and the AirportStringName columns.
I found a code that I'm trying to replicate, logic-wise. However it is designed for a list:
List<AirportDTO> listToBeAdded = new List<AirportDTO>();
List<AirportDTO> listAdded = new List<AirportDTO>();
listToBeAdded = GetAirportNotInUser(false, false);
listAdded = GetAirportInUser(false);
foreach (ListViewItem item in uoListViewAirport.Items)
{
uoCheckBoxSelect = (CheckBox)item.FindControl("uoCheckBoxSelect");
if (uoCheckBoxSelect.Checked == true)
{
uoHiddenFieldAirport = (HiddenField)item.FindControl("uoHiddenFieldAirport");
uoLabelAirport = (Label)item.FindControl("uoLabelAirport");
var listToAdd = (from a in listToBeAdded
where a.AirportIDString == GlobalCode.Field2String(uoHiddenFieldAirport.Value)
select new
{
AirportID = a.AirportIDString,
AirportName = a.AirportNameString,
}).ToList();
}
}
I do not know how I would get the necessary data from the datatable as it is different from a list. Is there a way for me to do the same thing with DataTables the way lists were tackled.
Since I really need to fix the problem yesterday, I decided to do the following.
What I did was just basic for loop, then inside compare each row and then just use Datatable.ImportRow and DataTable.RemoveAt. I also added a temporary Datatable for the changed lists.
foreach(ListViewItem item in uoListViewAirport.Items)
{
uoCheckBoxSelect = (CheckBox)item.FindControl("uoCheckBoxSelect");
if (uoCheckBoxSelect.Checked == true)
{
uoHiddenFieldAirport = (HiddenField)item.FindControl("uoHiddenFieldAirport");
uoLabelAirport = (Label)item.FindControl("uoLabelAirport");
string HiddenFieldAirport = GlobalCode.Field2String(uoHiddenFieldAirport.Value);
for (var f = 0; f < dt.Rows.Count; f++ )
{
if (dt.Rows[f]["colAirportIDInt"].ToString() == HiddenFieldAirport)
{
dt3.ImportRow(dt.Rows[f]);
dt.Rows.RemoveAt(f);
}
}
}
}
The code is dirty, plus I had to sort it as well, but since I really needed it, I can make do with this.

Get subitem value in radlistview items

here is my listview
<telerik:RadListView runat="server" ID="lvAllUsers" Width="30px">
<ItemTemplate>
<table>
<tr>
<td >
<asp:CheckBoxList ID="cbID" runat="server" CssClass="item" Font-Size="15px" RepeatDirection="Horizontal">
<asp:ListItem Text=" " > </asp:ListItem>
</asp:CheckBoxList></td>
<td style="padding-bottom:10px"><%# Eval("FirstName") %></td>
<td style="padding-bottom:10px"><%# Eval("FamilyName") %></td>
</tr>
</table>
</ItemTemplate>
</telerik:RadListView>
how can I get checkboxlists item text at code behind ? or how can I get FirstName and FamilyName and code behind after I binded my data at pageload?
I can't use
foreach (Telerik.Web.UI.RadListViewItem item in lvAllUsers.Items) {
var cb = item.FindControl(index);
}
because index is equals an id normally. But in item template id is not equal to cbID. When item template iteratives, id is changing. I need get FirstName and FamilyName or checkboxlists item at codebehind (c# only not js). How can I do that?
I find the solution. It's seems like a little long way but it works.
foreach (Telerik.Web.UI.RadListViewItem item in lvAllUsers.Items)
{
if (((System.Web.UI.WebControls.CheckBoxList)(((System.Web.UI.Control)(item)).Controls[1])).Items[0].Selected)
{
ccUserNames.Add(((System.Web.UI.WebControls.Label)(((System.Web.UI.Control)(item)).Controls[7])).Text);
}
}

Fill dropdown list in casceding way and set each dropdown list before its first value

In my project I am making one form which contains three dropdown lists each for company,department and vacancies with "Select" as their default text. I am feeling company dropdown list at form load event but default text is "Select" now when user select company, second list should be filled with departments of selected company but default text should be "select". Again when user select department,the third list should be filled with vacancies on the selected department of selected company but default text should be "select".
I am trying to fill other two dropdown list with "selected index change" event of company list and department list respectively. but its not working as I want.
Here is my code for .aspx page.
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<table width="100%">
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td align="center" class="tdtitle" colspan="4">
Search Candidates
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td class="RowHeight" width="20%">
Select Company</td>
<td width="30%">
<asp:DropDownList ID="companyList" runat="server" AutoPostBack="True"
onselectedindexchanged="companyList_SelectedIndexChanged" Width="150px">
<asp:ListItem>-Select Company-</asp:ListItem></asp:DropDownList>
</td>
<td width="20%">
Select Department</td>
<td width="30%">
<asp:DropDownList ID="deptList" runat="server" AutoPostBack="True"
Width="150px" onselectedindexchanged="deptList_SelectedIndexChanged" onclick="Validate();">
<asp:ListItem>-Select Department-</asp:ListItem></asp:DropDownList>
</td>
</tr>
<tr>
<td class="RowHeight" width="20%">
Select Vacancy</td>
<td colspan="3" width="*">
<asp:DropDownList ID="vacanyList" runat="server" Width="200px">
<asp:ListItem>-Select Vacancy-</asp:ListItem></asp:DropDownList>
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td align="center" colspan="4">
<asp:Label ID="notifyLbl" runat="server" Font-Size="Large" ForeColor="Red"
Text="Label"></asp:Label>
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
</table>
<script type="text/javascript">
function alertOnBadSelection() {
var select = document.getElementById('companyList');
if (select.options[select.selectedIndex].value == "-Select Company-") {
alert('Please Select Company!');
return false;
}
}
</script>
</asp:Content>
/And below is the code for my .aspx.cs page
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
public partial class HR_Department_searcAppForVac : System.Web.UI.Page
{
DataOperation oDo = new DataOperation();
protected void Page_Load(object sender, EventArgs e)
{
// deptList.Attributes.Add("onchange", "alertOnBadSelection();");
notifyLbl.Visible = false;
if (!IsPostBack)
{
try
{
DataTable objCmpnyTable = oDo.DropDownList("select * from tblCompanyMaster");
if (objCmpnyTable.Rows.Count > 0)
{
foreach (DataRow Row in objCmpnyTable.Rows)
{
companyList.Items.Add(new ListItem(Row["CompName"].ToString(), Row["CompId"].ToString()));
}
}
else
{
notifyLbl.Visible = true;
notifyLbl.Text = "There is not any company in the list.";
}
}
catch (Exception)
{
throw;
}
}
else
{
//deptList.SelectedIndex = -1;
//vacanyList.SelectedIndex = 1;
}
}
protected void companyList_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (companyList.SelectedIndex > 0)
{
deptList.Items.Clear();
string str = "select * from vwCompWiseList where CompId=" + companyList.SelectedValue;
DataTable objDeptTable = oDo.DropDownList("select DeptId,DeptName from vwCompWiseDept where CompId= "+companyList.SelectedValue);
if (objDeptTable.Rows.Count > 0)
{
foreach (DataRow Row in objDeptTable.Rows)
{
deptList.Items.Add(new ListItem(Row["DeptName"].ToString(), Row["DeptId"].ToString()));
}
}
}
else
{
notifyLbl.Visible = true;
notifyLbl.Text = "Select Company....";
}
}
catch (Exception)
{
throw;
}
}
protected void deptList_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (deptList.SelectedIndex > 0)
{
vacanyList.Items.Clear();
DataTable objVacancytbl = oDo.DropDownList("select VacId,VacTitle from tblVacancyMaster where DeptId =" + deptList.SelectedValue + " and CompId=" + companyList.SelectedValue);
if (objVacancytbl.Rows.Count > 0)
{
foreach (DataRow Row in objVacancytbl.Rows)
{
vacanyList.Items.Add(new ListItem(Row["VacTitle"].ToString(), Row["VacId"].ToString()));
}
vacanyList.SelectedIndex = -1;
vacanyList.ClearSelection();
}
else
{
notifyLbl.Visible = true;
notifyLbl.Text = "Ops..!There is no available vacancy....";
}
}
else
{
notifyLbl.Visible = true;
notifyLbl.Text = "Select Department...";
}
}
catch (Exception)
{
throw;
}
}
}
Please show my problem and its solutions.
I think you may want to leverage jquery cascading drop downs . Using a cascading drop down javascript (jquery) will call back and reload dependent drop downs based on the value(s) selected in the previous drop down.

Optimize asp.net C# code for repeaters using a table

On the aspx:
<table>
<tr>
<asp:Repeater ID="rptHeader" runat="server">
<ItemTemplate>
<th><%#Eval("Category")%></th>
</ItemTemplate>
</asp:Repeater>
</tr>
<tr>
<asp:Repeater ID="rptContents" runat="server">
<ItemTemplate>
<td valign="top">
<%#Eval("Content")%>
</td>
</ItemTemplate>
</asp:Repeater>
</tr>
</table>
On the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
rptHeader.DataSource = DataSource;
rptHeader.DataBind();
rptContentBlocks.DataSource = DataSource;
rptContentBlocks.DataBind();
}
The problem here is that instead of using Two repeaters, can we use only one?
We actually need the header to be separated from the contents using a different table row...
Edit: changed rptHeader's ItemTemplate's html element from <td> to <th> to be a little clearer. :-)
IMO it's impossible without repeater hacking. Anyway, there is a rather irregular approach that maybe works. Also you can use two foreach statements instead of repeaters.
Code
protected string[] headers = { "A", "B", "C", "D" };
protected string[] contents = { "Alpha", "Beta", "Counter", "Door" };
//string[] headers = { "A", "B", "C", "D" };
//string[] contents = { "Alpha", "Beta", "Counter", "Door" };
//DataList1.RepeatColumns = headers.Length;
//DataList1.DataSource = headers.Concat(contents);
//DataList1.DataBind();
Html markup
<table>
<tr>
<%foreach (string item in headers)
{ %>
<th><%= item %></th>
<% } %>
</tr>
<tr>
<%foreach (string item in contents)
{ %>
<td><%= item %></td>
<% } %>
</tr>
</table>
<!--
<asp:DataList ID="DataList1" runat="server" RepeatDirection="Horizontal">
<ItemTemplate>
<%# Container.DataItem %>
</ItemTemplate>
</asp:DataList>
-->
An HTML table is always declared as cells nested within rows, i.e.
<table>
<tr>
<td>
...
</td>
</tr>
</table>
rather than
<table>
<td>
<tr>
...
</tr>
</td>
</table>
This means you won't be able to write a single Category followed by a single Content. You will have to repeate the Category values and then the Content values as you are already doing.
I see nothing wrong with the approach you are using. The use of 2 repeaters rather than one should be a negligible overhead.
The alternative would be to nest a table within each column. This would allow you to use just a single repeater but the resulting HTML would be rather contrived and bloated. I would not recommend this approach but somehow I can't stop myself from providing an example.
<table>
<tr>
<asp:Repeater ID="rptHeader" runat="server">
<ItemTemplate>
<td>
<table>
<tr>
<td valign="top">
<strong><%#Eval("Category")%></strong>
</td>
</tr>
<tr>
<td valign="top">
<%#Eval("Content")%>
</td>
</tr>
</table>
</td>
</ItemTemplate>
</asp:Repeater>
</tr>
</table>
If it's important to place the content in a table, then you could "rotate" your table into a different structure and bind on that structure. Or if it's not important that the data is in a table, you could place the items in divs and float them so they're side-by-side.
Edit:
Here's what I mean by rotating the data. If your data is currently in a structure like List<MyDataClass>, where MyDataClass is defined as something like:
class MyDataClass
{
public string Category { get; set; }
public string Content { get; set; }
public int OtherField { get; set; }
}
...then the logical layout when iterating through the structure would look like this:
MyDataClass[0]: Category, Content, OtherField
MyDataClass[1]: Category, Content, OtherField
...
When rotating the data, you'd turn those rows into columns and columns into rows. For example, you could populate a List<List<string>> with code such as this:
var rotated = new List<List<string>> {
new List<string>(), new List<string>(), new List<string>(),
};
for each (MyDataClass object in myCollection)
{
rotated[0].Add(object.Category);
rotated[1].Add(object.Content);
rotated[2].Add(object.OtherField.ToString("n0"));
}
Now your data structure looks like this:
rotated[0]: MyDataClass[0].Category, MyDataClass[1].Category, ...
rotated[1]: MyDataClass[0].Content, MyDataClass[1].Content, ...
rotated[2]: MyDataClass[0].OtherField, MyDataClass[1].OtherField, ...
Basically, you transform the data into a form that can be dropped right into your table.
Edit 2:
I actually have to do these sorts of rotations for reports often enough that I made an extension method for IEnumerable that will do the rotation in a somewhat more elegant manner. Here's the extension method:
public static class MyCollectionExtensionMethods
{
public static IEnumerable<IEnumerable<TResult>> Rotate<TOrig, TResult>(
this IEnumerable<TOrig> collection,
params Func<TOrig, TResult>[] valueSelectors)
{
return valueSelectors.Select(s => collection.Select(i => s(i)));
}
}
And here's how I'd use it:
IEnumerable<IEnumerable<string>> rotated = data.Rotate(
i => i.Category, i => i.Content, i => i.OtherField.ToString("n0"))
Correct me if i misunderstood but it sounds to me like you could use only one repeater, integrating your first repeater into a HeaderTeplate tag and the second into the ItemTemplate.

Categories