Find Control inside Grid Row - c#

i m using parent child grid and on child grid i m doing Show / hide threw java script. and child grid i bind run time with Templatecolumns like
GridView NewDg = new GridView();
NewDg.ID = "dgdStoreWiseMenuStock";
TemplateField TOTAL = new TemplateField();
TOTAL.HeaderTemplate = new BusinessLogic.GridViewTemplateTextBox(ListItemType.Header, "TOTAL",e.Row.RowIndex );
TOTAL.HeaderStyle.Width = Unit.Percentage(5.00);
TOTAL.ItemTemplate = new BusinessLogic.GridViewTemplateTextBox(ListItemType.Item, "TOTAL", e.Row.RowIndex);
NewDg.Columns.Add(TOTAL);
NewDg.DataSource = ds;
NewDg.DataBind();
NewDg.Columns[1].Visible = false;
NewDg.Columns[2].Visible = false;
System.IO.StringWriter sw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);
NewDg.RenderControl(htw);
Now I have one TextBox inside Grid named "TOTAL" I want to Find This TextBox and wanna get its value.
How can Get it ?

You could get the TextBox control inside the corresponding cell of the GridView, using the Controls property or the FindControl(string id) method:
TextBox txtTotal = gv.Rows[index].cells[0].Controls[0] as TextBox;
or
TextBox txtTotal = gv.Rows[index].cells[0].Controls[0].FindControl("TOTAL") as TextBox;
where index could be 0 for the first row, or an iterator inside a for loop.
Alternatively, you can use a foreach loop over the GridView's rows:
foreach(GridViewRow row in gv.Rows)
{
TextBox txtTotal = row.cells[0].Controls[0].FindControl("TOTAL") as TextBox;
string value = txtTotal.Text;
// Do something with the textBox's value
}
Besides, you have to keep in mind that, if you're creating the GridView dynamically (and not declaratively in the web form), you won't be able to get this control after a page postback.
There is a great 4 Guys from Rolla article on the subject: Dynamic Web Controls, Postbacks, and View State

As you know you may get TextBox value for example for the first row and the first cell:
((TextBox) dgdStoreWiseMenuStock.Rows[0].Cells[0].Controls[1]).Text;
or change the index of control put 0 if the above line dosen't work.

Try This
TextBox txtTotal = (TextBox)gv.Rows[index].cells[0].FindControl("TOTAL");
string value = txtTotal.Text;

The easiest way to find the control inside the gridview use foreach loop to find the rows
foreach (GridViewRow row in Gridname.Rows)
{
TextBox txttotal = (TextBox)row.FindControl("textboxid_inside_grid");
string var = txttotal.Text;
Response.Write("Textbox value = " + var);
}

Related

Not able to find embedded control in gridview

I have a gridview and on some condition basis, I am inserting text box in it in RowDataBound:
private void GetColumnWithValidation(GridViewRowEventArgs e, string columnName, int columnLength)
{
if (Convert.ToString(DataBinder.Eval(e.Row.DataItem, columnName)).Length > columnLength)
{
int colindex = GetColumnIndexByName(e.Row, columnName);
TextBox txt = new TextBox();
txt.Text = Convert.ToString(DataBinder.Eval(e.Row.DataItem, columnName));
txt.BorderColor = Color.Red;
txt.ID = "txt_" + i + "_" + colindex;
lstErrorTracker.Add(i + "_" + colindex);
//link.NavigateUrl = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "PV_INVOICE_LOCATION"));
e.Row.Cells[GetColumnIndexByName(e.Row, columnName)].Controls.Add(txt);
}
}
Now if I change some data in text box of gridview I want that to be fetch whenever I click Update button. Update button is placed outside of gridview as a normal asp.net button.
But when I am trying to fetch the data I am getting null.
foreach (GridViewRow row in GVUploadDetails.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
TextBox txt= (row.Cells[3].FindControl("txt_0_3") as TextBox);
var test = txt.Text;
}
}
I am getting text data as null. Please help how to get those values. And on other hand I want the entire data of the gridview as a Dataset or datatable how can I get that.
The NamingContainer is the GridViewRow not the cell, so you should use:
foreach (GridViewRow row in GVUploadDetails.Rows)
{
TextBox txt = row.FindControl("txt_0_3") as TextBox;
// ...
}
If this doesn't fix the issue, where in the page's life-cycle do you addd this TextBox programatically? You know that you always have to re-create it on every consecutive postback? Do that latest in Page_Load, better Page_Init.
If you add it from RowDataBound you have to re-create it in RowCreated, otherwise it's too late to retain the ViewState.

DetailsView in ASP.Net - How to add another column on the side/add a control in each row?

I have a DetailsView control on my page used to edit various fields of a record, which works well in this respect.
I am looking for a way to add one column (and if that works, why not more) to the right, which will be absolutely read-only, to show the same fields of another record for comparison purposes.
I am aware there is no obvious way to do such thing out of the box with DetailsView. I have looked into other controls (transposed GridView, someone recommended FormView, ListView), but nothing satisfies. I have some very special data binding setup using the DetailsView and I can't get out of it without losing some features.
Anyone on how to "hack in" additional columns (for display only) on a DetailsView ?
The solution I have now, is to use a second DetailsView, with Visible set to False in my aspx.
In the code, I make sure to DataBind the hidden DetailsView that hosts the data for my third column first, then the initial DetailsView named ItemDetails.
And in the item created event, I pass to a third column the html rendering of my hidden controls (in the last code block) :
protected void ItemDetails_ItemCreated(object sender, EventArgs e)
{
if (dataItem2 != null) //compare enabled
{
var headerRow = ((DetailsView)sender).HeaderRow;
var headerL = new Label();
headerL.Text = header2;
headerL.Style.Add("font-weight", "bold");
var headerCell = new TableCell();
headerCell.Controls.Add(headerL);
headerCell.Style.Add("text-align", "right");
headerRow.Cells.Add(headerCell);
if (string.IsNullOrEmpty(header1) && string.IsNullOrEmpty(header2)) ((DetailsView)sender).HeaderRow.Visible = false;
}
else
{
((DetailsView)sender).HeaderRow.Visible = false;
}
foreach (DetailsViewRow r in ItemDetails.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
// Assume the first cell is a header cell
var dataCell = (DataControlFieldCell)r.Cells[0];
string dataFieldName = null;
if (dataCell.ContainingField is CustomBoundField) dataFieldName = ((CustomBoundField)dataCell.ContainingField).GetDataFieldName();
else if (dataCell.ContainingField is BoundField) dataFieldName = ((BoundField)dataCell.ContainingField).DataField;
if (dataItem2 != null) //compare enabled
{
if (!string.IsNullOrEmpty(dataFieldName)) //it's a field, copy boundField from hidden DetailsView
{
var ct = new TableCell();
var text = new StringWriter();
var html = new HtmlTextWriter(text);
dict[dataFieldName].RenderControl(html);
ct.Text = text.ToString().Replace("<td>", String.Empty).Replace("</td>", String.Empty);
r.Cells.Add(ct);
}
}
}
}
}

Programmatically adding bound Gridview to tabPanels

I want to add GridView programmatically in a TabPanel. In fact the tab panels themselves are created programmatically so I want to create a GridView for each TabPanel.
Here is the code to create the tab panels:
while (j < l.Count)
{
AjaxControlToolkit.TabPanel panel = new AjaxControlToolkit.TabPanel();
panel.HeaderText = testrub.RubricName.ToString();
GridView grid = new GridView();
grid.DataSource = element.GetElementByRubric(testrub.ID);
panel.Controls.Add(grid);
TabContainer1.Tabs.Add(panel);
j++;
}
As you can see the gridview that I want to create is databound. I would seriously appreciate some help. :)
Add this one line to your code
GridView grid = new GridView();
grid.DataSource = element.GetElementByRubric(testrub.ID);
grid.DataBind(); // <------ this new line

How to access a dynamically created control's value in a gridview in ASP.NET

I can't figure out how to access the value of a control in a dynamically-created gridview. Thhe problem is that I don't know the name of the control. If I knew the name of the control I could do just do this :
string dropDownListText =((DropDownList).row.FindControl("DropDownList1")).SelectedItem.Value;`
I know the type of control and I know the cell it is in. Is there any way using the information about the control I have to be able to access the control's value?
If you know what cell it is, then you could do something like this;
TableCell tc = GridView1.Cells[indexOfCell];
// where GridView1 is the id of your GridView and indexOfCell is your index
foreach ( Control c in tc.Controls ){
if ( c is YourControlTypeThatYouKnow ){
YourControlTypeThatYouKnow myControl = (YourControlTypeThatYouKnow)c;
}
}
If you don't know what cell it is exactly, then you can always loop through each cell. I am sure there is a better way in Linq.
With Linq (I think this should work)
var controls = GridView1.Cells[indexOfCell].Cast<Control>();
YourControlTypeThatYouKnow myControl = (YourControlTypeThatYouKnow) controls.Where( x => x is YourControlTypeThatYouKnow).FirstOrDefault();
On ItemDataBound event handler of GridView, access the table-cell as follows. Within the cell, Controls collection provides you access to ASP control embedded in the cell
TableCell cell = e.Item.Cells[0];
if (cell.Controls.Count > 0)
{
cell.Controls[0].Visible = false;
}
I have had the same problem. Add a command name to your field like CommandName="ProjectClick". Then add a rowcommand and in the row command do this:
if (e.CommandName.Equals("ProjectClick")) {
}
or you can use the text:
if (e.CommandName.Equals("")) {
if (((System.Web.UI.WebControls.LinkButton)(e.CommandSource)).Text.Equals("Projects")) {
}
}

New Row Created In DataGridView When AutoComplete Dropdown Clicked On

I've implemented AutoComplete like this in my DataGridView on several of my textbox columns.
var source = new AutoCompleteStringCollection();
List<string> values = new List<string>();
for (int i = 0; i < dataGridRoadway.Rows.Count - 2; i++)
{
if (columnName == "Road Name")
{
values.Add(dataGridRoadway.Rows[i].Cells["Road Name"].Value.ToString());
}
}
source.AddRange(values.ToArray());
//Set the appropriate properties on the textbox control
TextBox dgvEditBox = e.Control as TextBox;
if (dgvEditBox != null)
{
dgvEditBox.AutoCompleteMode = AutoCompleteMode.Suggest;
dgvEditBox.AutoCompleteCustomSource = source;
dgvEditBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
}
When an item from my AutoComplete source is selected using the mouse, the current row is incorrectly set to a new row (selecting an item from AutoComplete using the arrows and tab doesn't trigger a new row). This in turn, fires the RowValidating event and runs my validation logic on the entire row before the user is actually done entering data from that row.
I would guess that DataGridView detects my mouse click on the AutoComplete dropdown and associates it with clicking on a new row. Of course, this is not the behavior I need. Is there a way around this? Is there a way to detect an AutoComplete selection and then override the new row being created?

Categories