I'm generating a DataTable with some data and using it as DataSource for a GridView that will be added to an ASP.NET-Webpage.
GridView gvItems = new GridView();
DataTable dtItems = new DataTable();
dtItems.Columns.Add("name");
dtItems.Columns.Add("description");
dtItems.Columns.Add("count");
foreach(var item in items)
{
string name = item.name;
string description = item.description;
string count = item.count.ToString();
string link = "~/Views/Items.aspx?item=" + item.name;
string linkName = item.name;
dtItems.Rows.Add(name, description, count)
}
gvItems.DataSource = dtItems;
gvItems.DataBind();
PlaceHolder.Controls.Add(gvItems)
Is it possible to generate a Hyperlink for each whole row that is added?
I want a detailed page of an item to be opened if someone clicks somewhere inside of a row.
You cannot add a link to an entire row directly, but you can do it with an attribute and some jQuery. For that you need the RowDataBound event. But since you are creating a GridView dynamically you need to add it with code.
gvItems.RowDataBound += GvItems_RowDataBound;
gvItems.DataSource = dtItems;
gvItems.DataBind();
Then the RowDataBound method itself.
private void GvItems_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//cast the row back to a datarowview
DataRowView row = e.Row.DataItem as DataRowView;
//add the url as an attribute to the row
e.Row.Attributes.Add("data-url", row["link"].ToString());
//give the row a class to the jquery click event can be bound to it
e.Row.Attributes.Add("class", "ClickableRow");
}
}
Then for some front end code to handle the click.
<script type="text/javascript">
$(document).ready(function () {
$(".ClickableRow").click(function () {
location.href = $(this).data("url");
});
});
</script>
Related
How do I get a dynamic dropdownlist control from a gridview when clicking on btnDoAction
I'm trying to get a dropdownlist control when I click btnDoAction to row, but when I'm looking for the dropdownlist control it always returns null, I'm changing dropdownlist ID in RowDataBound 'cause I populated listItems depending row ID.
Code behing
protected void gvLista_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string varId = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "Id"));
var ctrlDDlActions = e.Row.Cells1.FindControl("ddlActions") as DropDownList;
ctrlDDlActions.ID = ctrlDDlActions.ID + "" + varId.Replace("-", "");
}
}
protected void BtnDoAction_Click(object sender, EventArgs e)
{
var id = Guid.Parse(((LinkButton)sender).CommandArgument);
var varId = id.ToString().Replace("-", "_");
var control = "ddlActions_" + varId;
DropDownList ddl = new DropDownList();
foreach (GridViewRow row in gvLista.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
ddl = (DropDownList)row.FindControl(control);
}
}
var selectedValue = ddl.SelectedValue; //<--- ddl is null
}
guys... I found the answer.. thank you for your feeds... the solution that I found is this:
protected void BtnDoAction_Click(object sender, EventArgs e)
{
var id = Guid.Parse(((LinkButton)sender).CommandArgument);
LinkButton btn = (LinkButton)sender;
GridViewRow row = (GridViewRow)btn.NamingContainer;
int i = Convert.ToInt32(row.RowIndex);
var control = "ddlActions";
var ddl = (DropDownList)gvLista.Rows[i].FindControl(control);
//Now I can read my dropdownlist in my gridview just passing de RowIndex
//you don't need to change the dropdownlist ID in RowDataBound, just let it with the
//same ID
}
When grabbing the ddl from the rowdataboud, look for it like this (note the e):
ddl = (DropDownList)e.row.FindControl(control);
You are trying to set the selected value for the DropDownList you created. What is the value you are trying to set it to? Looks to me like you are trying to set ddl to some value that you havent set;
var selectedValue = ddl.SelectedValue; //<--- ddl is null
// maybe something like
var selectedVal = "someval"
ddl.SelectedValue = selectedVal;
What is "var selectedValue"? I don't see where that gets set, therefore it is not the ddl that's null its "var selectedValue".
I'm pulling company schedule data from a web API and formatting the data so it can be displayed neatly on a local site and also available to export onto an excel template for distribution across the company.
I've added a button on the bottom of the site to display the previous weeks schedule and another to export the data to excel. When "Previous Week" is clicked it populates the same Gridview1 table with last weeks data. But When I click the export button it exports the data from the current week into Excel.
Here's some of my code, let me know what else I need to post for help.
The datatable gets set on page load into a gridview:
protected void Page_Load(object sender, EventArgs e)
{
// ..... bunch of code above to call web API for date range and format table....
DataView view = table.AsDataView();
view.Sort = "Sort ASC";
GridView1.DataSource = view;
GridView1.DataBind();
if (GridView1.Columns.Count > 0)
GridView1.Columns[8].Visible = false;
else
{
GridView1.HeaderRow.Cells[8].Visible = false;
foreach (GridViewRow gvr in GridView1.Rows)
{
gvr.Cells[8].Visible = false;
}
}
and the gridview gets pulled into a datatable and sent to an excel spreadsheet
protected void ExportExcel(object sender, EventArgs e)
{
DataTable dt = new DataTable("Resident Schedule");
foreach (TableCell cell in GridView1.HeaderRow.Cells)
{
dt.Columns.Add(cell.Text);
}
foreach (GridViewRow row in GridView1.Rows)
{
dt.Rows.Add();
for (int i = 0; i < row.Cells.Count; i++)
{
dt.Rows[dt.Rows.Count - 1][i] = row.Cells[i].Text;
}
}
dt.Columns.Remove("Rotation");
dt.Columns.Remove("Sort");
using (XLWorkbook wb = new XLWorkbook(#"C:\template.xlsx"))
{
IXLWorksheet ws = wb.Worksheet("Resident Schedule");
var rangeWithStrings = ws.Cell(5, 2).InsertTable(dt.AsEnumerable(), false);
// ..... bunch of code below
now I have a button click method that gets called to load the previous week into GridView:
protected void PreviousWeek(object sender, EventArgs e)
{
// ..... bunch of code above to pull and sort last weeks schedule....
DataView view = table.AsDataView();
view.Sort = "Sort ASC";
GridView1.DataSource = view;
GridView1.DataBind();
if (GridView1.Columns.Count > 0)
GridView1.Columns[8].Visible = false;
else
{
GridView1.HeaderRow.Cells[8].Visible = false;
foreach (GridViewRow gvr in GridView1.Rows)
{
gvr.Cells[8].Visible = false;
}
}
So, my question is, if the button click is repopulating GridView1 data, why is the ExportExcel method is going back to the Page Load data?
Click on button, send postback event and seems you missed to check whether request is postback or not. so whenever you click on button then always gridview populated with current week data. Check postback request and then poulate gridview on load event.
if (!IsPostBack)
{
// GridView Populate code
}
I have a datatable with values and I need to assign them as default values to gridview dropdown list on button click event. I have tried writing the below code and it retains only the last row values. How can I retain all the rows?
Am I missing to add rows to the GridView?
For example: DataTable now has three rows and in GridView only the third row has the default values from DataTable and the first rows are empty.
DataTable dtValues = dtSource;
if (dtValues.Rows.Count > 0)
{
for (int i = 1; i <= dtValues.Rows.Count; i++)
{
RadComboBox ID = (RadComboBox)gvGrid.Rows[i].Cells[1].FindControl("radID");
RadComboBox Names = (RadComboBox)gvGrid.Rows[i].Cells[2].FindControl("radName");
ID.SelectedValue = dtValues.Rows[i]["ID"].ToString();
Names.SelectedValue = dtValues.Rows[i]["Name"].ToString();
}
}
Can anyone please correct me if I'm doing something wrong?
You should need to use RowDataBound event of GridView as like below and populate it from DataTable as DataSource:
protected void gvGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
// check if row is not in edit mode
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dtValues = dtSource;
// get dropdownlist from gridview
var ddl = e.Row.FindControl("YourDropDown") as DropDownList;
if (ddl != null)
{
ddl.DataSource = dtValues;
ddl.DataTextField = "Name"; // add text to dropdownlist
ddl.DataValueField = "ID"; // add value to dropdownlist
ddl.DataBind();
// add default selected value
ddl.Items.Insert(0, new ListItem("----- Select a Value -----", "0"));
}
}
}
Note: Don't forget to add OnRowDataBound event gvGrid_RowDataBound to your GridView.
I have gridview that contains textbox that created in code behind
this is the page load:
protected void Page_Load(object sender, EventArgs e)
{
//my page load is empty;
}
here is code for button after selecting dropdown and then click "Pilih" for showing gridview that contains textbox:
public void btnPilihKrit_Click(object sender, EventArgs e)
{
DataTable dtsubKrit = new DataTable();
dtsubKrit = subkritMgr.getListSubKriteriaByIDKriteria(int.Parse(ddlKrit.SelectedValue));
NbDtSubKritRow = dtsubKrit.Rows.Count;
dtGvSubKrit.Columns.Add(new DataColumn("SUBKRITERIA", typeof(string)));
foreach (DataRow row in dtsubKrit.Rows)
{
dtGvSubKrit.Columns.Add(new DataColumn(row["SUBKRITERIA"].ToString(), typeof(string)));
}
DataRow dr = null;
foreach (DataRow row in dtsubKrit.Rows)
{
dr = dtGvSubKrit.NewRow();
dr["SUBKRITERIA"] = row["SUBKRITERIA"];
dtGvSubKrit.Rows.Add(dr);
}
gvKrit2.DataSource = dtGvSubKrit;
gvKrit2.DataBind();
ViewState["CurrentTable"] = dtGvSubKrit;
}
this is code in rowdatabound for gridview:
protected void gvKrit2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
for (int i = 1; i <= NbDtSubKritRow; i++)
{
TextBox txtNilai = new TextBox();
txtNilai.ID = "txtNilai" + e.Row.RowIndex.ToString() + i.ToString();
if (i == e.Row.RowIndex + 1)
{
txtNilai.Text = "1";
}
else
{
txtNilai.Text = "";
}
if (i <= e.Row.RowIndex + 1)
{
txtNilai.Enabled = false;
}
e.Row.Cells[i].Controls.Add(txtNilai);
}
}
}
then this is code for getting value from textbox inside grid view:
protected void btnProsesPerbBerpsg_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in gvKrit2.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
TextBox textBox = row.FindControl("txtNilai") as TextBox;
string tb = textBox.Text;
// do somthing with the text box textBox
}
}
}
Here's some illustration :
Screenshot 1, after clicking button Pilih and choose dropdown, gridview with textbox will show up and I will fill the textbox with my own value
Screenshot 2, to get value from gridview by clicking button "Proses Perbandingan Berpasangan"
anyone could help me?
i have tried many way like
TextBox box1 = (TextBox)(gvKrit2.Rows[rowIndex].Cells[1].FindControl("txtNilai")) as TextBox;
but textbox couldn't found from findcontrol. seems like gridview isn't created again on post back.
I have search some literature that I have to recreate gridview or make rowcreated event in gridview but Now I don't have any idea to do that.
As you created textbox on RowDataBound with ID like:
txtNilai.ID = "txtNilai" + e.Row.RowIndex.ToString() + i.ToString();
So you need to find with that ID :
string txtid = "txtNilai"+e.Row.RowIndex.ToString()+i.ToString(); // as per given inRowdataBound , so make sure to define i value.
TextBox textBox = row.FindControl(txtid) as TextBox;
I currently have a GridView control on my aspx page with paging enabled and I need to loop through the entire row collection/count to process the selected records. With my current code, it will only loop through the current page of GridView row.
What is the best way to accomplish this task?
Here is my current code:
ASPX page:
<asp:GridView ID="MyGridView" runat="server" AllowPaging="true" PageSize="20">
<Columns>
<!-- My Column list -->
</Columns>
</asp:GridView>
<asp:Button id="MyButton" runat="server" Text="Add" OnClick="MyButton_Click" />
code behind:
protected void MyButton_Click(object sender, EventArgs e)
{
for (int Count = 0; Count < MyGridView.Rows.Count; Count++)
{
//The row count is 20 and only contains the GridViewRow object in the current page view
//I want to retrieve the all GridViews rows so I can add them to a ReorderList control
}
}
Yes because your gridview UI is only aware of the current page.
Get the datasource and determine the row count from there...
int count = ((DataTable)MyGridView.DataSource).Rows.Count;
//or
int count = ((ICollection<SomeRecord>)MyGridView.DataSource).Count;
Simply use the following code:
//Change gridview to
GridView1.AllowPaging = false;
GridView1.DataBind();
//Transfer rows from GridView to table
for (int i = 0; i < GridView1.Rows.Count; i++)
{
if (GridView1.Rows[i].RowType == DataControlRowType.DataRow)
{
for (int j = 0; j < GridView1.Rows[0].Cells.Count; j++)
{
//Add your code here..
}
}
}
//After filling your datatable change gridview paging style back to first, ie.
GridView1.AllowPaging = true;
GridView1.DataBind();
This may help you, let me know if this was helpful for you...
I think you should get the row count from your data source's row count.
If you need to filter rows, you can use DataTable's / DataView's Select method.
EDIT : You can not get actual row count by gridview.Rows.Count if gridview is paged. Depending on your comment, I assume that you're using listDataSource generic list to bind your gridview, you can get your row count as :
List<DataSourceItem> selectedRows =
listDataSource.FindAll(delegate(DataSourceItem item)
{
// Assuming you have a IsSelected bool property
// that refers your row is selected :
return item.IsSelected;
});
int rowCount = selectedRows.Count;
use session or state to store:
protected void Set_CheckboxStatus()
{
CheckBox selectall = (CheckBox)EmployeeGrid.HeaderRow.FindControl("gcb_selectall");
ArrayList cbstatuslist = new ArrayList();
if (Session["childcbstatus"] != null)
{
cbstatuslist = (ArrayList)Session["childcbstatus"];
}
foreach (GridViewRow row in EmployeeGrid.Rows)
{
int cb_index = (int)row.DataItemIndex; //For Getting DataItemIndex of EmployeeGrid
//int cb_index = (int)row.RowIndex;
CheckBox cb_selemp = (CheckBox)row.FindControl("gcb_selemp");
CheckBox cb_active = (CheckBox)row.FindControl("gcb_active");
if (cb_selemp.Checked == true)
{
if (!cbstatuslist.Contains(cb_index))
cbstatuslist.Add(cb_index);
}
else
{
cbstatuslist.Remove(cb_index);
}
}
Session["childcbstatus"] = cbstatuslist;
}
from the arraylist you can get all row index to loop and get the value from the gridview with paging.
#CRice's answer should have been the official answer.
Here is my solution. You need to presave the gridview's data, via its DataSource, into ViewState or Session.
GridView.Rows only refers to the "visible" rows, or the page currently shown on the screen.
protected void GridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView gv = (GridView)sender;
DataSourceSelectArguments dss = new DataSourceSelectArguments();
//get the datasource related to the gridview
string wsDataSourceID = (gv.DataSourceID == string.Empty) ? ViewState["DataSourceID"].ToString() : gv.DataSourceID;
SqlDataSource sds = (SqlDataSource)pnlMAIN.FindControl(wsDataSourceID);
if (sds != null)
{
//load the data again but this time into a dataview object
DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty);
if (dv != null)
{
//convert the dataview to a datatable so we can see the row(s)
DataTable dt = (DataTable)dv.ToTable();
if (dt != null)
{
//Save your data before changing pages
ViewState["AllTheData"] = dt;
gv.DataSource = dt;
gv.DataSourceID = null;
}
}
}
//now change pages!
gv.PageIndex = e.NewPageIndex;
gv.DataBind();
}
Next, when changing pages, here we save the data
protected void GridView_PageIndexChanged(object sender, EventArgs e)
{
GridView gv = (GridView)sender;
DataSourceSelectArguments dss = new DataSourceSelectArguments();
//reload the datatable back to the gridview
gv.DataSource = ViewState["AllTheData"];
gv.DataSourceID = null;
gv.DataBind();
I hope the code speaks for itself.
Thanks