Databind List of Dictionnary into a GridView - asp.net

I'd like to bind a List of Dictionary to a GridView.
var liste = new List<Dictionary<string, string>>();
var dictionary = new Dictionary<string,string>();
dictionary["Id"] = "111";
dictionary["Description"] = "text to show";
dictionary["OtherInfo"] = "other text";
liste.Add(dictionary);
gvClients.DataSource = liste;
gvClients.DataBind();
The code in the aspx :
<asp:GridView ID="gvClients" runat="server" AutoGenerateColumns="true" GridLines="None"
AllowPaging="True" CssClass="gridview" AlternatingRowStyle-CssClass="alt" Width="80%">
<AlternatingRowStyle CssClass="alt"></AlternatingRowStyle>
<Columns>
<asp:TemplateField HeaderText="PropertyName">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Description") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="PropertyName">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("OtherInfo") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
How can I bind the GridView to that Object (or a System.Collections.HashTable).
edit
The geek's solution for Dictionary work but not for HashTable, is there a solution ?
var liste = new List<System.Collections.Hashtable>();
var table = new System.Collections.Hashtable();
table["Denomination"] = "a";
table["Denomination2"] = "an";
liste.Add(table);
var result = liste.Select(map => new
{
IdClient = map["Denomination"],
Denomination = map["Denomination2"]
}).ToList();
gvClients.DataSource = result;
gvClients.DataBind();
I've this error :
The data source for GridView with id 'gvClients' did not have any properties or attributes from which to generate columns.
When I modify the mapping like this :
var result = liste.Select(map => new
{
IdClient = map["Denomination"],
Denomination = map["Denomination2"],
Test = "test"
}).ToList();
It will show only the Test property.
Thanks

Check out the following code.
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvClients" runat="server" AutoGenerateColumns="false" GridLines="None"
CssClass="gridview" AlternatingRowStyle-CssClass="alt" Width="80%">
<AlternatingRowStyle CssClass="alt"></AlternatingRowStyle>
<Columns>
<asp:BoundField DataField="Key" />
<asp:BoundField DataField="Value" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Specialized;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var liste = new List<Dictionary<string, string>>();
var dictionary = new Dictionary<string, string>();
dictionary["PropertyName"] = "text to show";
var dictionary2 = new Dictionary<string, string>();
dictionary2["PropertyName"] = "text to show1";
liste.Add(dictionary2);
liste.Add(dictionary);
var result = liste.SelectMany(x => x);
gvClients.DataSource = result;
gvClients.DataBind();
}
}
}
Edit
I have edited the code as per your requirements.Please try this code and let me know if you experience any problems .
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvClients" runat="server" AutoGenerateColumns="true" GridLines="None"
CssClass="gridview" AlternatingRowStyle-CssClass="alt" Width="80%">
<AlternatingRowStyle CssClass="alt"></AlternatingRowStyle>
<Columns>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Description") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="OtherInfo">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("OtherInfo") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public class Client
{
public string ID { get; set; }
public string Description { get; set; }
public string OtherInfo { get; set; }
}
public partial class Default3 : System.Web.UI.Page
{
List<Client> list=new List<Client>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var liste = new List<Dictionary<string, string>>();
var dictionary = new Dictionary<string, string>();
dictionary["ID"] = "111";
dictionary["Description"] = "XYZ";
dictionary["OtherInfo"] = "Addd";
liste.Add(dictionary);
var result = liste.Select(map => new Client
{
ID = map["ID"],
Description = map["Description"],
OtherInfo = map["OtherInfo"]
}).ToList();
gvClients.DataSource = result;
gvClients.DataBind();
}
}
}
EDITII
If you want to use Hashtable then do the following
Create a new class named Client (what ever you want)
public class Client
{
public string IdClient { get; set; }
public string Denomination { get; set; }
}
and then query the list as follows
var liste = new List<Hashtable>();
var table = new Hashtable();
table["Denomination"] = "a";
table["Denomination2"] = "an";
liste.Add(table);
var result = liste.Select(map => new Client()
{
IdClient = map["Denomination"].ToString(),
Denomination = map["Denomination2"].ToString()
});
gvClients.DataSource = result;
gvClients.DataBind();

Related

Asp.net Gridview error: Operator '-' is not defined for types 'Object' and 'Date'

I used this code: (Eval("RegDtTime")-DateTime.Now to calculate the difference between Registered DateTime (is in a database) and DateTime.now in a gridview, But get this error: operator '-' is not defined for types 'Object' and 'Date'. So what should I use instead?
Use below Eval Object
<%# System.Convert.ToDateTime(Eval("RegDtTime"))%>
So that your template will be
<asp:TemplateField ItemStyle-Width = "100px" HeaderText = "DATE" >
<ItemTemplate >
<%# (System.Convert.ToDateTime(Eval("Date")) - (DateTime.Now)) %>
</ItemTemplate>
</asp:TemplateField>
Instead of coding the logic in aspx files, you can define a method in code behind and call that from GridView.
This is my GridView in aspx.
<asp:GridView ID="GridView1" AutoGenerateColumns="false" runat="server">
<Columns>
<asp:TemplateField HeaderText="Date">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# GetCalculatedDateTime(Convert.ToDateTime(Eval("RegDtTime"))) %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
This is my Entity or Model.
public class MyClass
{
public DateTime RegDtTime { get; set; }
}
And this is the code behind for ASPX.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var lst = new List<MyClass>();
lst.Add(new MyClass { RegDtTime = DateTime.Now.AddDays(-5) });
lst.Add(new MyClass { RegDtTime = DateTime.Now.AddDays(6) });
lst.Add(new MyClass { RegDtTime = DateTime.Now.AddDays(5) });
lst.Add(new MyClass { RegDtTime = DateTime.Now.AddDays(-9) });
lst.Add(new MyClass { RegDtTime = DateTime.Now.AddDays(-7) });
GridView1.DataSource = lst;
GridView1.DataBind();
}
}
public static string GetCalculatedDateTime(DateTime dt)
{
var result = dt - DateTime.Now;
return result.ToString();
}
You can write the required logic in GetCalculatedDateTime method.

External XML data to gridview

I´m trying to get data (link) from an public XML file to my gridview.
I´m trying following, but can't get it done. Anyone can help me on that?
<body>
<form id="form1" runat="server">
<div>
<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="http://weather.aero/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=lebl&hoursBeforeNow=5"> </asp:XmlDataSource>
<asp:GridView ID="GridView1" runat="server" DataSourceID="XmlDataSource1">
</asp:GridView>
</div>
</form>
</body>
Any help would be very appreciated.
Thanks in advance for any help.
RU
You will have to parse the XML anyway so try this
Markup
<asp:GridView ID="WeatherList" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Latitude" HeaderText="Latitude" />
<asp:BoundField DataField="WindDirectionSpeed" HeaderText="Wind Speed(kms)" />
</Columns>
</asp:GridView>
Code-behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindWeatherGrid();
}
}
private void BindWeatherGrid()
{
var url = "http://weather.aero/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=lebl&hoursBeforeNow=5";
XDocument doc = XDocument.Load(url);
var metars = from wthr in doc.Descendants("METAR")
select new Metar()
{
Latitude = (string)wthr.Element("latitude"),
WindDirectionSpeed = (string)wthr.Element("wind_speed_kt")
};
WeatherList.DataSource = metars;
WeatherList.DataBind();
}
Namespaces used
using System.Linq;
using System.Xml.Linq;
Helper Class
public class Metar
{
public string Latitude { get; set; }
public string WindDirectionSpeed { get; set; }
}

how to retrieve TextBox control's ClientID within the ListView's ItemDataBound event?

I am having trouble retrieving a TextBox control's ClientID value from a ListView control.
I thought this syntax would return me the ClientID fine(very strange):
((TextBox)e.Item.FindControl("amount")).ClientID;
but it keeps throwing this exception:
"Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index"
Any help is greatly appreciated.
Below is my code:
aspx:
<asp:ListView ID="categories" runat="server"
ClientIDRowSuffix="ID"
ItemPlaceholderID="categoryItem"
DataKeyNames="ID" onitemdatabound="categories_ItemDataBound">
<ItemTemplate>
<div class="category">
<asp:TextBox ID="amount" runat="server" />
</div>
</ItemTemplate>
</asp:ListView>
codebehind:
public string AmountTextBoxClientID { get; set; }
protected string GetAmountTextBoxClientID()
{
return this.AmountTextBoxClientID;
}
protected void categories_ItemDataBound(object sender, ListViewItemEventArgs e)
{
switch (e.Item.ItemType)
{
case ListViewItemType.DataItem:
TextBox amountTextBox = (TextBox)e.Item.FindControl("amount");//this line excutes without any error
amountTextBox.Text = categoryAmount.ToString("C");
amountTextBox.Attributes.Add("readonly", "readonly");
this.AmountTextBoxClientID = amountTextBox.ClientID; //this line keeps throwing the OutOfRange exception
break;
}
}
Im afraid I cant pinpoint your problem but i drew up a page based on what you've given and pasted it below. It does NOT error.
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
public string AmountTextBoxClientID { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("column1");
DataRow dr = dt.NewRow();
dr[0] = "some data";
dt.Rows.Add(dr);
ListView1.DataSource = dt;
ListView1.DataBind();
}
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
TextBox tbAmount = (TextBox)e.Item.FindControl("amount");
this.AmountTextBoxClientID = tbAmount.ClientID;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ListView ID="ListView1" runat="server" onitemdatabound="ListView1_ItemDataBound">
<ItemTemplate>
<asp:TextBox ID="amount" runat="server" />
</ItemTemplate>
</asp:ListView>
</div>
</form>
</body>
</html>

Append empty text box Rows to a grid

I have a grid with two columns first column with check box and second column with text box. I have a add and save button down the grid.Can you please tell how to obtain if i click add button i need to append one more row to the grid with empty text box and check box so that i can type and click save
need to do possibly without java script
If I am getting you correctly you want something like below
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default5.aspx.cs" Inherits="Default5" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="grdDemo" runat="server" AutoGenerateColumns="False" EnableModelValidation="True">
<Columns>
<asp:TemplateField HeaderText="CheckBox">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("IsCheckBox") %>' Enabled="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="TextBox">
<ItemTemplate>
<asp:TextBox ID="Label1" runat="server" Text='<%# Bind("IsTextBox") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Save" />
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Caching;
public partial class Default5 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
grdDemo.DataSource = new Demo().GetData();
grdDemo.DataBind();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
var list = new Demo().GetData();
list.Add(new Demo() {IsCheckBox = false, IsTextBox = ""});
Cache["list"] = list;
grdDemo.DataSource = list;
grdDemo.DataBind();
}
}
public class Demo
{
public bool IsCheckBox { get; set; }
public string IsTextBox { get; set; }
public List<Demo> GetData()
{
if (HttpContext.Current.Cache["list"] == null)
{
List<Demo> list = new List<Demo>()
{
new Demo(){IsCheckBox=true,IsTextBox = "text1"},
new Demo(){IsCheckBox=false,IsTextBox = "text2"},
};
return list;
}
return (List<Demo>)HttpContext.Current.Cache["list"];
}
}

asp.net TemplateField.ItemTemplate

TemplateField tf1 = new TemplateField();
tf1.ItemTemplate = ???
How to initialize this property?
If I need to this programmatically then what to do?
TemplateField tf1 = new TemplateField();
tf1.ItemTemplate = Page.LoadTemplate("ItemTemplate.ascx");
You would usually do this sort of thing in the markup:
<TemplateField ...>
<ItemTemplate>
<asp:TextBox .../>
</ItemTemplate>
</TemplateField>
or do the same thing using the designer.
Example follows. The commented-out markup produces the same thing as the codebehind does:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
SelectCommand="SELECT Person.Contact.FirstName, Person.Contact.LastName
FROM Person.Contact
INNER JOIN HumanResources.Employee ON Person.Contact.ContactID = HumanResources.Employee.ContactID
WHERE (Person.Contact.LastName LIKE N'A%')
ORDER BY Person.Contact.LastName, Person.Contact.FirstName">
</asp:SqlDataSource>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<%-- <ItemTemplate>
<asp:Label runat="server" ID="lblLast">Name: </asp:Label>
<asp:Label runat="server" ID="lblName" Text='<%# DataBinder.Eval(Container.DataItem, "LastName")+", "+DataBinder.Eval(Container.DataItem, "FirstName") %>' />
</ItemTemplate>--%>
<SeparatorTemplate>
<hr />
</SeparatorTemplate>
</asp:Repeater>
</form>
</body>
</html>
Codebehind:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Repeater1.ItemTemplate = new TheItemTemplate();
}
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
}
public class TheItemTemplate : ITemplate
{
#region Implementation of ITemplate
public void InstantiateIn(Control container)
{
var lblLast = new Label {ID = "lblLast", Text = "Name: "};
container.Controls.Add(lblLast);
var lblName = new Label {ID = "lblName"};
lblName.DataBinding += delegate(object sender, EventArgs e)
{
var theLabel = (Label) sender;
var dataItem = DataBinder.GetDataItem(theLabel.BindingContainer);
theLabel.Text = DataBinder.Eval(dataItem, "LastName") + ", " +
DataBinder.Eval(dataItem, "FirstName");
};
container.Controls.Add(lblName);
}
#endregion
}

Resources