How to put GridView into edit mode while nested in two Repeaters? - data-binding

I have a Gridview inside a Repeater inside another Repeater. The declarative code looks like this:
<asp:Repeater id="parentRepeater" runat="server">
<itemtemplate>
<b> <%# DataBinder.Eval(Container.DataItem, "Name") %></b>
<div>
<asp:repeater id="childRepeater" runat="server" datasource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("myrelation") %>' OnItemDataBound="getNestedData">
<itemtemplate>
<div><%# DataBinder.Eval(Container.DataItem, "Owner") %></div>
<div><asp:GridView ID="Grd" runat="server" AutoGenerateColumns="false" OnRowEditing="EditRecord" HorizontalAlign="Left" Width="100%">
</asp:GridView></div>
</itemtemplate>
</asp:repeater>
</div>
</itemtemplate>
</asp:repeater>
The imperative code-behind looks like this:
public void Page_Load(object sender, EventArgs e)
{
SqlConnection cnn = new SqlConnection("asdf");
SqlDataAdapter cmd1 = new SqlDataAdapter("select * from tblNames", cnn);
DataSet ds = new DataSet();
cmd1.Fill(ds, "names");
SqlDataAdapter cmd2 = new SqlDataAdapter("select * from tblThings", cnn);
cmd2.Fill(ds, "things");
ds.Relations.Add("myrelation",
ds.Tables["names"].Columns["id"],
ds.Tables["things"].Columns[NameID"]);
parentRepeater.DataSource = ds.Tables["names"];
Page.DataBind();
cnn.Close();
}
So that will set up the parent repeater, and the child repeater, and when the child repeater has an itemdatabound, the following happens which binds the gridview:
public void getNestedData(Object Sender, RepeaterItemEventArgs e)
{
GridView subGridView = (GridView)e.Item.FindControl("Grd");
DataRow rowView = (DataRow)e.Item.DataItem;
Int32 key = (Int32)rowView["id"];
SqlConnection cnn = new SqlConnection("asdf");
SqlDataAdapter cmd1 = new SqlDataAdapter("select * from tblSubThings WHERE ThingID = " + key, cnn);
DataSet ds = new DataSet();
cmd1.Fill(ds, "subThings");
subGridView.DataSource = ds.Tables["subThings"];
TemplateField edit = new TemplateField();
edit.ItemTemplate = new editGridViewTemplate(DataControlRowType.DataRow, "edit");
subGridView.Columns.Add(edit);
TemplateField Notes = new TemplateField();
Notes.ItemTemplate = new GridViewTemplate3(DataControlRowType.DataRow, "Notes");
Notes.HeaderTemplate = new GridViewTemplate3(DataControlRowType.Header, "Notes");
Notes.EditItemTemplate = new NotesEditGridViewTemplate(DataControlRowType.DataRow, "Notes");
subGridView.Columns.Add(Notes);
subGridView.DataBind();
}
This code all works fine. It shows gridview inside two repeaters, with an edit button. And when the edit button is fired, the gridview is supposed to go into edit mode (and use the EditItemTemplate). However, the gridview does not go into editmode when EditRecord is called. This is what EditRecord looks like:
public void EditRecord(object sender, GridViewEditEventArgs e)
{
GridView subGridView = (GridView)sender;
subGridView.EditIndex = e.NewEditIndex;
subGridView.Rows[e.NewEditIndex].RowState = DataControlRowState.Edit;
DataBind();
}
Does anyone know how I can get my GridView into edit mode?

Related

ASP.net databound field update value

I want to update only selected row, but entire rows were updated instead, like this:
before
after
Afterwards, I have tried using #SMT_Assembly for update statement but it give me error "Must declare the scalar variable". I'm new to ASP.net ,please make any necessary modification on my source code and your helps are much appreciated.
Homepage.aspx:
<asp:GridView ID="GridView1" DataKeyNames="SMT_Assembly" AutoGenerateColumns="false" runat="server" BackColor="White" BorderColor="#E7E7FF" BorderStyle="None" BorderWidth="1px" CellPadding="4" GridLines="Horizontal" Height="214px" Width="848px">
<asp:HyperLinkField DataTextField="IQA_status" NavigateUrl="ConfirmIQAstatus.aspx" HeaderText="IQA status"/>
<asp:HyperLinkField DataTextField="Overall_Status" NavigateUrl="ConfirmIQAstatus.aspx" HeaderText="Overall_Status"/>
</Columns>
</asp:GridView>
Homepage.cs
public partial class Homepage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SqlConnection sqlcon = new SqlConnection(#"Data Source=MYPENM0LSQLV01D\INST3;Initial Catalog=RTDF;Persist Security Info=True;User ID=*******; Password=*******");
String query = "UPDATE RTDF.dbo.SMT_CompWeight SET IQA_status = 'Open' where SMT_Assembly = #SMT_Assembly ";
SqlCommand retrieveCommand = new SqlCommand(query,sqlcon);
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = retrieveCommand;
DataSet ds = new DataSet();
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
sqlcon.Close();
}
}
Selecting the row event is fired when you make a click on the select link. If you need any particular item in that row you can easily select it using the cells property. In the Gridview, double-Click on the SelectedIndexChanged Event and write the following code:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
TextBoxUserID.Text = GridView1.SelectedRow.Cells[1].Text;
TextBoxUserName.Text = GridView1.SelectedRow.Cells[2].Text;
}
Source: https://www.c-sharpcorner.com/UploadFile/rohatash/how-to-get-the-selected-row-in-gridview-using-Asp-Net/
EDIT:
and I think for your grid you should add AutoGenerateSelectButton="True"
and if that doesn't work, try: OnSelectedIndexChanged="function" or onitemcommand="function"
it seems very similar to Telerik:RadGrid that I'm familiar with.

Putting data from SQL query into grid view asp.net

I have a grid box in which I want to fill data from a database where the username is one and their location was added in the last 24 hours.
I have tested the SQL query and it is working fine, however when trying to put the data in a grid box nothing happens.
Here is the code I have used in the aspx.cs file:
public partial class last24hours : System.Web.UI.Page
{
SqlConnection con = new SqlConnection(#"Data Source = sql2008.net.dcs.hull.ac.uk; Initial Catalog = rde_514872; Integrated Security = True");
protected void Page_Load(object sender, EventArgs e)
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT Location FROM StaffLocation WHERE [Date and Time]>= getdate()-1 AND [Username] = '1'";
cmd.Connection = con;
DataTable dt = new DataTable();
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
}
gridView1 is an empty grid view I have made with no sql source.
This is how the gridview is initialised in the aspx file:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
</asp:GridView>
You have AutoGenerateColumns set to false. And since you haven't defined any columns manually, of course nothing is going to show up. There's two fixes:
Set auto generate columns to true.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true" />
Or manually define your columns
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Location" HeaderText="Location" SortExpression="Location" />
</Columns>
</asp:GridView>

GridView RowCommand Event and Saving Text

I have a GridView set up:
<asp:GridView id="GridView1" Runat="server" AutoGenerateColumns="False" OnRowCommand = "GridView1_RowCommand" EnableViewState="true">
<Columns>
<asp:TemplateField HeaderText="Delete" ItemStyle-HorizontalAlign="Center">
<ItemTemplate><asp:Button runat="server" ID="Delete" ImageUrl="~/images/Close.gif" CommandName="DeleteRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>"/></ItemTemplate></asp:TemplateField>
<asp:TemplateField HeaderText="Comment" ItemStyle-Width="175px">
<ItemTemplate><textarea class="raTextBox" id="txtItemComment" rows="4" cols="30"></textarea></ItemTemplate></asp:TemplateField>
</Columns>
</asp:GridView>
The RowCommand in code-behind is setup like:
Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs)
If (e.CommandName = "DeleteRow") Then
//do stuff here
The GridView is data bound on Page Load as follows:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
Session("CalledModule") = "RCMT0021"
Else
With ViewState
_intRepor = CInt(.Item("Report"))
End With
End If
DataBind() //Gridview Load
End Sub
My questions:
The row command event is never fired. The page just goes into the ELSE (of Not is Postback) in Page_Load
How can I keep track of what all is typed in the "Comments" column of each row (a TEXTAREA), and save the data to the database when a SAVE CHANGES (form) button is clicked?
Thanks!
UPDATE:
The Grid-View's Databinding is as follows:
Public Sub DataBind()
Dim clsDatabase As New clsDatabase
Dim cmd As New OleDbCommand()
Try
cmd.CommandText = "SELECT A, B FROM WHERE C = ? ORDER BY A"
Dim report As New OleDbParameter("#Report", _intReportNumber)
cmd.Parameters.Add(report)
cmd.Connection = clsDatabase.Open_DB()
Dim dReader As OleDbDataReader
dReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
Dim dt As New DataTable
dt.Columns.Add(New DataColumn("PictureURL", GetType(String)))
dt.Columns.Add(New DataColumn("Seq", GetType(Int16)))
dt.Columns.Add(New DataColumn("ReportNumber", GetType(String)))
Do While (dReader.Read())
Dim dr As DataRow = dt.NewRow()
_strComments = dReader(0).ToString
dr("Seq") = dReader.GetInt16(1)
dr("PictureURL") = "GetImages.aspx?report=" + _intReportNumber.ToString + "&seq=" + dReader.GetInt16(1).ToString
dr("ReportNumber") = _intReportNumber.ToString
dt.Rows.Add(dr)
Loop
GridView1.DataSource = dt
GridView1.DataBind()
Catch err As Exception
End Try
End Sub
So basically, the GridView has three visible columns - a comments field, a picture field, and a field with a delete button (image) to delete the picture (and comments, if any) from the database. The 4th column is a hidden one, keeping track of the the Image ID of the images. I didn't include the picture and other columns for simplicity sake.
The user can add comments, and when he clicks a 'SAVE CHANGES' button, the corresponding comments should get saved for the picture.
The 'SELECT IMAGE' opens up a ModalDialogBox which enables the user to select the image. When closed, it causes a postback, and rebinds the gridview to display the image the user just selected. Therefore, I need the GridView to rebind on postback, or a way around this.
The delete imagebutton (in gridview) should delete the image and comments from the database.
Thanks again!
try this structure...
aspx page: (note textarea has runat="server")
<body>
<form runat="server">
<asp:ScriptManager runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowCommand="GridView1_RowCommand"
EnableViewState="true" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Delete" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button runat="server" ID="Delete" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Comment" ItemStyle-Width="175px">
<ItemTemplate>
<textarea runat="server" class="raTextBox" id="txtItemComment" rows="4" cols="30"></textarea></ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindGrid();
}
}
protected void BindGrid()
{
var items = new List<string>();
for (int i = 0; i < 10; i++)
{
items.Add(i + ";comment" + i.ToString());
}
GridView1.DataSource = items;
GridView1.DataBind();
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "DeleteRow")
{
var idx = Convert.ToInt32(e.CommandArgument);
var cmt = GridView1.Rows[idx].FindControl("txtItemComment") as System.Web.UI.HtmlControls.HtmlTextArea;
cmt.Value = DateTime.Now.ToString();
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var item = e.Row.DataItem.ToString().Split(";".ToCharArray());
var del = e.Row.FindControl("Delete") as Button;
del.CommandName = "DeleteRow";
del.CommandArgument = item[0];
var cmt = e.Row.FindControl("txtItemComment") as System.Web.UI.HtmlControls.HtmlTextArea;
cmt.Value = item[1];
}
}

how to retrieve "TextBox1" in gridview and indicate a value to it when aspx is load

Basically I want tO retrieve a "TextBox1" which I add in to one of the new column (TemplateField) of the gridview and the rest of the column are data load from the sqldatasource control
i will want to indicate the "TextBox1" basic value that i calculated...so the result is when the default.aspx is loaded (which mean page load) the "TextBox1" should have show the calculated value...sO now is how am I going to retrieve that " TextBox1" from the gridview in order for me to indicate a value
cause i dont need to use this code below as my gridview data is use the retrieve in sqldatasource in the design default.aspx
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Age");
DataRow dr = dt.NewRow();
dr["Name"] = "Chris Harris";
dr["Age"] = "40";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Sean Williams";
dr["Age"] = "39";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Paul Newcombe";
dr["Age"] = "38";
dt.Rows.Add(dr);
GridView1.DataSource = dt;
GridView1.DataBind();
SO how should do to retrieve that " TextBox1" from the gridview in order for me to indicate a value
<ItemTemplate>
<table style="width: 73%; height: 31px;">
<tr>
<td class="style1">
<asp:Label ID="Label2" runat="server" Text="Calculation:"></asp:Label>
</td>
<td >
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</td>
</tr>
</table>
</ItemTemplate>
If this a row-by-row situation, you will probably want to do this in the RowDataBound event on the GridView:
public void gridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
Textbox txt = (TextBox)e.Row.FindControl("Textbox1");
//Do your processing here...
}
}
you need to find control inside the gridview container in RowDatabound event . Gridview class and methods
TextBox t = GridView1.FindControl("TextBox1") as TextBox;
if (t != null)
{
t.Text = "Hello World!";
}

ASP.NET: dynamically adding a matrix of images to each row of a Gridview

I'd like to dynamically add a matrix of images to each row of a GridView. Suppose I wanted a 5 x 5 matrix of the same image per row, and the path is:
public static string PASS = "./Images/pass.png";
Also suppose that it's a Gridview within a Gridview (I'm not sure if the inner Gridview is the right control to use):
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<asp:ItemTemplate>
<asp:GridView ID="GridView2" runat="server">
</asp:GridView>
</asp:ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
How can I dynamically add each matrix to each row?
EDIT:
Ok, here's a first attempt using Steve's answer, and loosely following http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.datalist.items.aspx as a model. I'm confused about how to dynamically add a DataList inside a GridView, as well as how (and when) to do the data binding.
protected void Page_Load(object sender, EventArgs e)
{
DataTable table = new DataTable();
table.Columns.Add("DataList", typeof(DataList));
for (int i = 0; i < 4; i++)
{
DataRow dr = table.NewRow();
DataList1.DataSource = CreateDataSource();
DataList1.DataBind();
table.Rows.Add(dr);
}
GridView1.DataSource = table;
GridView1.DataBind();
}
ICollection CreateDataSource()
{
string imageLocation = "./Images/311.jpg";
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("ImageURL", typeof(string)));
for (int i = 0; i < 25; i++)
{
dr = dt.NewRow();
dr[0] = imageLocation;
dt.Rows.Add(dr);
}
DataView dv = new DataView(dt);
return dv;
}
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:DataList ID="DataList1" RepeatColumns="5" runat="server">
<ItemTemplate>
<img src="<%# DataBinder.Eval(Container.DataItem, "ImageURL") %> />
</ItemTemplate>
</asp:DataList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
The particular exception I get is:
The data source for GridView with id 'GridView1' did not have any properties or attributes from which to generate columns. Ensure that your data source has content.
Where am I going wrong?
How about using a datalist instead? Create a generic collection list of string, add 25 "./Images/pass.png" and bind it to the datalist.
In the item template, you have this:
Edit (changed eval to container)
<asp:DataList ID="DataList1" RepeatColumns="5" runat="server">
<ItemTemplate>
<img src="<%# Container.DataItem %>" />
</ItemTemplate>
</asp:DataList>
There's probably a faster way to get 25 instances of the string into the collection or better way to represent it, but I can't think of one now.
Protected void Page_Load(object sender, EventArgs e)
{
DataTable table = new DataTable();
table.Columns.Add("DataList", typeof(DataList));
DataRow dr = table.NewRow();
table.Rows.Add(dr);
GridView1.DataSource = table;
GridView1.DataBind();
}
ICollection CreateDataSource()
{
string imageLocation = "~/text.jpg";
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("ImageURL", typeof(string)));
for (int i = 0; i < 25; i++)
{
dr = dt.NewRow();
dr[0] = imageLocation;
dt.Rows.Add(dr);
}
DataView dv = new DataView(dt);
return dv;
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataList dataList1 = e.Row.FindControl("DataList1") as DataList;
dataList1.DataSource = CreateDataSource();
dataList1.DataBind();
}
}
<asp:GridView ID="GridView1" runat="server"
onrowdatabound="GridView1_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:DataList ID="DataList1" RepeatColumns="5" runat="server">
<ItemTemplate>
<asp:Image ID="img" runat="server"
ImageUrl='<%# DataBinder.Eval
(Container.DataItem, "ImageURL") %>' />
</ItemTemplate>
</asp:DataList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Does it have to be a gridview. Why can't it be an asp:table?

Resources