how to access templatefield from code behind - asp.net

the reason why i am looking to update dynamic is because i am using objectdatasource and my objectdatasource have a collection of object and within that object i have another object that i wanted to access so for an example:
+Student
......
......
......
-Courses
.........
.........
Name
Update end
how do i bind templatefield from code-behind?
<asp:Gridview ID="gridview1" runat="Server">
<columns>
<asp:TemplateField HeaderText="Name" SortExpression="Name">
<ItemTemplate>
</ItemTemplate>
</asp:TemplateField>
</columns>
</asp:Gridview>

First of all define your key field in GridView control, just add net attribute to GridView markup: datakeynames="StudentID".
You can use both event handler for GridView: RowDataBound or RowCreated. Just add one of this event handler and find there control that is placed in your ItemTemplate. Like here, for instance:
void ProductsGridView_RowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
// Retrieve the LinkButton control from the first column.
Label someLabel = (Label)e.Row.FindControl("someLabel");
if (someLabel != null)
{
// Get Student index
int StudentId = (int)GridView.DataKeys[e.Row.RowIndex].Values[0];
// Set the Label Text
// Define here all the courses regarding to current student id
someLabel.Text = //
}
}
}
This example was gotten from MSDN

Here are some code samples from MSDN:
http://msdn.microsoft.com/en-us/library/aa479353.aspx
These are in VB but you should be able to locate C# also :-)
If you follow this link and scroll down you will find a code sample:
http://bytes.com/topic/asp-net/answers/624380-gridview-generated-programmatically

Related

select data from gridview field and populate textbox

I'm trying to populate a single text box (or parameter) with data from a gridview column when I click on a button in that row.
Gridview gets it data from a sqlconnection
the gridview is
| Drawing |
| 12345 | VIEW
| 12346 | VIEW
the VIEW is a template button with an onclick event, when the user clicks the button the data from the Drawing column (12345) should be passed to ether a textbox or a paremeter. (this is the part I dont know how to do) once the Iv got the number in a textbox I can use it as pareameter and then a pdf is opened of that drawing, I have code for this and is working.
thanks for any help
If you are using C#, the simplest thing to do would be to add an in-built select command button to the gridview rows at runtime. Then on the selectedindexchanged event of the gridview simply access the cell of the selected row that you want the value from. You can then assign that string to anything you want. Like so:
protected void myGridView_SelectedIndexChanged(object sender, EventArgs e)
{
string myString = myGridView.SelectedRow.Cells[4].Text.ToString();
TextBox1.Text = myString;
}
Remember that the cell index collection is zero based, so [0] is actually the first cell in the row.
Use TemplateFields and the grid view's OnRowCommand event, like this:
Markup:
<asp:gridview id="GridView1"
OnRowCommand="GridView1_RowCommand"
runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBoxDrawing" runat="server"
Text="<%# Eval("Drawing")) %>" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="selc" runat="server" Text="View"
CommandName="View"
CommandArgument="<%# ((GridViewRow)Container).RowIndex %> />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code-behind:
protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked
if(e.CommandName == "View")
{
// Convert the row index stored in the CommandArgument
// property to an integer
var index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button clicked
// by the user from the Rows collection
var row = GridView1.Rows[index];
// Find the drawing value
var theDrawingTextBox = row.FindControl("TextBoxDrawing") as TextBox;
// Verify the text box exists before we try to use it
if(theDrawingTextBox != null)
{
var theDrawingValue = theDrawingTextBox.Text;
// Do something here with drawing value
}
}
}

Specifying constant value in the gridview hyperlink

I have a gridview with a HyperLinkField column where the DataNavigateUrlFormatString is as following:
DataNavigateUrlFormatString="DetailedPage.aspx?OrderNo={0}"
I would like to add to the above DataNavigateUrlFormatstring another value – constant - so that the called page (DetailedPage can get both the value of OrderNo (passed dynamically) and the same value for all rows.
For example, the url would be something like:
DetailedPage.aspx?OrderNo=100&filename=’myfilename.doc’
Note, again that the name ‘myfilename.doc’ is the same for all rows but will be known in the OnLoad of the page. Ideally I would like the second value (e.g. myfilename.doc) to be hidden from the URL
but if this is not possible, it will still work.
How can I do it?
Use a TemplateField with a HyperLink control inside and then in the RowDataBound event in code-behind, just set the NavigateUrl property to the value, like this:
Markup:
<asp:GridView id="GridView1" runat="server"
OnRowDataBound="GridView1_RowDataBound">
<Columns>
...Other columns here...
<asp:TemplateField>
<ItemTempalte>
<asp:HyperLink id="HyperLink1" runat="server" Text="Details" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code-behind:
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
// Only interact with the data rows, ignore header and footer rows
if(e.Row.RowType == DataControlRowType.DataRow)
{
// Find the hyperlink control by ID
var theHyperLink = e.Row.FindControl("HyperLink1") as HyperLink;
// Verify we found the hyperlink before we try to use it
if(theHyperLink != null)
{
// Set the NavigateUrl value here
theHyperLink.NavigateUrl = String.Format("DetailedPage.aspx?OrderNo={0}&filename='{1}'", theOrderNumber.ToString(), theFileName);
}
}
}
Note: theOrderNumber and theFileName would be values determined upon load of the page from the database, for example.

Determine the datatable index of the row clicked in GridView

I have a GridView in ASP.NET page. The GridView is bound to a dataset/datatabe. One of the columns of the grid is a command button and the gridview has method OnRowCommand (e.g. OnRowCommand="GridView_RowCommand") specified.
When user clicks on the button in the grid, the method GridView_RowCommand fires. I would like to find the index to the DataTable for the row where button was clicked. Note, that I am not looking for index to the GridView row but rather the index to the DataTable bound to the GridView.
Thank you in advance for your help.
You have a few options and it depends on the amount of data you are binding to the gridview, one you could save the dataset/datatable to Session[""] as you bind or you could retrieve the data from the database again once you have the unique id of the row. You could create the following on your gridview:
<asp:GridView ID="gvCustomer" runat="server"
AutoGenerateColumns="False" DataKeyNames="yourId" onrowcommand="gvCustomer_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkAction" runat="server" Text="Do Something" CommandName="yourEvent" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
then in the code behind for the RowCommand event have:
protected void gvCustomer_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "yourEvent")
{
var row = (GridViewRow)((LinkButton)e.CommandSource).NamingContainer;
int rowId = Convert.ToInt32(gvCustomer.DataKeys[row.RowIndex]["yourId"]);
}
}
At this point you have the id which you could either query the database again or access the data source object that you save in to session before binding to the gridview
Or another alternative is:
<asp:LinkButton CommandArgument='<%#Eval("PrimaryKey")%>' />
Then you can get the arg with e.CommandArgument in the gvCustomer_RowCommand method

DetailsView: How to set a HiddenField value using the CommandArgument on a New command?

I have inherited some code that has a GridView and a DetailsView in a webpart control.
The DetailsView is able to create two different kinds of an object e.g. TypeA and TypeB.
There's a dropdown list that filters the GridView by object type and the DetailsView has an automatically generated Insert button.
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="True"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemUpdating="OnItemUpdating"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnItemInserting="OnItemInserting"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
I have been asked to:
remove the filter on the GridView; and
split the New buttons/links into two so there's a separate button for creating each type of object.
Removing the filter means that I need some other way to track what kind of object we're creating.
I have split the New links by changing the above to:
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="False"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemUpdating="OnItemUpdating"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnItemInserting="OnItemInserting"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
and adding
<FooterTemplate>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkCreateNewTypeA" CommandName="New" CommandArgument="TypeA" CssClass="buttonlink">New Type A</asp:LinkButton>
<asp:LinkButton runat="server" ID="lnkCreateNewTypeB" CommandName="New" CommandArgument="TypeB" CssClass="buttonlink">New Type B</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</FooterTemplate>
I haven't yet removed the filter so the changes currently function the same as before, as I'm using the New command.
What I was hoping to be able to do is somehow capture the New event so I can put the CommandArgument value into a hidden field, that the DetailsView would then use to determine which type of object it's creating and also to show/hide fields.
When I put breakpoints in all of the event handlers in my code, the first one to break is OnDetailsViewModeChanging, which doesn't have access to the CommandArgument.
OnItemCommand (if it's hooked up) is triggered when any button within the DetailsView is pressed and does give me access to the CommandArgument but I'm not sure what exactly needs to be done within this method to mimic the chain of events that occurs when you use automatically generated buttons.
Is my only option for retrieving the CommandArgument to capture it in the OnItemCommand event handler or is there some other event that is triggered on the New command?
Can anyone explain to me the sequence of events that occurs when the New command is triggered?
I read somewhere that it changes the mode to Insert but I don't know what else it does. I believe the OnItemInserting method isn't called until the "Insert" link is clicked.
Any help would be gratefully received!!
Edit:
I have found this link on DetailsView events but it hasn't answered my question.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview_events.aspx
Edit:
I have tried adding the following:
in ascx:
<asp:DetailsView ID="myDetailsView"
...
OnItemCommand="OnItemCommand"
...
runat="server">
...
<asp:TemplateField HeaderText="Object Type" HeaderStyle-CssClass="columnHeader">
<ItemTemplate>
<asp:HiddenField runat="server" ID="hidObjectType" Value=""/>
<asp:Label runat="server" ID="lblObjectType"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
in code behind:
protected void OnItemCommand(object sender, DetailsViewCommandEventArgs e)
{
if (e.CommandName.Equals("New"))
{
var objectType = e.CommandArgument.ToString();
HiddenField typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField;
if (typeHidden != null)
{
typeHidden.Value = objectType;
}
Label typeLabel = this.myDetailsView.FindControl("lblObjectType") as Label;
if (typeLabel != null)
{
typeLabel.Text = objectType;
}
}
}
I found that I didn't need to set the mode (this.myDetailsView.ChangeMode(DetailsViewMode.Insert);) in this method, as the OnDetailsViewModeChanging event handler still triggered.
This finds the controls and sets the values on them correctly. If I check the values again in OnDetailsViewModeChanging, their values are still set but as part of the logic in this method, there is a call to
this.myDetailsView.DataBind()
which causes a postback and at this point, the values are lost. I tried adding
EnableViewState="True"
but this made no difference. I've reviewed the page lifecycle (http://spazzarama.files.wordpress.com/2009/02/aspnet_page-control-life-cycle.pdf) and thought that maybe this.EnsureChildControls() would help but it's also made no difference.
An alternative would be to store the value in the session but I'd rather not.
As far as I can tell there is no event for capturing the "New" command aside from OnItemCommand, which captures all commands. (NOTE: You will need to make sure that CausesValidation="False" is set on your LinkButton or the code won't break into OnItemCommand).
When stepping through the code, the following occurred:
After the linkbutton was pressed, OnItemCommand is triggered. CommandName = "New" and here I could retrieve the CommandArgument
Next OnModeChanging is triggered. e.NewMode = "Insert". From all examples I've seen, here you call ChangeMode on the DetailsView and then call Databind() on it
Next OnDataBound is triggered as a result of calling Databind()
I didn't find a way to retain the value of the hidden variable between the various events so I ended up using a session variable. Code is below in case anyone wants it.
DetailsView declaration in the ASCX:
<asp:DetailsView ID="myDetailsView"
AutoGenerateInsertButton="False"
AutoGenerateEditButton="True"
AutoGenerateRows="false"
OnItemInserting="OnItemInserting"
OnItemUpdating="OnItemUpdating"
OnItemCommand="OnItemCommand"
DefaultMode="ReadOnly"
OnDataBound="OnDetailsViewBound"
OnModeChanging="OnDetailsViewModeChanging"
runat="server">
In the code-behind:
constant declarations...
private const string SESSIONKEY_MYVALUE = "MyValue";
private const string DEFAULT_OBJECTTYPE = "TypeA";
OnItemCommand event handler...
protected void OnItemCommand(object sender, DetailsViewCommandEventArgs e)
{
if (e.CommandName.Equals("New", StringComparison.InvariantCultureIgnoreCase))
{
var objectType = e.CommandArgument.ToString();
HiddenField typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField;
if (typeHidden != null)
{
typeHidden.Value = objectType;
}
HttpContext.Current.Session[SESSIONKEY_MYVALUE] = objectType;
}
}
OnModeChanging event handler....
protected void OnDetailsViewModeChanging(Object sender, DetailsViewModeEventArgs e)
{
if (e.NewMode == DetailsViewMode.Insert)
{
this.myDetailsView.ChangeMode(DetailsViewMode.Insert);
this.myDetailsView.DataBind();
}
}
OnDataBound event handler...
protected void OnDetailsViewBound(object sender, EventArgs e)
{
if (this.myDetailsView.CurrentMode == DetailsViewMode.Insert)
{
var sessionVar = HttpContext.Current.Session[SESSIONKEY_MYVALUE];
var objectType = sessionVar == null ?
DEFAULT_OBJECTTYPE :
sessionVar.ToString();
var typeHidden = this.myDetailsView.FindControl("hidObjectType") as HiddenField;
if (typeHidden != null)
{
typeHidden.Value = objectType;
}
}
}

How do I find the Client ID of control within an ASP.NET GridView?

I have a asp:GridView which contains a asp:TextBox within a TemplateField. I would like to obtain it's ID for use in javascript. Something like this:
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="textDateSent" runat="server" />
<input type="button" value='Today'
onclick="setToday('<%# textDateSent.ClientID %>');" />
</ItemTemplate>
</asp:TemplateField>
But when I compile, I get an error:
The name 'textDateSent' does not exist in the current context
Anybody know how to get the client ID of this TextBox?
Try this:
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="textDateSent" runat="server">
</asp:TextBox>
<input type="button" value='Today' onclick="setToday('<%# ((GridViewRow)Container).FindControl("textDateSent").ClientID %>');" />
</ItemTemplate>
</asp:TemplateField>
Maybe you don't want to do it where you need the ClientID. Check out this post here where the controls in a row are referenced in a generic way.
Change <%# textDateSent.ClientID %> to <%= textDateSent.ClientID %>.
Argh, you may need to use the OnDataBinding event of the grid view. Then put a literal control in your javascript. Then you can get the clientID of the text box and feed that into your literal control.
protected void GridViewName_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Create an instance of the datarow
DataRowView rowData = (DataRowView)e.Row.DataItem;
//locate your text box
//locate your literal control
//insert the clientID of the textbox into the literal control
}
}
Look here for a great detailed tutorial on working within this context.
You can get client id like this:
protected void Gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string strClientID = ((TextBox)e.Row.FindControl("txtName")).ClientID;
}
}
This will give unique client ID for each textbox in all rows.
I just do this...
var tbl = document.getElementById('<%=GridView.ClientID%>');
var checkBox = tbl.rows[i].cells[11].getElementsByTagName("input")[0].id;
the cell should always be the same and it gets rendered into an input. You may have to change the number at the end if you have more then one input in that cell. This will give you the new clientid/id of the input object (checkbox or whatever)
This is what I did. In the aspx page I just passed the entire object to the javascript function, so I didn't even meed to client id. In my case the object was a drop down list in the EditItemTemplate of the GridView. I added an html onchange(this) event in the aspx code.
<asp:DropDownList ID="custReqRegionsDDL" runat="server" onchange='custReqRegionsDDLOnChange(this)'>
</asp:DropDownList>
here is my javascript
function custReqRegionsDDLOnChange(myDDL)
{
alert('selected text=' + myDDL.options[myDDL.selectedIndex].text);
}

Resources