ASP.NET/C# Linq Binding to GridView - c#

I group my data by length as follows
int[] a = { 1, 2, 3,45,45,100,566};
var result =
a.GroupBy(x => x.ToString().Length).
Select(d => new { Key = d.Key, Grp = d });
My BulletedList is nested in GridView(placed as template field) to display the items,What is the way to bind the BulletedList when GridView displays "Key".
GridView1.DataSource = result;
GridView1.DataBind();

set DataKeyNames to your key name
For example:
<asp:gridview id="CustomersGridView"
datasourceid="CustomersSource"
autogeneratecolumns="true"
emptydatatext="No data available."
autogenerateselectbutton="true"
datakeynames="CustomerID"

Binding to a bulleted list within a gridview (works similarly for any control, of course)
void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
RadioButtonList list = (RadioButtonList)e.Row.FindControl("rbList");
if(list != null)
{
list.DataSource = mysource;
list.DataBind();
}
}
}
Make sure you add the event to the GridView.

Related

Creating a single "view" button method for gridview

I'm just trying to create a single button "view" click for the data in the specific row for gridview and pass it to a Silverlight viewer.
Here's a "viewall" button I'm trying to figure out off of.
protected void btnViewAll_Click(object sender, EventArgs e)
{
string id = HttpContext.Current.Request.Headers["id"];
#if DEBUG
if (id == null)
id = "111"; // Use my own id for testing locally
#endif
using (aDataContext dc = new aDataContext())
{
var query = (from a in dc.aLists
where a.ID == id
select new
{
a.aNumber,
a.bNumber,
a.cNumber,
a.dNumber,
}
);
List<aListItem> List = new List<aListItem>();
foreach (var queryItem in query)
{
aList.Add(new aListItem()
{
aNumber = queryItem.aNumber,
bNumber = queryItem.bNumber,
cNumber = queryItem.cNumber,
dNumber = queryItem.dNumber
});
}
Session["aList"] = aList;
}
Session["Database"] = null;
Response.Redirect("Viewer.aspx" + "?UseList=true");
}
Solution 1:
It can be done with a ButtonField in the GridView:
Add the row-specific info to the DataKeyNames of the GridView (e.g. if the fields "name1" and "age2" of your data source are needed to view with your Silverlight viewer):
<asp:GridView ID="gvClients" DataKeyNames="name1,age2" ... >
Add a ButtonField to the GridView:
<asp:ButtonField ButtonType="Button" CommandName="View" Text="View" />
Set the RowCommand event handler (can be done in markup or in code):
gvClients.RowCommand += new GridViewCommandEventHandler(gvClients_RowCommand);
And process the command:
void gvClients_RowCommand(object sender, GridViewCommandEventArgs e)
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
string name1 = (string)gvClients.DataKeys[rowIndex].Values["name1"];
int age2 = (int)gvClients.DataKeys[rowIndex].Values["age2"];
// Open docName with the viewer
...
}
Solution 2: An alternative, which avoids a postback, would be to use a a HyperLinkField:
<asp:HyperLinkField Text="View" DataNavigateUrlFormatString="Viewer.aspx?Name={0}&Age={1}" DataNavigateUrlFields="name1,age2" />

Gridview dataBound add hyperlink to column data from code behind

Using grid view binding it from code behind:
I want to bind a particular column data into a hyper link so when it clicked it should do a download.
How to do that ?
Below is my code :
for (int i = 0; i <= tbl.Columns.Count - 1; i++)
{
Telerik.Web.UI.GridBoundColumn boundfield = new Telerik.Web.UI.GridBoundColumn();
if (tbl.Columns[i].ColumnName.ToString() == "Row")
{
LinkButton lkbtn = new LinkButton();
lkbtn.CommandName = i;
lkbtn.CommandArgument = "dwnld";
lkbtn.Font.Underline = true;
lkbtn.Text = tbl.Columns(i).ColumnName.ToString();
boundfield.DataField = tbl.Columns(i).ColumnName.ToString()
boundfield.HeaderText = tbl.Columns(i).ColumnName.ToString();
GridView2.MasterTableView.Columns.Add(boundfield);
}
}
Why not use grid template column with link button.
<telerik:GridTemplateColumn>
<ItemTemplate>
<asp:LinkButton ID="btnDownload" OnClick="btnDownload_Click" runat="server">Download Something</asp:LinkButton>
</ItemTemplate>
</telerik:GridTemplateColumn>
protected void btnDownload_Click(object sender, EventArgs e)
{
LinkButton lbBtn = sender as LinkButton;
GridDataItem item = (GridDataItem)(sender as LinkButton).NamingContainer;
// Use item to get other details
...
...
}

How to save changes from DropDownList to sql database?

I edited a DataGrid column so the location is now a DropDownList, which works fine. It populates the DropDownList from the database.
<asp:TemplateColumn HeaderText="Trailer Location">
<itemtemplate>
<asp:DropDownList ID="ddlTrailerLoc" runat="server" OnSelectedIndexChanged="ddlTrailerLoc_SelectedIndexChanged">
</asp:DropDownList>
<asp:HiddenField ID="hdlTrailerLoc" runat="server" Value='<%#Eval("TrailerLocation")%>' />
</itemtemplate>
</asp:TemplateColumn>
But when I change the value in the DropDownList I don't know how to save the changes made to the database.
protected void PopulateDDLs(DropDownList ddlTrailerLoc)
{
DataSet dsTrailerLocation = DataUtils.GetAllGenSmall(Company.Current.CompanyID, "Description", "", 1, false, "Description", false, "TrailerLocationNOCODE", 0);
if (dsTrailerLocation.Tables[0].Rows.Count > 0)
{
ddlTrailerLoc.DataSource = dsTrailerLocation;
ddlTrailerLoc.DataValueField = "Description";
ddlTrailerLoc.DataTextField = "Description";
ddlTrailerLoc.DataBind();
}
else
{
ddlTrailerLoc.Items.Insert(0, new ListItem("No Locations Entered", "0"));
}
}
protected void dgList_ItemCreated(object sender, DataGridItemEventArgs e)
{
if (e.Item.ItemType != ListItemType.Header && e.Item.ItemType != ListItemType.Pager && e.Item.ItemType != ListItemType.Footer)
{
DropDownList ddlTrailerLocation = e.Item.FindControl("ddlTrailerLoc") as DropDownList;
if (ddlTrailerLocation != null)
{
PopulateDDLs(ddlTrailerLocation);
//set the value in dropdown
HiddenField hdlTrailerLoc = e.Item.FindControl("hdlTrailerLoc") as HiddenField;
if (hdlTrailerLoc != null)
{
ddlTrailerLocation.SelectedValue = hdlTrailerLoc.Value;
}
}
}
}
I tried creating this ddlTrailerLoc_SelectedIndexChanged method but the event doesn't run.
protected void ddlTrailerLoc_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList list = (DropDownList)sender;
TableCell cell = list.Parent as TableCell;
DataGridItem item = cell.Parent as DataGridItem;
int selectedIndex = item.ItemIndex;
string selectedItem = item.Cells[0].Text;
// now save your work here and rebind the grid.
Trailer.UpdateTrailer(int.Parse(TrailerID), Company.Current.CompanyID,
txtTrailerReg.Text,
ddlTrailerLocation.Text);
ddlTrailerLocation.DataValueField = "Description";
ddlTrailerLocation.DataTextField = "Description";
ddlTrailerLocation.DataBind();
}
Please add AutoPostBack="True" in dropdown. It will work
<asp:DropDownList ID="ddlTrailerLoc" runat="server" OnSelectedIndexChanged="ddlTrailerLoc_SelectedIndexChanged" AutoPostBack="True"></asp:DropDownList>
Please write code as below
protected void ddlTrailerLoc_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddlTrailerLoc=sender as DropDownList;
if(ddlTrailerLoc!=null)
{
int trailerId=int.Parse(ddlTrailerLoc.SelectedValue.ToString());
//Save selected value in Database
// now save your work here and rebind the grid.
Trailer.UpdateTrailer(trailerId, Company.Current.CompanyID,
txtTrailerReg.Text,
ddlTrailerLoc.Text);
ddlTrailerLocation.DataValueField = "Description";
ddlTrailerLocation.DataTextField = "Description";
ddlTrailerLocation.DataBind();
}
}

Creating Gridview column Header by loading data from database

I want to bind my grid column header names by retrieving data from a table. This table has two fields, DomainID and DomainName, I want to display the DomainNames as Column header of the Grid.
Actually I am creating employee grid view. I want all the domain names of employee to be displayed as a header and i have to check the corresponding domain in Checkbox.
Please Give me some ideas.
Thanks in advance.
From what i understood....
Make a grid view
Create two columns:
a. TextBoxColumn
b. CheckBoxColumn
Set your column header using .HeaderText property
Add the columns to your data grid view
Query your database and get the data_table from it
using dgv.DataSource = data_table bind your data to the table
OR
Make a for loop for all rows in the data_table and add each row explicitly
For getting your checkboxes to work, handle the cellContentClick event of the data grid view and perform the necessary updates in your database.....
Hope it helps....
You could load the headers into a DataTable and then create them dynamically with a custom TemplateField.
Here's the aspx part:
<asp:GridView ID="GridView1" AutoGenerateColumns="false" DataKeyNames="EmployeeID" runat="server" >
<SelectedRowStyle BackColor="Aqua" />
<Columns>
<asp:TemplateField HeaderText="Employee" SortExpression="Employee">
<ItemTemplate>
<asp:HiddenField ID="HiddenEmpID" Value='<%# Bind("EmployeeID") %>' runat="server" />
<asp:label runat="server" ID="LblEmployee" Text='<%# Bind("EmployeeName") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="BtnSave" Text="Save" runat="server" onclick="BtnSave_Click" />
Here's a complete sample:
public partial class GridTest : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
CreateGridColumns();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) BindGrid();
}
private void CreateGridColumns()
{
var tblDomain = GetDomains();
// Create dynamic TemplateFields
foreach (DataRow row in tblDomain.Rows)
{
String domainName = row.Field<String>("DomainName");
TemplateField field = new TemplateField();
//Initalize the DataField value.
field.ItemTemplate = new GridViewCheckBoxTemplate(ListItemType.Item, domaninName);
field.HeaderText = domainName;
//Add the newly created field to the GridView.
GridView1.Columns.Add(field);
}
}
private DataTable GetDomains()
{
var tblDomain = new DataTable();
tblDomain.Columns.Add("DomainID", typeof(int));
tblDomain.Columns.Add("DomainName");
tblDomain.Rows.Add(1, "Google.com");
tblDomain.Rows.Add(2, "Yahoo.com");
tblDomain.Rows.Add(3, "Msn.com");
tblDomain.Rows.Add(4, "Youtube.com");
tblDomain.Rows.Add(5, "Myspace.com");
tblDomain.Rows.Add(6, "Facebook.com");
tblDomain.Rows.Add(7, "Wikipedia.org");
return tblDomain;
}
private void BindGrid()
{
var tblDomain = GetDomains(); // load domains from database or wherever
var tblData = new DataTable();// load sample data
tblData.Columns.Add("EmployeeID", typeof(int));
tblData.Columns.Add("EmployeeName");
//add domains as DataTable-Columns
foreach (DataRow row in tblDomain.Rows)
{
String domaninName = row.Field<String>("DomainName");
//Add column from domain-name
tblData.Columns.Add(domaninName, typeof(bool)); //CheckBox-Checked is a boolean
}
//get some Employees and random checked state
var rnd = new Random();
var empRow = tblData.NewRow();
empRow["EmployeeID"] = 1;
empRow["EmployeeName"] = "Jon";
foreach (DataRow dom in tblDomain.Rows)
{
empRow[dom.Field<String>("DomainName")] = rnd.Next(0, 2) == 0;
}
tblData.Rows.Add(empRow);
empRow = tblData.NewRow();
empRow["EmployeeID"] = 2;
empRow["EmployeeName"] = "Eric";
foreach (DataRow dom in tblDomain.Rows)
{
empRow[dom.Field<String>("DomainName")] = rnd.Next(0, 2) == 0;
}
tblData.Rows.Add(empRow);
empRow = tblData.NewRow();
empRow["EmployeeID"] = 3;
empRow["EmployeeName"] = "Alain";
foreach (DataRow dom in tblDomain.Rows)
{
empRow[dom.Field<String>("DomainName")] = rnd.Next(0, 2) == 0;
}
tblData.Rows.Add(empRow);
GridView1.DataSource = tblData;
GridView1.DataBind();
}
// show how to retrieve all checkbox values and the according EmployeeID
protected void BtnSave_Click(object sender, EventArgs e)
{
if (GridView1.Rows.Count == 0) return;
var checkBoxColumns = GridView1.Columns.Cast<DataControlField>()
.Select((bf,index) => new{Field=bf, Index=index})
.Where(f => f.Field.GetType() == typeof(TemplateField) && ((TemplateField)f.Field).ItemTemplate.GetType() == typeof(GridViewCheckBoxTemplate))
.ToArray();
foreach (GridViewRow row in GridView1.Rows)
{
int EmployeeID = int.Parse(((HiddenField)row.FindControl("HiddenEmpID")).Value);
foreach (var f in checkBoxColumns)
{
String domain = f.Field.HeaderText;
bool isChecked = row.Controls[f.Index].Controls.OfType<CheckBox>().First().Checked;
}
}
}
}
Here's the custom ITemplate:
public class GridViewCheckBoxTemplate : ITemplate
{
ListItemType _templateType;
string _columnName;
public GridViewCheckBoxTemplate(ListItemType type, string colname)
{
_templateType = type;
_columnName = colname;
}
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (_templateType)
{
case ListItemType.Header:
break;
case ListItemType.Item:
var chb1 = new CheckBox();
chb1.DataBinding += new EventHandler(CB_DataBinding);
container.Controls.Add(chb1);
break;
case ListItemType.EditItem:
//As, I am not using any EditItem, I didnot added any code here.
break;
case ListItemType.Footer:
break;
}
}
void CB_DataBinding(object sender, EventArgs e)
{
CheckBox chb = (CheckBox)sender;
GridViewRow container = (GridViewRow)chb.NamingContainer;
object dataValue = ((DataRowView)container.DataItem)[_columnName];
chb.Checked = dataValue != DBNull.Value && (bool)dataValue;
}
}

Connect HyperLinkField click to Server-side method (c#)

I have a HyperLinkField which I populate with the urls from a datatable, the field in the datatable is called EncodedAbsUrl.
However, I want to connect this link to a code behind method instead
What I do now
var encodedAbsUrl = new string[] { "EncodedAbsUrl" };
var hf = new HyperLinkField
{
HeaderText = "Link",
DataTextField = "ServerUrl",
DataNavigateUrlFields = encodedAbsUrl,
DataNavigateUrlFormatString = "{0}",
Target = "_blank",
};
But id like to do something like this
var encodedAbsUrl = new string[] { "EncodedAbsUrl" };
var hf = new HyperLinkField
{
HeaderText = "Link",
DataTextField = "ServerUrl",
NavigateUrl = clicker(encodedAbsUrl["{0}"]),
Target = "_blank",
};
protected void clicker(string url)
{
//...
}
Well you can see my attempts are unsuccessful :)
Any advice is appreciated
Thanks!
if you will use HyperLinkField so you will not need to Clicker or any postback event because this field will be rendered as <a> tag. I made a sample example using HyperLink control and LinkButton control that will be postback your page.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
gv.DataSource = [YourDataSource];
gv.DataBind();
}
}
protected void Clicker(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Link")
{
Response.Redirect(e.CommandArgument.ToString());
}
}
protected void gv_DataBinding(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hlink = e.Row.FindControl("hlink") as HyperLink;
hlink.NavigateUrl = ((Person)e.Row.DataItem).NavUrl;
hlink.Text = ((Person)e.Row.DataItem).NavUrl;
hlink.Target = "_blank";
LinkButton lnkButton = e.Row.FindControl("lnkButton") as LinkButton;
lnkButton.Text = ((Person)e.Row.DataItem).NavUrl;
lnkButton.CommandName = "Link";
lnkButton.CommandArgument = ((Person)e.Row.DataItem).NavUrl;
}
}
you GridView will like this
<asp:GridView runat="server" ID="gv" OnRowCommand="Clicker" OnRowDataBound="gv_DataBinding"
AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink runat="server" ID="hlink"></asp:HyperLink>
<asp:LinkButton runat="server" ID="lnkButton"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You'll need to use a LinkButton if you want to be able to postback to the server in the way you require.
This class has an OnClick event unlike the HyperLinkField you've been using.
You can find out more info about the LinkButton class here.

Categories