I need to retrieve the email address from my grid, so any one can help me to retrieve the email value alone from grid..
CODE
<asp:BoundField ItemStyle-Width="150px" DataField="Email" HeaderText="Email">
<HeaderStyle HorizontalAlign="Left" />
</asp:BoundField>
Check this snippet please.
string[] emails="";
for (int i=0; i<Gridview.Rows.Count;i++)
{
emails[i] = Gridview.Rows[i].Cells[2].Text;
}
Your emails array contains all the e-mails of your Gridview rows.
If you want a specific email there is another approach, like this:
If the command of the linkbutton is UPDATE then the following will suffice:
protected void GridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
string email = GridView.Rows[e.RowIndex].Cells[2].Text;
}
You can add this in generic list
List<string> email = new List<string>();
for (int i=0; i<Gridview.Rows.Count;i++)
{
email.Add(Gridview.Rows[i].Cells[2].Text);
}
Related
My scenario is that i am creating a data table dynamically and adding the latter to a data set and displaying it in a grid view. I want to add a button "Add to chart" at the end of each row which will have additional functionality.
My code for creating the dynamic data table :
try
{
response = client.query(a);
///List of fields
var fields = response.#return.fields;
//loop through each column
foreach (String column in fields)
{
dtservice.Columns.Add(column);
}
///List of value return as list of object
var values = response.#return.values.ToList();
///get the first object from the list of object
foreach (object item in values)
{
if (item == null) continue;
foreach (PropertyInfo property in item.GetType().GetProperties())
{
// do something with the property
List<string> valueList = (List<string>)(property.GetValue(item, null));
dtservice.Rows.Add(valueList.ToArray());
}
}
}
catch (Exception error)
{
var b = error.ToString();
}
//create dataset
DataSet test= new DataSet();
test.Tables.Add(dtservice);
return test;
}
I have tried using the below code but the button dissapear on click.
protected void WorkList_RowDataBound(object sender, GridViewRowEventArgs e)
{
// CHECK IF ROW IS NOT IN EDIT MODE
if (e.Row.RowType == DataControlRowType.DataRow)
{
// CREATE A Button
Button btn = new Button();
btn.ID = "btnEstados";
btn.Text = "Estados";
// ADD BUTTON TO EACH ROW IN 2ND COLUMN
e.Row.Cells[7].Controls.Add(btn);
}
}
second problem now i was able to get the button on each row, but using the code below,i get the count of column equal to 1. It is actually reading only the static column added in the html and not the one generated dynamically.
//adding column to datatable
for (int row = 0; row < test.Columns.Count - 1; row++)
{
ServiceName.Columns.Add(test.HeaderRow.Cells[row].Text, typeof(string));
}
This is the other way on how to add button in Gridview.
<asp:GridView ID="WorkList" runat="server" Width="100%" AutoGenerateColumns="false" AllowPaging="false" AllowSorting="false"
EmptyDataText="No Record Found"
OnRowCreated="WorkList_RowCreated"
OnRowCommand="WorkList_RowCommand"
OnRowCancelingEdit="WorkList_RowCancelingEdit"
OnRowEditing="WorkList_RowEditing">
<AlternatingRowStyle CssClass="alt" BackColor="#CCFF99"></AlternatingRowStyle>
<Columns>
<asp:ButtonField ButtonType="Button" CommandName="Estados" HeaderText="" ShowHeader="True" Text="Estados" ItemStyle-Width="30px" />
</Columns>
<HeaderStyle BackColor="#808080" ForeColor="#48D1CC" />
</asp:GridView>
In WorkList_RowCommand:
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow gvRow = WorkList.Rows[index];
WorkList.Rows[index];
if (e.CommandName == "Estados")
{
//your code here like `gvRow.Cells[0].Text`
}
Make sure the property declared of your WorkList is exists in your code behind.
Hope it helps.
I have a grid view on my page and I want to allow the user to add / remove items to it. How it works, and the add functionality does work albeit probably not great, is that a user selects a product from a drop down list, then clicks Add.
This creates a new row in grid with the select Product text and ID. The GridView markup is:
<asp:GridView runat="server" ID="grdSelectedProducts" BorderWidth="1px" CellPadding="3" CellSpacing="2" AutoGenerateColumns="False" OnRowDataBound="grdSelectedProducts_OnRowDataBound" ShowHeaderWhenEmpty="True" DataKeyNames="ProductId"
OnRowCommand="grdSelectedProducts_RowCommand" OnRowDeleted="grdSelectedProducts_RowDeleted" OnRowDeleting="grdSelectedProducts_RowDeleting">
<Columns>
<asp:BoundField DataField="Product" HeaderText="Product" ReadOnly="False" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="linkDelete" runat="server" CommandName="Delete" CommandArgument="<%# Container.DataItemIndex %>">Remove</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ProductId" HeaderText="ProductId" ReadOnly="False" Visible="False" />
</Columns>
</asp:GridView>
The data in the grid is bound but there is no connection to a database, as it's just the information from the drop down.
The linkDelete is where I want to allow the user to remove an item, so my question is, how can I actually delete the row? I've got the RowCommand event up which I've tried to remove it, but it just doesn't seem to work correctly as the table either 1) gets rebound with the same data as before or 2) all rows are removed due to the binding of a new DataTable. I'm missing something obvious, but this type of grid is new to me.
Any example I've seen here or on Google has been around gridviews which are databound from SQL, or some other database, which seems to make the rebinding easier. However my version doesn't use that so binding again doesn't seem to work correctly.
protected void grdSelectedProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
grdSelectedProducts.DeleteRow(rowIndex);
CountryDataTable = (DataTable)grdSelectedProducts.DataSource;
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}
}
private DataTable CreateDataTable(bool isAddingValue, string selectedProduct, string selectedId)
{
// if isAddingValue is FALSE then it isn't from a button click to add a Product, it is just
// a call to create the datatable
DataTable dataTable = ProductDataTable;
if (!dataTable.Columns.Contains("Product"))
{
dataTable.Columns.Add("Product");
dataTable.Columns.Add("ProductId");
}
if (isAddingValue)
{
// Get the data from ViewState
DataRow dataRow;
dataRow = dataTable.NewRow();
dataRow["Product"] = selectedProduct;
dataRow["ProductId"] = selectedId;
dataTable.Rows.Add(dataRow);
}
else
{
grdSelectedProducts.DataSource = null;
grdSelectedProducts.DataSource = ProductDataTable;
grdSelectedProducts.DataBind();
}
// Save the data back to ViewState
ProductDataTable = dataTable;
return dataTable;
}
private DataTable ProductDataTable
{
get {return ViewState["ProductDataTable"] as DataTable ?? new DataTable(); }
set { ViewState["ProductDataTable"] = value; }
}
I do have the RowDeleting & RowDeleted events but I don't have any code in it.
First thing you should note is you are deleting the row from grid not from the data table
Then you again bind the data table which may not give you any change, What you should do is instead of deleting from grid delete it from datatable
Rewrite it like
if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
table.Rows.RemoveAt(rowIndex)
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}
If you need it to remove it from DB , DOnt forget to do that , And also note that the above code each time when u fetch the table it will give u everything from DB
so you can make it global , or you can just remove from DB
try this code
if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
grdSelectedProducts.DeleteRow(rowIndex);
SqlCommand cmd = new SqlCommand ("Delete from table where id='"+ rowIndex )+"'",ConnectionObject);
cmd.ExecutenonQuery();
CountryDataTable = (DataTable)grdSelectedProducts.DataSource;
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}
I have the following GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SysInvoiceID" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="SysInvoiceID" HeaderText="SysInvoiceID" ReadOnly="True" SortExpression="SysInvoiceID" />
<asp:BoundField DataField="BillMonth" HeaderText="BillMonth" SortExpression="BillMonth" />
<asp:BoundField DataField="InvoiceDate" HeaderText="InvoiceDate" ReadOnly="True" SortExpression="InvoiceDate" />
<asp:BoundField DataField="InvoiceNumber" HeaderText="InvoiceNumber" SortExpression="InvoiceNumber" />
<asp:BoundField DataField="Net" HeaderText="Net" SortExpression="Net" />
<asp:BoundField DataField="VAT" HeaderText="VAT" SortExpression="VAT" />
<asp:BoundField DataField="Gross" HeaderText="Gross" SortExpression="Gross" />
<asp:ButtonField CommandName="ViewInvoice" HeaderText=" " ShowHeader="True" Text="View" />
</Columns>
</asp:GridView>
Here is the code behind the page:
public partial class PagingTest01 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
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 == "ViewInvoice")
{
// Convert the row index stored in the CommandArgument
// property to an Integer.
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button clicked
// by the user from the Rows collection.
GridViewRow row = GridView1.Rows[index];
// Now you have access to the gridviewrow.
ViewButton_Click(row);
}
}
protected void ViewButton_Click(GridViewRow row)
{
byte[] FileImage = GetImageData(0,row);
if (FileImage != null)
{
base.Response.Clear();
base.Response.Buffer = true;
base.Response.ContentType = "Application/x-pdf";
base.Response.ContentEncoding = Encoding.Default;
string attachment = string.Format("attachment;filename=\"Invoice_{0}.pdf\"", "Customer1");
base.Response.AddHeader("content-disposition", attachment);
base.Response.BinaryWrite(FileImage);
base.Response.Flush();
base.Response.Close();
base.Response.End();
}
}
public byte[] GetImageData(int sysInvoiceID, GridViewRow row)
{
string strUserID = CommonCode.GetCurrentUserID().ToString();
string strCustomerID = CommonCode.GetCurrentCustomerID().ToString();
byte[] numArray;
string strConnectionString = "Data Source=TESTSERV;Initial Catalog=DB_Invoices;Persist Security Info=True";
SqlConnection connection = new SqlConnection(strConnectionString);
SqlCommand command = new SqlCommand("select FileImage from DB_Invoices.dbo.Bills WHERE (FileType = 'PDF' AND SysInvoiceID = #ID)", connection);
command.Parameters.AddWithValue("#ID", GridView1.Rows[row].Cells[0].Text);
SqlDataAdapter da = new SqlDataAdapter(command);
DataSet ds = new DataSet();
try
{
connection.Open();
da.Fill(ds);
DataRow item = ds.Tables[0].Rows[0];
byte[] item1 = (byte[])item["FileImage"];
ds.Tables.Clear();
numArray = item1;
}
catch (Exception ex)
{
throw ex;
}
finally
{
connection.Close();
}
return numArray;
}
}
So basically I have a GridView with a lot of rows, each one with a 'View' Buttonfield next to it. When 'View' is clicked, I attempted to make use of GridView1_RowCommand which should hopefully grab the row clicked before passing it onto ViewButton_Click. This will then call GetImageData and pass the row number onto this line:
command.Parameters.AddWithValue("#ID", GridView1.Rows[row].Cells[0].Text);
Cell 0 is the SysInvoiceID column, so if the correct row is passed, #ID will be assigned a SysInvoiceID.
'Row' however doesn't seem to be a valid argument, though I can't think why not... Unless I have to explicitly convert it into a int? Any help would be really appreciated! Thanks.
I have just commented this as side-note but maybe it's your issue because you mention that "it doesn't seem to be a valid argument, though I can't think why not... Unless I have to explicitly convert it into a int".
If ID is an int you should use int.Parse(celltext), othwerwise the database gets the wrong type since AddWithValue needs to infer the type from the value.
So use:
command.Parameters.AddWithValue("#ID", int.Parse(GridView1.Rows[row].Cells[0].Text));
Apart from that, you haven't added the event handler GridView1_RowCommand.
<asp:GridView ID="GridView1" OnRowCommand="GridView1_RowCommand" runat="server" AutoGenerateColumns="False" DataKeyNames="SysInvoiceID" DataSourceID="SqlDataSource1">
....
and you are also not setting the CommandArgument to the index of the row. I would use a different approach anyway if you need the row-index. Use a templatefield and a control, for example a Button. Then use it's NamingContainer property to get the reference to the 'GridViewRow`, here is an example: Get Row Index on Asp.net Rowcommand event
use this:
int index = ((GridViewRow)((WebControl)sender)).RowIndex;
in place of
int index = Convert.ToInt32(e.CommandArgument);
I have a Gridview with these parameters:
<asp:GridView runat="server" ID="ItemGrid" CssClass="Grid"
AutoGenerateColumns="false"
AutoGenerateDeleteButton="true" OnRowDeleting="RowDeleting"
AutoGenerateEditButton="true" onRowEditing="RowEdit"
OnRowCancelingEdit="CancelRowEdit" onRowUpdating="RowUpdating"
DataKeyNames="Item_ID">
<Columns>
<asp:BoundField HeaderText="Item" DataField="Item"/>
<asp:BoundField HeaderText="Family" DataField="Family"/>
<asp:BoundField HeaderText="Structure" DataField="Structure"/>
<asp:BoundField HeaderText="Updated" ReadOnly="true" DataFormatString="{0:d}" DataField="Updated"/>
</Columns>
</asp:GridView>
On updating it calls:
protected void RowUpdating(object sender, GridViewUpdateEventArgs e){
int Item_ID = (int)this.ItemGrid.DataKeys[e.RowIndex][0];
//Problem is something right here:
string Item = ((TextBox)ItemGrid.Rows[e.RowIndex].Cells[1].Controls[0]).Text;
string Family = ((TextBox)ItemGrid.Rows[e.RowIndex].Cells[2].Controls[0]).Text;
string Structure = ((TextBox)ItemGrid.Rows[e.RowIndex].Cells[3].Controls[0]).Text;
ItemTableAdapter taItem = new ItemTableAdapter();
taItem.UpdateItem(Item, Family, Structure, DateTime.Now, Item_ID);
//just a <asp:Label> for seeing some output.
Alert.Text= string.Format("Item:{0}Family:{1}Structure:{2}",Item,Family,Structure);
this.ItemGrid.EditIndex = -1;
dataBind();
}
It generates the Update/Edit/Delete buttons, my Delete function is working exactly how I want and the 'Edit' button generates editable TextBoxes as it should.
My problem is in the updating part, the strings Item, Family, Structure are getting the old values, not the new values I put in the generated text boxes.
If I hard code in values they are updated to the database and the DateTime.Now is always updating correctly in the database so the update query is working.
I've been looking at this/reading forums testing things for a couple days now. I'm sure I'm just missing something simple that I have overlooked.
Thanks for any help.
Edit:
It has been answered but for those who were curious this is my dataBind();
protected void dataBind()
{
ItemTableAdapter taItem = new ItemTableAdapter();
this.ItemGrid.DataSource = taItem.GetActive();
this.ItemGrid.DataBind();
}
Are you re-binding your GridView on postback by mistake? You should only fetch the data from the database on initial load:
if (!IsPostBack)
{
Gridview1.Datasource = BLL.SomeClass.Load(SomeRecordId);
GridView1.DataBind();
}
RowUpdating and RowUpdated fire at different times. See if that isn't your problem.
Try using the following method to get your new values:
//string Item = ((TextBox)ItemGrid.Rows[e.RowIndex].Cells[1].Controls[0]).Text;
//string Family = ((TextBox)ItemGrid.Rows[e.RowIndex].Cells[2].Controls[0]).Text;
//string Structure = ((TextBox)ItemGrid.Rows[e.RowIndex].Cells[3].Controls[0]).Text;
string Item = e.NewValues["Item"].ToString();
string Family = e.NewValues["Family"].ToString();
string Structure = e.NewValues["Structure"].ToString();
In a DataGrid, when text in a textbox changes I want to add the value of another field in that row to an array.
public void txtTitle_TextChanged(object sender, EventArgs e)
{
TextBox titleBox = (TextBox)sender;
DataGridItem myItem = (DataGridItem)titleBox.Parent.Parent;
string test = DataBinder.Eval(myItem.DataItem, "prod_id").ToString();
}
However myItem.DataItem evaluates as null. I was expecting it to evaluate as DataRowView?
You can get the TextChanged event to fire if you do the following:
<asp:DataGrid ID="DataGrid1" runat="server" AutoGenerateColumns="False"
onitemdatabound="DataGrid1_ItemDataBound">
<Columns>
<asp:TemplateColumn HeaderText="Test">
<ItemTemplate>
<asp:TextBox OnTextChanged="txtBox_TextChanged" ID="TextBox1" runat="server" AutoPostBack="True"></asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="Name" HeaderText="Test 1"></asp:BoundColumn>
</Columns>
</asp:DataGrid>
You will notice that i have the following properties set:
AutoPostBack="True"
I have also manually added the OnTextChanged="txtBox_TextChanged" to the text box as well.
In my code behind i have:
protected void txtBox_TextChanged(object sender, EventArgs e)
{
TextBox txtBox = (TextBox)sender;
Label1.Text = txtBox.Text;
}
The only way the event will fire is when you lose focus on the text box after typing.
Key points to consider:
This will cause a post back, so Ajax might be a good way to keep the user experience nice.
You will need to make sure you wrap your DataBind() in a if (!IsPostBack)
Hope this helps!
Effectively, I solved this by adding an autonumber column to the table, and using the value of this to determine the row's positino in the table, then using the value of this to affect the appropriate row in the datagrid.
I'm now merely changing the color of the row rather than adding values in that row to an array, as stated in the original question.
public void txtPrice_TextChanged(object sender, EventArgs e)
{
TextBox txtPrice = (TextBox)sender;
DataGridItem myItem = (DataGridItem)txtPrice.Parent.Parent;
markRows(myItem, true);
}
public void markRows(DataGridItem myItem, bool toSave)
{
// Prepeare to save this record?
CheckBox thisSave = (CheckBox)myItem.FindControl("chkSave");
thisSave.Checked = toSave;
// Establish the row's position in the table
Label sNo = (Label)myItem.FindControl("SNo");
int rowNum = Convert.ToInt32(sNo.Text) - 1;
CheckBox rowSave = (CheckBox)grid.Items[rowNum].FindControl("chkSave");
// Update background color on the row to remove/add highlight
if (rowSave.Checked == true)
grid.Items[rowNum].BackColor = System.Drawing.Color.GreenYellow;
else
{
Color bgBlue = Color.FromArgb(212, 231, 247);
grid.Items[rowNum].BackColor = bgBlue;
// some code here to refresh data from table?
}
}