I need some help getting my code to work. DataGridView is proving much more complex that I had anticipated. I need someone to please show me how to fix my code, so that both the DataGridView control can be updated and my DataGridViewComboBoxColumn dropdown and DataGridViewCheckBoxColumn controls all work. I'm okay with any strategy, provided the solution you offer is somewhat elegant and complete. I've already spent far too much time trying to figure this out on my own. Any thoughts or suggestions would be greatly appreciated.
Here is a simplifcation of what my backend looks like:
MySqlDataAdapter dataAdapter = new MySqlDataAdapter(sqlRequestString, this.dbConnection);
MySqlCommandBuilder commandBuilder = new MySqlCommandBuilder(dataAdapter);
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
dataAdapter.Fill(table);
bindingSource.DataSource = table;
If I get rid of the BindingSource, how do I connect the DataTable directly to the DataGridView, so that the ComboBox and Checkbox columns are properly populated?
UPDATE
This should be a complete overview of how I am attempting to initialize my DataGridView:
private void InitializeComponent()
{
/* ... */
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.DataGridViewColumn_Section,
this.DataGridViewColumn_Indent,
this.DataGridViewColumn_Content,
this.DataGridViewColumn_Summary,
this.DataGridViewColumn_Role,
this.DataGridViewColumn_Author,
this.DataGridViewColumn_Updated});
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.DataSourceChanged += new System.EventHandler(this.dataGridView1_DataSourceChanged);
this.dataGridView1.CellEnter += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellEnter);
this.dataGridView1.CellLeave += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellLeave);
this.dataGridView1.ColumnAdded += new System.Windows.Forms.DataGridViewColumnEventHandler(this.dataGridView1_ColumnAdded);
this.dataGridView1.SelectionChanged += new System.EventHandler(this.dataGridView1_SelectionChanged);
this.dataGridView1.Leave += new System.EventHandler(this.dataGridView1_Leave);
//
// DataGridViewColumn_Section
//
this.DataGridViewColumn_Section.HeaderText = "Section";
this.DataGridViewColumn_Section.Name = "DataGridViewColumn_Section";
//
// DataGridViewColumn_Indent
//
this.DataGridViewColumn_Indent.HeaderText = "Indent";
this.DataGridViewColumn_Indent.Name = "DataGridViewColumn_Indent";
//
// DataGridViewColumn_Content
//
this.DataGridViewColumn_Content.HeaderText = "Content";
this.DataGridViewColumn_Content.MinimumWidth = 100;
this.DataGridViewColumn_Content.Name = "DataGridViewColumn_Content";
//
// DataGridViewColumn_Summary
//
this.DataGridViewColumn_Summary.HeaderText = "Summary";
this.DataGridViewColumn_Summary.Name = "DataGridViewColumn_Summary";
//
// DataGridViewColumn_Role
//
this.DataGridViewColumn_Role.HeaderText = "Minimum Signoff";
this.DataGridViewColumn_Role.Name = "DataGridViewColumn_Role";
//
// DataGridViewColumn_Author
//
this.DataGridViewColumn_Author.HeaderText = "Author";
this.DataGridViewColumn_Author.Name = "DataGridViewColumn_Author";
this.DataGridViewColumn_Author.ReadOnly = true;
//
// DataGridViewColumn_Updated
//
this.DataGridViewColumn_Updated.HeaderText = "Updated";
this.DataGridViewColumn_Updated.Name = "DataGridViewColumn_Updated";
this.DataGridViewColumn_Updated.ReadOnly = true;
/* ... */
}
public MyWinform()
{
InitializeComponent();
// Initialize DataGridView DataTable
this.dgvDataTable = new DataTable();
// Initialize DataGridView column indexes
this.idxSection = dataGridView1.Columns["DataGridViewColumn_Section"].Index;
this.idxIndent = dataGridView1.Columns["DataGridViewColumn_Indent"].Index;
this.idxContent = dataGridView1.Columns["DataGridViewColumn_Content"].Index;
this.idxSummary = dataGridView1.Columns["DataGridViewColumn_Summary"].Index;
this.idxRole = dataGridView1.Columns["DataGridViewColumn_Role"].Index;
this.idxAuthor = dataGridView1.Columns["DataGridViewColumn_Author"].Index;
this.idxLastUpdate = dataGridView1.Columns["DataGridViewColumn_Updated"].Index;
}
private void MyWinform_Load(object sender, EventArgs e)
{
DataGridView dgv = this.dataGridView1;
DataGridViewComboBoxColumn comboCol;
// Load System Menu
SystemMenu.Load(this.Handle);
// Insert selection prompt
ProcTemplateRecord selectProcPrompt = new ProcTemplateRecord();
selectProcPrompt.PrimaryKey = 0;
selectProcPrompt.ProcName = "Select from the list...";
this.procList.Insert(0, selectProcPrompt);
// Add new procedure prompt
ProcTemplateRecord newProcPrompt = new ProcTemplateRecord();
newProcPrompt.PrimaryKey = -1;
newProcPrompt.ProcName = "Start a new Safe Job Procedure";
this.procList.Add(newProcPrompt);
// Finish initializing the ComboBox dropdown list
this.comboBox1.DataSource = this.procList;
this.comboBox1.DisplayMember = "ProcName";
this.comboBox1.ValueMember = "PrimaryKey";
// Finish initializing DataGridView and bind to BindingSource
this.dataGridView1.AutoGenerateColumns = false;
/*
// Finish initializing the DataGridView ComboBox columns...
comboCol = (DataGridViewComboBoxColumn)dgv.Columns[this.idxSection];
comboCol.DataSource = Enum.GetValues(typeof(SectionType));
comboCol.ValueType = typeof(SectionType);
comboCol.DropDownWidth = ComboBoxMaxLabelWidth(comboCol);
comboCol = (DataGridViewComboBoxColumn)dgv.Columns[this.idxRole];
comboCol.DataSource = Enum.GetValues(typeof(RoleType));
comboCol.ValueType = typeof(RoleType);
comboCol.DropDownWidth = ComboBoxMaxLabelWidth(comboCol);
this.dataGridView1.DataSource = this.dgvDataTable;
*/
this.RefreshDataGridViewColumnWidths();
// Setup post-initialization DataGridViewEvent handlers
this.dataGridView1.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellValueChanged);
this.dataGridView1.CurrentCellDirtyStateChanged += new System.EventHandler(this.dataGridView1_CurrentCellDirtyStateChanged);
}
private void dataGridView1_DataSourceChanged(object sender, EventArgs e)
{
this.RefreshDataGridViewColumnWidths();
}
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
this.RefreshButtons();
if (e.ColumnIndex == this.idxSection)
{
this.label_dgvToolTip.Visible = false;
}
else if (e.ColumnIndex == this.idxIndent)
{
this.label_dgvToolTip.Visible = false;
}
else if (e.ColumnIndex == this.idxContent)
{
this.label_dgvToolTip.Visible = false;
}
else if (e.ColumnIndex == this.idxSummary)
{
this.label_dgvToolTip.Visible = false;
}
else if (e.ColumnIndex == this.idxRole)
{
this.label_dgvToolTip.Visible = false;
}
else if (e.ColumnIndex == this.idxAuthor)
{
this.label_dgvToolTip.Visible = false;
this.label_dgvToolTip.Text = "Author column values are read only.";
this.label_dgvToolTip.Visible = true;
}
else if (e.ColumnIndex == this.idxLastUpdate)
{
this.label_dgvToolTip.Visible = false;
this.label_dgvToolTip.Text = "Updated column values are read only.";
this.label_dgvToolTip.Visible = true;
}
else
{
this.label_dgvToolTip.Visible = false;
}
this.idxActiveColumn = e.ColumnIndex;
this.idxActiveRow = e.RowIndex;
}
private void dataGridView1_CellLeave(object sender, DataGridViewCellEventArgs e)
{
this.label_dgvToolTip.Visible = false;
this.RefreshButtons();
}
private void dataGridView1_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
{
DataGridView dgv = this.dataGridView1;
if ((e.Column.DataPropertyName == "PageSection") &&
(e.Column.CellType != typeof(DataGridViewComboBoxCell)))
{
var cbo = GetComboBoxColumn(e.Column);
cbo.DataSource = Enum.GetValues(typeof(SectionType));
cbo.ValueType = typeof(SectionType);
dgv.Columns.Remove(e.Column);
dgv.Columns.Add(cbo);
}
else if ((e.Column.DataPropertyName == "UserRole") &&
(e.Column.CellType != typeof(DataGridViewComboBoxCell)))
{
var cbo = GetComboBoxColumn(e.Column);
cbo.DataSource = Enum.GetValues(typeof(RoleType));
cbo.ValueType = typeof(RoleType);
dgv.Columns.Remove(e.Column);
dgv.Columns.Add(cbo);
}
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
this.RefreshButtons();
}
private void dataGridView1_Leave(object sender, EventArgs e)
{
DataGridView dgv = this.dataGridView1;
if (dgv.SelectedCells.Count == 0)
{
this.idxActiveColumn = -1;
this.idxActiveRow = -1;
}
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
DataGridViewComboBoxCell sectionCell = (DataGridViewComboBoxCell)dgv.Rows[e.RowIndex].Cells[this.idxSection];
DataGridViewTextBoxCell indentCell = (DataGridViewTextBoxCell)dgv.Rows[e.RowIndex].Cells[this.idxIndent];
DataGridViewComboBoxCell roleCell = (DataGridViewComboBoxCell)dgv.Rows[e.RowIndex].Cells[this.idxRole];
Int32 colIndex = e.ColumnIndex;
try
{
if (colIndex == this.idxIndent)
{
int number;
string cellValue = indentCell.Value.ToString();
bool isNumeric = int.TryParse(cellValue, out number);
if (!isNumeric)
{
cellValue = cellValue.Substring(0, cellValue.Length - 1);
indentCell.Value = cellValue;
}
}
// Column resizing code goes last
this.RefreshDataGridViewColumnWidths();
this.dgvIsDirty = true;
}
catch (Exception ex)
{
throw new Exception("Failed to refresh DataGridView on cell change.", ex);
}
}
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
DataGridView dgv = (DataGridView)sender;
try
{
if (dgv.IsCurrentCellDirty)
{
// This fires the cell value changed handler below
dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
this.RefreshDataGridViewColumnWidths();
}
}
catch (Exception ex)
{
throw new Exception("Failed to commit edit of DataGridView cell.", ex);
}
}
This is the code I am using to update my DataGridView contorl:
// Load the data from the database into the DataGridView
this.dbif.GetProcedure(this.procList.ElementAt(selectedIndex).PrimaryKey, ref this.dgvDataTable);
DataRow[] rows = this.dgvDataTable.Select();
//Object dgvDataSource = dgv.DataSource;
//dgv.DataSource = null;
foreach (DataRow dataRow in rows)
{
DataGridViewRow dgvRow = new DataGridViewRow();
dgvRow.CreateCells(dgv);
dgvRow.Cells[idxSection].Value = dataRow.Field<string>(0);
dgvRow.Cells[idxIndent].Value = dataRow.Field<byte>(1);
dgvRow.Cells[idxContent].Value = dataRow.Field<string>(3);
dgvRow.Cells[idxSummary].Value = dataRow.Field<UInt32>(4) != 0;
dgvRow.Cells[idxRole].Value = dataRow.Field<string>(5);
dgvRow.Cells[idxAuthor].Value = dataRow.Field<string>(6) + dataRow.Field<string>(7);
dgvRow.Cells[idxLastUpdate].Value = dataRow.Field<DateTime>(8).ToString();
dgv.Rows.Add(dgvRow);
}
//dgv.DataSource = dgvDataSource;
This is how my enumerations are defined:
public enum SectionType
{
ESJP_SECTION_HEADER = 1, // start with 1 for database compatibility
ESJP_SECTION_FOOTER,
ESJP_SECTION_BODY
}
public enum RoleType
{
ESJP_ROLE_NONE = 1, // start with 1 for database compatibility
ESJP_ROLE_TEST_ENG,
ESJP_ROLE_FEATURE_LEAD,
ESJP_ROLE_TEAM_LEAD
}
There are a number of issues/improvements. There are too many unknowns about the data to fix everything, but some techniques shown here may help.
1. Manually populating the DGV
You ought not have to do that. Just setting the DataTable as the DataSource will work most of the columns.
2. Expressions
You have 2 expressions where you populate the dgv:
dgvRow.Cells[idxSummary].Value = dataRow.Field<UInt32>(4) != 0;
dgvRow.Cells[idxAuthor].Value = dataRow.Field<string>(6) + dataRow.Field<string>(7);
This leads me to believe the dgv is ReadOnly. Otherwise you will have trouble with those. The Summary for instance: if the user Unchecks the column, you can set that value to 0, but what if they check it? How will you know what value to set??
Indent as Byte seems odd too - almost like it is a boolean.
3. Combos
In a previous question, the dgv was populated from a List<Class>. With that as the `DataSource, an Enum works well because the 2 properties were of that Type. With an enum, the following works:
cbo.ValueType = typeof(RoleType);
It's less likely to work with a DataTable as in version 1, 2 or 3 of this question because there is no db/Datatable type of SectionType or RoleType. In other cases where there is a translation - show the user "ESJP_SECTION_HEADER" but store 2 in the DataTable and ultimately the DB - a small NameValue pairs list will work. A different data model means a different approach to the DGV cbo.
It now looks like those are text columns (I've asked 3 times). If so, you really just need to constrain the selection to the enum names. In the IDE, paste in the text for the Items property:
Alternatively, you can do so in code:
private string[] secList = {"ESJP_SECTION_HEADER","ESJP_SECTION_FOOTER",
"ESJP_SECTION_BODY"};
...
((DataGridViewComboBoxColumn)dgv1.Columns["PageSection"]).Items.AddRange(secList);
AutoGenerateColumns
When the DataSource for a DGV is set, by default it will automatically create a DGVcolumn for each DTColumn, and this works well for the most part. Sometimes you'll want some small tweak like hide an Id column, or change a TextColumn to a CBOColumn. Code in the ColumnAddedEvent to make these changes rather than manually laying out columns can work well.
But since there are quite a few such such changes and since you have already layed out columns in the IDE, you want to be sure to set AutoGenerateColumns to false somewhere in code. Otherwise it will add still more columns.
Setup
Things you may or may not have done in the DGV designer:
Add the columns in whatever order you wish, but be sure to assign the DataPropertyName to the name used in the SQL query. Leave it blank for Author.
Expression columns like Author means either changing the query or doing some formatting in the DGV. For this, add First and Last name columns to the DGV as well as the Author column. Make the first two invisible. The code below shows the formatting. (Make sure that the compound column (Author) appears after the parts!).
Normally, I would try to do that in SQL: SELECT (First + Last) AS Author, but if you do not want to mess with that query, you can concat in DGV events.
Be sure to add the names for the Page and Role columns to the Items collection.
Then, the rest is fairly simple:
private DataTable dtF;
...
string SQL = "SELECT PageSection, Indent, Content, SummaryId, "
+ "UserRole, AuthorFirstN, AuthorLastN, LastUpdated FROM FellPage";
using (var dbCon = new MySqlConnection(MySQLConnStr))
using (var cmd = new MySqlCommand(SQL, dbCon))
{
dbCon.Open();
dtF = new DataTable();
dtF.Load(cmd.ExecuteReader());
}
// IMPORTANT!!!
dgv1.AutoGenerateColumns = false;
dgv1.DataSource = dtF;
The formatting event:
private void dgv1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (dgv1.Rows[e.RowIndex].IsNewRow)
return;
if (e.ColumnIndex == 7) // ie "Author"
{
e.Value = dgv1.Rows[e.RowIndex].Cells[6].Value.ToString() + ", " +
dgv1.Rows[e.RowIndex].Cells[5].Value.ToString();
e.FormattingApplied = true;
}
}
Result:
It is very important to turn off AutoGenerateColumns. By default, the dgv will add columns for everything in the source. Since you added them, set that to false in the code (there is no IDE property for it).
By virtue of Summary and Indent being defined as check columns, it translates non zero as true. I have no idea how you will edit any SummaryId value. That should probably be a text column so they can enter a value, if that is allowed (that col could be read only too?).
My query and such arent as complex as yours, and surely there are some details I/we are unaware of which have been omitted. But there is certainly a much less gyrations and code to get it working...whatever this is.
Being bound to a DataTable, when the user edits anything, the changes flow thru to the underlying DataTable (use the various Validating events to check their work). The DataTable in turn tracks the state of each row - new, changed, deleted - so later you can:
var changes = dtF.GetChanges();
This will return all the rows which have been changed since the last AcceptChanges().
I have this situation:
... a normal RadGrid with data. And, if I clic on a row, I want to obtain this:
... a list of label-textbox pair (please pay attention: these list of data are obtained from the row, but are not part of it).
With the first RadGrid it's all okay.
Therefore, I have used a simple HTML Table for the list of pair (in the second image). This list being generated code-behind, from database.
The problem is the update of the TextBoxs: if I edit these textboxes and do clic on the Update Botton, starts the myRadGrid_UpdateCommand method. But I can't find a way to manage these textboxes (they don't appear in myRadGrid.Controls or else).
So I have tried to use another RadGrid inside the first RadGrid, but with no luck... Maybe I have to use another different Telerik control?
Someone know how I can do this?
This is part of my implementation:
protected void myRadGrid_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
{
this.myRadGrid.DataSource = this.dtListaDettagli;
this.dtListaDettagli.PrimaryKey = new DataColumn[] { this.dtListaDettagli.Columns["key"] };
}
protected void myRadGrid_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
if (e.Item is GridEditFormItem && e.Item.IsInEditMode)
{
GridEditFormItem item = (GridEditFormItem)e.Item;
UserControl userControl = (UserControl)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
var listOfDetails = this.Session["listOfDetails"];
//...
var dtoTrav = (List<Detail_Type_N>) listOfDetails;
PopolaUC(dtoTrav, userControl, e.Item.ItemIndex);
}
}
private void PopolaUC<T>(List<T> data, UserControl uc, int index) where T : FlussiBaseDto
{
// ...
RadPane radPane = uc.FindControl("RadPane1") as RadPane;
var properties = TypeDescriptor.GetProperties(typeof(Detail_Type_N));
// ...
var dettaglioSelected = (from x in data
where x.IdFlusso == idFlussoSelected && x.ProgDettaglio == progDettaglioSelected
select x).FirstOrDefault();
HtmlTable htmlTable = new HtmlTable();
htmlTable.ID = "DettaglioSinistro";
var tRow = new HtmlTableRow();
int i = 0;
foreach (PropertyDescriptor prop in properties)
{
i++;
if (i > 3) // organizza la sottotabella in 2 colonne
{
tRow = new HtmlTableRow();
i = 1;
}
// Set label:
HtmlTableCell tLabel = new HtmlTableCell();
var stringInNormalCase = Regex.Replace(prop.Name, "(\\B[A-Z])", " $1");
tLabel.InnerText = stringInNormalCase;
tRow.Cells.Add(tLabel);
// Set TextBox:
HtmlTableCell tCell = new HtmlTableCell();
// ...
TextBox box = new TextBox();
box.Text = Convert.ToString(prop.GetValue(detailSelected));
box.ID = string.Format("my_{0}", prop.Name);
tCell.Controls.Add(box);
tRow.Cells.Add(tCell);
htmlTable.Rows.Add(tRow);
}
radPane.Controls.Add(htmlTable);
}
protected void myRadGrid_UpdateCommand(object source, GridCommandEventArgs e)
{
GridEditableItem editedItem = e.Item as GridEditableItem;
UserControl userControl = (UserControl)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
//Prepare new row to add it in the DataSource
DataRow[] changedRows = this.dtListaDettagli.Select("key = " + editedItem.OwnerTableView.DataKeyValues[editedItem.ItemIndex]["key"]);
// ... and then?
catch (Exception ex)
{
changedRows[0].CancelEdit();
Label lblError = new Label();
lblError.Text = string.Format("Errore nell'aggiornamento movimento. Errore: {0} ", ex.Message);
lblError.ForeColor = System.Drawing.Color.Red;
RadGridIpa.Controls.Add(lblError);
e.Canceled = true;
}
}
You cannot generate TextBoxes and Labels dynamically.
Instead, you want to use Edit Form.
For example,
<telerik:RadGrid ID="RadGrid1" ...>
<MasterTableView>
...
<EditFormSettings>
Place those textboxes and lables here.
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
I have a requirement where i need to add column names and rowdatabound values dynamically .I has managed to get Column names dynamically .According to my need i want values to be displayed in the form of checkboxes in the rows of the grid either in checked form or unchecked based on condition but here every thing is coming in unchecked formate ..
I am using .net membership Role table...
Here is my code for gridview Dynamic column allocation..
protected void BindGridviewData()
{
var role = from MembershipUser u in Membership.GetAllUsers()
select new
{
User = u.UserName,
Role = string.Join(",", Roles.GetRolesForUser(u.UserName))
};
DataTable dTable = new DataTable();
string[] rolesarr = Roles.GetAllRoles();
// add column for user name
dTable.Columns.Add("Username", typeof(string));
// then add all the roles as columns
Array.ForEach(rolesarr, r => dTable.Columns.Add(r));
List<string> tempfield = new List<string>();
foreach (DataColumn column in dTable.Columns)
{
string ColName = column.ColumnName;
tempfield.Add(ColName);
}
for (int i = 0; i < tempfield.Count; i++)
{
string tempfieldname = tempfield[i];
TemplateField temp = new TemplateField();
if (i == 0)
{
temp.HeaderText = tempfieldname;
tempfieldname = string.Empty;
}
else {
temp.ItemTemplate = new MyTemplate();
temp.HeaderText = tempfieldname;
tempfieldname = string.Empty;
}
GridView1.Columns.Add(temp);
}
Now Here i am checking values to be checked or uncked..
foreach (MembershipUser u in Membership.GetAllUsers())
{
DataRow dRow = dTable.NewRow();
dRow[0] = u.UserName;
string[] roles = Roles.GetRolesForUser(u.UserName);
dRow[1] = roles.Contains("Admin") ? true : false;
dRow[2] = roles.Contains("DPAO User") ? true : false;
dRow[3] = roles.Contains("GeneralUser") ? true : false;
dTable.Rows.Add(dRow);
}
GridView1.DataSource = dTable;
GridView1.DataBind();
}
Upto here values are coming fine in dTable but once flow goes to rowdatabound event
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
}
On rowdatabound event flow automatically moves to custom control class which is ...
public class MyTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
CheckBox chk = new CheckBox();
chk.ID = "chk";
container.Controls.Add(chk);
}
}
And from here all checkboxes are displaying as unchecked ...
Please guys help me ..
Thanks in advance...
Do it in this way. check where the column is true false in the rowDatabound event and the add control here only.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox cb = new CheckBox();
if(e.Row.Cells["Column Name"].toString == true ){
cb.Checked = true;
}else{
cb.Checked = false;
}
e.Row.Cells["Column Name"].Controls.Add(cb);
}
}
Hello fellow programmers,
Right now I have a webpage which displays a data-table via grid-view. This works fine. I also inserted a column of check-boxes in the beginning of the view. This works fine as well. But when I try to retrieve info from cells from the row whose respective check-box is selected, I get an empty string.
Below are the parts of my code pertinent to this problem:
.aspx:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
return;
}
else
{
}
//server connections and whatnot//
OleDbCommand c0 = new OleDbCommand(sql0, myConnection);
myAdapter.SelectCommand = c0;
DataSet ds0 = new DataSet("Contacts");
myAdapter.Fill(ds0);
DataTable dt0 = new DataTable();
dt0 = ds0.Tables["Contacts"];
DataView view = new DataView();
view.Table = dt0;
GV0.DataSource = view;
GV0.DataBind();
myConnection.Close();
}
.cs:
/**
* WHY U NO WORK?!
*/
public void Dedupe(Object o, EventArgs e)
{
String output = "start ";
foreach (GridViewRow row in GV0.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("CheckBox1");
if (cb.Checked == true)
{
output += row.Cells[1];
}
}
Label1.Text = output;
}
Any help would be greatly appreciated.
Cheers
Just a thought but in your foreach loop you may need to check the RowType property of the current row that you are looping over and make sure that it is set to DataRow. Or you could use a LINQ statement to bring back only rows with a RowType == DataRow and loop over that.
UPDATE Here is a quick sample of what I meant. But in reviewing your code it does not appear that you have any text in the second cell of your gridview, in fact your gridview only has one cell based on the code you provided.
public void Dedupe(Object o, EventArgs e)
{
String output = "start ";
IEnumerable<GridViewRow> rows = from r in GV0.Rows
where r.RowType == DataControlRowType.DataRow
select r;
foreach (GridViewRow row in rows)
{
CheckBox cb = (CheckBox)row.FindControl("CheckBox1");
if (cb.Checked)
{
output += row.Cells[1];
}
}
Label1.Text = output;
}
I am working on Add To Cart Functionality, and I have added a GridView control with paging enabled. In the GridView, I show the quantity in a text box and handle the OnTextChanged event for that textbox. Now the problem, is how can I keep the changed quantity text in session or view state, and in which row, so that I can update my GridView and bind that data again to the GridView?
Here I took GridView with id gvMaster.
protected void txtQuantity_TextChanged(object sender, EventArgs e)
{
gvMaster.DataSource = ProductDetailsGridMaster();
gvMaster.AllowPaging = true;
gvMaster.DataBind();
}
public DataTable ProductDetailsGridMaster()
{
DataTable dtProducts = new DataTable();
dtProducts.Columns.Add("ProductId");
dtProducts.Columns.Add("ProductName");
dtProducts.Columns.Add("ProductPrice");
dtProducts.Columns.Add("Quantity");
dtProducts.Columns.Add("Price");
gvMaster.AllowPaging = false;
if (Session["dtProducts"] != null)
{
GridView gv = new GridView();
gv.DataSource = Session["dtProducts"];
gvMaster.DataSource = gv.DataSource;
gvMaster.DataBind();
lblMessage.Text = "";
}
//GridView gvc = (GridView)Page.FindControl("gvMaster");
for (int i = 0; i < gvMaster.Rows.Count; i++)
{
Label lblProductId = (Label)gvMaster.Rows[i].Cells[0].FindControl("lblProductId");
Label lblProductName = (Label)gvMaster.Rows[i].Cells[1].FindControl("lblProductName");
Label lblProductPrice = (Label)gvMaster.Rows[i].Cells[2].FindControl("lblProductPrice");
//Label lblssno = (Label)gv.Rows[i].Cells[2].FindControl("lblSSNo");
TextBox txtQuantity = (TextBox)gvMaster.Rows[i].Cells[3].FindControl("txtQuantity");
//TextBox mastertxtQuantity = (TextBox)gvMaster.Rows[i].Cells[3].FindControl("txtQuantity");
Label lblPrice = (Label)gvMaster.Rows[i].Cells[4].FindControl("lblPrice");
var Price = decimal.Parse(lblProductPrice.Text) * decimal.Parse(txtQuantity.Text);
lblPrice.Text = Price.ToString();
DataRow dr = dtProducts.NewRow();
dr["ProductId"] = lblProductId.Text;
dr["ProductName"] = lblProductName.Text;
dr["ProductPrice"] = lblProductPrice.Text;
dr["Quantity"] = txtQuantity.Text;
dr["Price"] = lblPrice.Text;
dtProducts.Rows.Add(dr);
}
Session["dtProducts"] = dtProducts;
return dtProducts;
}
I want to show changed quantity value in grid with paging enabled.
I can hardly understand what your code really does. However, such information like the state of a control shouldn't be kept in Session. Use ViewState instead.
Add C# Asp.net tags to your question.
Also look up n-tier programming/mvc with asp.net , it will help you improve your code many folds