I got i strange situations.
This is a part of the ascx code of my gridview
<asp:gridview ID="grdBooks" class="grdBooks" runat="server" width="100%" DataKeyNames="RecId,RefAuthorsRecId,RefBooksTypeRecId" autogeneratecolumns="false" onDataBound="grdBooks_dataBound" onPreRender="grdBooks_preRender" onrowediting="grdBooks_RowEdit" onrowupdating="grbBooks_onRowUpdating" onrowupdated="grdBooks_onUpdated" autogenerateeditbutton="true" onrowcancelingedit="grdBooks_onCancelingEdit">
<Columns>
<asp:TemplateField HeaderText="Title">
<EditItemTemplate>
<asp:TextBox ID="txtgrdTitle" runat="server" width="200px"></asp:TextBox>
<asp:Label ID="lblgrdTitle2" runat="server" visible="false" Text='<%# Eval("Title") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblgrdTitle" runat="server" Text='<%# Bind("Title") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>.....
This is a part of the "onRowEdit" and "onRowUpdating"
protected void grdBooks_RowEdit(object sender, GridViewEditEventArgs e)
{
grdBooks.EditIndex = e.NewEditIndex;
grdBooks.DataSource = book;
grdBooks.DataBind();
TextBox txtTitle = grdBooks.Rows[e.NewEditIndex].FindControl("txtgrdTitle") as TextBox;
Label lblTitle = grdBooks.Rows[e.NewEditIndex].FindControl("lblgrdTitle") as Label;
txtTitle.Text = lblTitle.Text;
}
protected void grbBooks_onRowUpdating(object sender, GridViewUpdateEventArgs e)
{
TextBox txtTitle = grdBooks.Rows[e.RowIndex].FindControl("txtgrdTitle") as TextBox;
....
}
The problem is:
the rowEdit works fine, change all the row of the grid in editable textboxes. The problem is that i write something in the text boxes and when i press "update" and go into the "onRowUpdate" method i haven't the new text(that i have inserted) in the textbox object that i have initialize. I got the old one.
(as u see now i use a not visible label in the editTemplate that carry the value of the original Title. Before i had Eval("title") on the textbox text but i thought that this was the probl so i try this other way)
As your datasource is book.Get the currentrow of the datatable and update values in that row.Then bind the grid again.
GridViewRow gridEditRow = this.grdBooks.Rows[e.RowIndex];
DataRow CurentRow = book.Rows[gridEditRow.DataItemIndex];
CurentRow["Title"] = (gridEditRow.FindControl("txtgrdTitle") as TextBox).Text;
Related
I'm trying to do a simple To-Do list application in ASP.NET with C# and I have a problem when I want to update the GridView with a value from a DropDownList. I've read a lot of solved question about this problem on this site but none of them worked so far or I must have missed something. Based on those answers I tried 2 method:
Method: I added a GridView to display and a FormView to add the Tasks. I created a database with a table for Tasks with Id, Name, Priority, DueDate, Completed columns and one table for priority possibilities(Low-Medium-High)
My code looks this was:
ASP.NET GridView part:
<asp:GridView ID="grdTasks" runat="server" AutoGenerateColumns="False" OnRowDataBound="grdTasks_RowDataBound" BackColor="White" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px" CellPadding="3" ForeColor="Black" GridLines="Vertical" OnRowEditing="grdTasks_RowEditing" AutoGenerateDeleteButton="True" AutoGenerateEditButton="True" OnRowCancelingEdit="grdTasks_RowCancelingEdit" OnRowUpdating="grdTasks_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="Id">
<EditItemTemplate>
<asp:TextBox ID="txtId" runat="server" Text='<%# Bind("Id") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblId" runat="server" Text='<%# Bind("Id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:TemplateField HeaderText="Priority">
<EditItemTemplate>
<asp:DropDownList ID="ddlPriority" runat="server" AppendDataBoundItems="True">
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblPriority" runat="server" Text='<%# Bind("Priority") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DueDate" HeaderText="DueDate" />
<asp:TemplateField HeaderText="Completed">
<EditItemTemplate>
<asp:Checkbox ID="chkCompleted" runat="server" Text='<%# Bind("Completed") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:TextBox ID="txtCompleted1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
C# part:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindTasks();
}
}
private void BindTasks()
{
SqlDataSource sqlDtsTasks = new SqlDataSource();
sqlDtsTasks.ID = "sqlDtsTasks";
this.Page.Controls.Add(sqlDtsTasks);
sqlDtsTasks.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
sqlDtsTasks.SelectCommand = "SELECT * FROM Tasks";
grdTasks.DataSource = sqlDtsTasks;
grdTasks.DataBind();
}
protected void grdTasks_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
DropDownList ddlPriority =
(DropDownList)e.Row.FindControl("ddlPriority");
SqlDataSource sqlDtsTasks = new SqlDataSource();
SsqlDtsTasks.ID = "sqlDtsTasks";
this.Page.Controls.Add(sqlDtsTasks);
sqlDtsTasks.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
sqlDtsTasks.SelectCommand = "SELECT [States] FROM [Reference]";
ddlPriority.DataSource = sqlDtsTasks;
ddlPriority.DataTextField = "States";
ddlPriority.DataValueField = "States";
ddlPriority.DataBind();
DataRowView dr = e.Row.DataItem as DataRowView;
ddlPriority.SelectedValue =
dr["Priority"].ToString();
}
}
}
protected void grdTasks_RowEditing(object sender, GridViewEditEventArgs e)
{
grdTasks.EditIndex = e.NewEditIndex;
BindTasks();
}
protected void grdTasks_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
grdTasks.EditIndex = -1;
BindTasks();
}
protected void grdTasks_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
SqlDataSource sqlDtsTasks = new SqlDataSource();
sqlDtsTasks.ID = "sqlDtsTasks";
this.Page.Controls.Add(sqlDtsTasks);
sqlDtsTasks.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string Priotext = (grdTasks.Rows[e.RowIndex].Cells[2].FindControl("ddlPriority") as DropDownList).SelectedItem.Value;
string Id = (grdTasks.Rows[e.RowIndex].Cells[0].FindControl("txtId") as TextBox).Text;
sqlDtsTasks.UpdateCommand = "UPDATE Tasks SET [Priority] = #Priority WHERE [Id] = #Id";
--> SqlDataSource2.UpdateParameters["Id"].DefaultValue = Id;
--> SqlDataSource2.UpdateParameters["Priority"].DefaultValue = Priotext;
grdTasks.DataSource = sqlDtsTasks;
grdTasks.DataBind();
}
This way I get the following error from the line marked with the arrow:
System.NullReferenceException - Object reference not set to an instance of an object.
This should mean that I got a null value from the ddl and the textbox but I dont know why, when I try to display the values of the ddl and textbox with a label, it displays it correctly.
Method: I basically did the same, but instead of doing it from code, I added 2 SqlDataSource. The first is binded to the GridView to display the Tasks. The second is binded to the DropDownList to display the Priority possibilities(Low-Medium-High). Also, I used the DataBindings from the smart tag of the DropDownList to bind the SelectedValue to the Priority column. This way, I can choose a priority when editing the row and I can update the Priority column if the current value in the db is null. BUT, when I want to update again, e.g. from Low to High I get this error:
System.ArgumentOutOfRangeException 'ddlPriority' has a SelectedValue which is invalid because it does not exist in the list of items.
As I've read about this many people pointed out that I should add a code like this and set the AppendDataBoundItems to true:
"<asp:ListItem Value=""></asp:ListItem>"
I even tried to add a line for each value like the one above, still the same error. What do I missing?
I have a grid view with a column:
<asp:BoundField DataField="ClosedDate" HeaderText="ClosedDate" SortExpression="ClosedDate" ReadOnly="True" ItemStyle-Width="11%" />
In gridview edit mode when a value is selected in a dropdown then I want to give this ClosedDate cell a value
I have the following code:
protected void ddlState_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow gvr = (GridViewRow)(((Control)sender).NamingContainer);
DropDownList duty = (DropDownList)gvr.FindControl("ddlState");
stateValue = duty.SelectedItem.Value;
if (stateValue == "3")
{
}
}
I only want to update the current edited cell.
I am not sure how to do this.
The row has a few columns but closedDate is empty until state = 3 then give the closedDate cell a date a value or now()
you may use asp:TemplateField with a TextBox instead of asp:BoundField. Then in your DropDownlist_selectedIndexChanged update the value of TextBox
<asp:TemplateField HeaderText="ClosedDate" SortExpression="ClosedDate" ItemStyle-Wrap="false">
<ItemTemplate>
<asp:Label ID="lblCD" runat="server" Text='<%# Eval("ClosedDate") %>'/>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtCD" runat="server" Text='<%# Bind("ClosedDate") %>'/>
</EditItemTemplate>
</asp:TemplateField>
I am trying to modify the content of a TextBox in the OnRowEditing event of the gridview but I cannot seem to find the TextBox control in code behind.
The field in aspx:
<asp:TemplateField HeaderText="AssignTo" SortExpression="AssignTo">
<EditItemTemplate>
<asp:TextBox ID="txtAssignTo" runat="server" Text='<%# Bind("AssignTo") %>' ClientIDMode="Static"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("AssignTo") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Trying to find it in code behind:
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridViewRow grow = GridView1.Rows[e.NewEditIndex];
TextBox txt = grow.FindControl("txtAssignTo") as TextBox;
}
The txt variable is always null. Not sure what I am missing here.
You have to bind the gridview after you set the editindex (call its DataBind() method)
I have a DetailsView bound to an EntityDataSource and am trying to get the values from my TextBoxes in the EditItemTemplates.
Here is my code:
<asp:DetailsView ID="DetailsView1" DataKeyNames="Name" runat="server" AutoGenerateRows="False"
OnDataBound="DetailsView_DataBound" DataSourceID="eds2" BorderWidth="0"
OnModeChanging="OnModeChanging" AutoGenerateEditButton="true"
OnItemUpdated="DetailsView_OnItemUpdated" OnItemUpdating="DetailsView_OnItemUpdating"
EmptyDataText="N/A" OnDataBinding="DetailsView_OnDataBinding" CellPadding="0"
CellSpacing="7" GridLines="None" CssClass="Center">
<Fields>
<asp:TemplateField HeaderText="Name">
<EditItemTemplate>
<asp:TextBox ID="txtName" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<Fields>
</asp:DetailsView>
And the code behind:
protected void OnModeChanging(object sender, DetailsViewModeEventArgs e)
{
foreach (DetailsViewRow row in DetailsView1.Rows)
{
if (row.RowType != DataControlRowType.DataRow) continue;
foreach (DataControlFieldCell cell in row.Cells)
{
var textbox = cell.FindControl("txtName");
var textbox2 = row.FindControl("txtName");
}
}
}
textbox and textbox2 are always null. What am I doing wrong? How can I get either the textbox or the value inside it?
You have these textboxes declared in your edit template. These will only show up when your mode has been set to edit. I'm guessing this hasn't happened yet when the ModeChanging event is fired.
Put your code in your ModeChanged event, and check to see that you're editing.
void DetailsView1_ModeChanged(object sender, EventArgs e)
{
if (DetailsView1.CurrentMode != DetailsViewMode.Edit)
return;
foreach (DetailsViewRow row in DetailsView1.Rows)
{
var textbox = row.FindControl("txtName");
}
}
Hi I have a grid view with a textbox in each row that im trying to get the value of in the RowCommand event. The below code works fine for all rows expect the first one. The textbox.text value for the first row in always empty.
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_OnRowCommand" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
Title <%# Eval("Title")%>
<asp:TextBox ID="TextBoxAddPost" runat="server"></asp:TextBox>
<asp:LinkButton ID="LinkButtonAddPost" CommandName="AddPost" CommandArgument='<%# Eval("postId") %>' runat="server">Add Post</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack)
bindGridView();
}
protected void GridView1_OnRowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "AddPost")
{
GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
TextBox textBox = (TextBox)row.FindControl("TextBoxAddPost");
//Empty for first row but works for all others
Debug.WriteLine("row: " + row.RowIndex + ", textBox:" + textBox.Text.Trim());
GridView1.DataBind();
}
}
The above code has been simplified for illustration purposes. Each row actually contains a child gridview, hence why in need the text box in each row. I fear that the binding in the page_load is overwriting the value of the text box, however, without the page_load binding, the rowCommand Event is not fired.
I find i a bit strange the it works fine for all rows except the first.
For getting data from textbox, You have to set text property first by putting below code.
<asp:TextBox ID="TextBoxAddPost" runat="server" Text='<%# Eval("Title") %>'></asp:TextBox>
It will definitely give value from textbox.
Either way, You can also set datakeynames property of gridview.Click here for datakeynames
I tried this and it works fine,GridView1_OnRowCommand fires by clicking on LinkButtonAddPost:
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBoxAddPost" runat="server" Text='<%# Eval("ID") %>'></asp:TextBox>
<asp:LinkButton ID="LinkButtonAddPost" CommandName="AddPost" CommandArgument='<%# Eval("ID") %>' runat="server">Add Post</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and change your page_load event like this:
protected void Page_Load(object sender, EventArgs e)
{
GridView1.DataSource = Data.RequestPaymentDB.GetRequestPaymentByRequestID(9208060001);
GridView1.DataBind();
}
compare your code with mine.