I am dynamically adding a textbox to certain rows (one column only) of a gridview. I add the controls with this insdie of a test condition (works fine):
TextBox txtASIN = new TextBox();
txtASIN.ID = "TxtASIN" + e.Row.RowIndex;
e.Row.Cells[4].Controls.Add(txtASIN);
int i = e.Row.Cells[4].Controls.Count; //TEST: This returns 1 correctly
I want the user to be able to enter values into one or more of these textboxes and then update the database with a single button click (not one click for each row). The problem I'm having is how to access those values on a button click event. I did a simple test this way to try to see the value in the second row but get null in temp1 (I am certain there is a value entered in that textbox):
protected void btnUpdate1_Click(object sender, EventArgs e)
{
TextBox temp = (TextBox)GridView2.Rows[1].FindControl("txt1");
string temp1 = temp.Text;
int i = GridView2.Row.Cells[4].Controls.Count; //TEST: This returns 0 incorrectly }
Once I can make this work, I can iterate through the rows and do what I need to do with the values. I don't know if the text entered in the textbox is actually readable without a postback but I'm otherwise stumped. Open to better suggestions on how to do this.
Thanks.
EDIT: Here is where I am now. I can see the textboxes in my column fine. I put a break in on a button that attempts to read them and this is what I'm seeing. If I check GridView2.Rows[0].Controls.Count, I get 8, which is the correect number of columns. If I check GridVeiw2.Rows[0].Cells[4].Controls.Count, I get 0, which is wrong because the textbox is there. I can get a Count of 1 right after I dynamically create it but not when I perform a subsequent button click.
Can anyone explain this? I feel if I can get past this holdup, I can get the rest done.
Thanks again.
You need to assign an ID to the TextBox controls and then access them by that ID in FindControl(). Also, make sure you're adding the controls in the Page's Init() method of the life-cycle. That way it gets added to ViewState.
TextBox txt1 = new TextBox();
txt1.ID = "txt1";
e.Row.Cells[4].Controls.Add(txt1);
EDIT: I just remembered another possible solution. Instead of programatically creating the TextBox controls in the code-behind just create a TemplateField in the GridView.
Add Textbox TemplateField Column To GridView Programmatically
I would try a different approach, putting the text box in the html markup of the page and then control the visible or readonly property of it on the ItemDataBound event. That way, the control will always be there and you don't have to worry about the lifecycle stuff.
Related
I am kind of new to C# and Asp.Net, so this question might sound repetitive but I am not able to find a solution for this particular problem.
I have two buttons on my HTML page and a single class in .cs file. On one of the button clicks, I create a table programmatically (dynamically).
The table contains some checkboxes which are also created dynamically.
Table creation is one of the last tasks that I perform. Before that, I read several files and extract data from them to create the table. After the table is drawn, the user can select one or more checkboxes.
Now, how on second button click, can I know that which of the checkboxes were checked before the page reload? Currently I have made all these checkboxes member variables of the the only class that I have in the .cs file.
I tried adding checkbox event handler through C# code. But the handler is not getting called when the checkbox is checked. I don't want to set the 'autopostback' property of the checkbox to true since if thats set true, the page reloads after checking one of the checkboxes. User should be able to select multiple checkboxes.
Add your checkboxes dynamically and set a unique name for each checkbox. Checkboxes are only posted back to the server if the checkbox is checked, so you can test to see if it is checked by checking Request.Form to see if the name exists. For example, lets say you named your check boxes chk_[0-9] (i.e. chk_0, chk_1 etc till 9), you could check if they ticked by doing:
for(int i=0; i < 10; i++)
{
string chk_name = "chk_" + i.ToString();
if (Request.Form[chk_name] != null)
{
//checkbox is checked
}
else
{
//checkbox is not checked
}
}
Out of curiosity is it possible to open a form based on row selection in a datagrid? I would also need the form to show information based on the username in the datagrid. The persons username is included within the row of the datagrid.
You will have to code this, but yes, it is possible.
First, populate your DataGrid with data that you can handle.
On the DataGrid's Selection Changed event, read that data, create the form you want to show (if it does not already exist), and display it using Show().
This would be like a typical Menu program.
You can handle this under the following event
dataGridView1_CellClick
Get the CurrentCell value of the datagridiview
Check for the username exists or not as per you asked and show the respective form
Sample code:
if (this.dataGridView1.CurrentCell != null)
{
string strusrname=dataGridView1.CurrentCell.Value.ToString();
//Here find out for the user name from the string as you get the currentcell value of the datagridview
// Raise the corresponding form as per you required
}
Not really sure if this is what your after, as i don't no if you want to show the data on another pre-built form or create a new one, but here it goes.
This way you won't even need to worry about the row selected, assuming you have the username of the person bound to the datagrid you can create a hyperlinkcolumn like this:
<asp:HyperLinkcolumn DataNavigateUrlField="Username"
DataNavigateUrlFormatString="PersonForm.aspx?Username={0}"
HeaderText="More Details"
Text="View Person Details" />
Then the PersonForm can load the persons details. Or if you would like some help on how to catch the selected row on itemcommand then let me no.
Hope this helps.
EDIT: after your winforms tag update you may be interested in this: DataGridViewLink On MSDN
The general code is:
DataGridViewLinkColumn links = new DataGridViewLinkColumn();
links.UseColumnTextForLinkValue = true;
links.HeaderText = ColumnName.ReportsTo.ToString();
links.DataPropertyName = //Set your field here.
links.ActiveLinkColor = Color.White;
links.LinkBehavior = LinkBehavior.SystemDefault;
links.LinkColor = Color.Blue;
links.TrackVisitedState = true;
links.VisitedLinkColor = Color.YellowGreen;
DataGridView1.Columns.Add(links);
Once you have added a link you can catch it using DataGridView1_CellContentClick and do what you want with it, ie open a new form or alter the current one.
I have a couple GridViews that are dynamically created and placed into a PlaceHolder. When I mouse over the Select button, it shows __doPostBack('ctl00$bodyPlaceHolder$ctl0X','Select$Y'), where X = what I think is the GridView/Control index for the page and Y = row number of that GridView.
Since it is dynamically creating the GridViews, it makes sense that names them ctl0X, but on the PostBack how do I use this information?
I wouldn't even have this problem if adding the SelectedIndexChanged EventHandler worked, but it never gets called.
I found one other question like this, but the answer involved adding a GridView within my GridViews, which would also have to be dynamic, which brings me back to the original problem.
Edit
Okay, so I set gridViewDynamic.ID = "blahblah" + r.LastName, thus giving each GridView a unique name, so on mouseover in the page I get __doPostBack('ctl00$bodyPlaceHolder$blahblahSmith',Select$Y, I still can't access the items on PostBack because they no longer exist. So, I added the same GridView creation code to an if(IsPostBack), then called GridView gView = (GridView)this.Page.FindControl(blahblahSmith). Great, gView isn't null. But all the data in the rows are. Calling gView.Rows[0] returns null.
Use Page.FindControl("TheNameYouGaveTheDynamicGridView")
GridView grid = Page.FindControl("TheNameYouGaveTheDynamicGridView") as GridView;
If you are using MasterPages, you need to take a different approach to find the control on the page, but it is the same premise.
I have a GridView, each row has Edit button. After it's clicked, one of the columns turns into a drop down list where users can select value. Edit button becomes Update - so very simple usual scenario.
Now, I don't seem to be able to grab the selected drop down list after Update is clicked. Here is my code:
protected void gv_UpdateRow(string arg)
{
int currentIndex = gv.EditIndex;
gv.EditIndex = -1;
GridViewRow currentRow = gv.Rows[currentIndex];
try
{
string value2 = ((DropDownList)currentRow.FindControl("ddlValueTwo")).SelectedItem.ToString();
}
catch
{
Response.Write("error");
}
BindGridView();
}
So basically, the program execution always ends up at the catch statement. I have checked and drop down list is found, the exception is thrown when selected item is not found.
What gives?
I use c# asp.net 2.0 web forms
Looks like a databinding error, you are trying yo access data that is not present yet...
got it!
it was the IsPostback, I was missing it, so the gridview was being rebound every page load, and since the drop down list is inside the grid, the data was lost.
However, one thing I forgot to mention here is that all this code sits inside the user control (ascx file) and IsPostBack property applies to the page not the control, which is useless in my case. For example, in my circumstances I add the control manually, so IsPostback will ALWAYS be true, so to avoid this problem I had to implement a session based solution. Hope this helps someone.
There also usercontrol.IsPostBack property but it didn't perform as expected, perhaps they got it right for 3.0
First thought is that you should probably do SelectedItem.Value rather than SelectedItem.ToString().
I am working on a datagridview in C# in windows application. I want to add textbox controls in DataGridView. So, when we run it then textbox should be shown in gridview and we can put value in it and My grid has 3 columns and I want to add new row in grid when I press tab on 3rd column of gridview.
How do I do this?
It's hard to provide a precise answer since your question is lacking in detail and pretty general, but to get textboxes in your DataGridView, you're going to want to add some instances of DataGridViewTextBoxColumn to the DataGridView's Columns collection. This will cause them to be populated with textboxes in each row.
To detect when the user presses tab on the 3rd column, you can add a 1-2 pixel wide fourth column and detect that it has recieved focus (almost definitely from a tab keystroke) using the OnCellEnter event.
Good luck!
So, for the "display textboxes by default portion of your question, here's the skinny:
On GridView->Edit Columns, add the columns you want to use explicitly. Then click on the link "Convert this field into a templateField". This will let you tweak the generated HTML for those cells. Say OK. Then go to GridView->Edit Templates. For your favorite Column, copy the ItemEditTemplate into the ItemTemplate. (ItemTemplate is the default. ItemEditTemplate contains the properly bound edit control.) Now all of your data fields will default to "editable."
I'm guessing you have a submit button. You'll need to tell the GridView to update the rows on submit., like so:
For Each r As GridViewRow In GridView1.Rows
Dim mon = System.Int32.Parse(CType(r.FindControl("TextBox1"), TextBox).Text)
If mon <> 0 Then GridView1.UpdateRow(r.RowIndex, False)
Next
Obviously, you'll want different logic inside there, but the basic loop/findControl/updateRow logic should apply.
Microsoft has a walkthrough on this here: Performing Bulk Updates to Rows Bound to a GridView
Try this, for example if you want to set your first column in datagridview as a textbox control:
private void dtgrdview_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 0)
{
TextBox txtbox1=new TextBox();
dtgrdview.Controls.Add(txtbox1);
Rectangle rectangle = dtgrdview.GetCellDisplayRectangle(0, e.RowIndex, true);
txtbox1.Location = rectangle.Location;
txtbox1.Size = rectangle.Size;
txtbox1.TextChanged += txtbox1_TextChanged;
txtbox1.Leave += txtbox1_Leave;
txtbox1.Visible = true;
}
}
and don't forget to add this event in the same class as like below to call it when the cell have the focus:
private void txtbox1_Leave(object sender, EventArgs e)
{
txtbox1.Visible = false;
}
private void txtbox1_TextChanged(object sender, EventArgs e)
{
dtgrdview.CurrentCell.Value = txtbox1.Text;
}
If you have any other questions, don't hesitate to ask me :)