iterate through ALL rows in a GridView - asp.net

<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="chkSelected" runat="server" Checked="false"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
elow code works fine but there is a bug :
if Employee object has return 5 rows and i am trying to checked the check box based on the ids but instead its just matching only the last id - it suppose to checked all 5 rows..
List<Employee> result = new List<Employee>();
long Id = (long)Session["Id"];
result = Employee.GetEmployeeById(Id);
foreach (GridViewRow row in gv.Rows)
{
CheckBox chkBox = row.FindControl("chkSelected") as CheckBox;
if (c != null)
{
if (result.Count > 0)
{
foreach (Employee item in result)
{
Label Id = row.FindControl("lblId") as Label;
if (Id.Text == item.Id.ToString())
{
chkBox.Checked = true;
}
else
{
chkBox.Checked = false;
}
}
}

Look at your logic - you only have the one checkbox. You're unchecking and checking the same control in the employee loop. Does each grid row have a checkbox that should be selected based on the condition the id exists in the employee list?
foreach (GridViewRow row in gv.Rows)
{
Label Id = row.FindControl("lblId") as Label;
var result = Employee.GetEmployeeById(Id.Text);
if (result.Count > 0)
{
CheckBox chkBox = row.FindControl("chkSelected") as CheckBox;
if (chkBox != null)
{
chkBox.Checked = result.Any(x => x.Id.ToString() == Id.Text);
}
}
}

Related

Why column count in gridview is 0 when columns are binded dynamically from datatable

I have a gridview which show column count 0 when gridview is directly binded to datasource and columns are not defined statically. I am unable to come up with this problem.
I tried this below code:
foreach (GridViewRow row in gv_services.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
for (int i = 0; i < gv_services.Columns.Count; i++)
{
if (row.Cells[i].Controls[0].GetType() == typeof(CheckBox))
{
CheckBox checkBox = row.Cells[i].Controls[0] as CheckBox;
checkBox.Enabled = true;
// checkBox.CheckedChanged += new EventHandler(chck_CheckedChanged);
}
}
}
}
If i understood correctly you are trying to loop through gridview rows and enable checkbox based on your conditions
try this code
foreach (GridViewRow row in yourgridview.Rows)
{
CheckBox myChk = row.FindControl("myControlName") as CheckBox;
if (myChk != null)
{
myChk.Enabled = true;
}
}

Dynamically dropping grid columns - effect on postbacks

I have read a number of threads here on the subject of posting back data from dynamically added datagrid columns. Everything I've read says that since the columns were added after the Init phase, they are not available in the control collection upon Postback and therefore any data posted back by these dynamically added columns is not available and cannot be restored from ViewState unless they are re-created in Page_Init. I have read that as long as the controls are re-added with identical IDS ( i.e IDS should match match posted back control ids), they will be restored from ViewState.
What if I'm not dynamically adding grid columns but rather dropping some grid columns in the code behind. So the ID's of the columns that remmin should match what was in the control collection to begin with so any data posted back should be resotored right but this is not what I'm seeing. SUppos the following is the list of columns in my ASPX page. If in my code behind I drop the "Test" column but check the checkbox in the first column. Upon postback, the checkbox selection is not maintained. I would have expected it to based on what I've read. Can someone correct my understanding on this?
<Columns>
<asp:TemplateColumn headertext="" headerstyle-width="1%" itemstyle-horizontalalign="center" FooterStyle-CssClass="DataGridFooter" FooterStyle-HorizontalAlign="Center" FooterStyle-VerticalAlign="Top">
<HeaderTemplate>
<input id="checkAll" type="checkbox" onclick="CheckAllDataGridCheckBoxes('checkboxIsSelected',this.checked)"/>
</HeaderTemplate>
<itemtemplate>
<asp:CheckBox runat="server" id="checkboxIsSelected" checked='false' />
</itemtemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Subject" HeaderStyle-Width="10%" Visible="TRUE" ItemStyle-HorizontalAlign="Center" FooterStyle-CssClass="DataGridFooter" FooterStyle-HorizontalAlign="Center" FooterStyle-VerticalAlign="Top" >
<ItemTemplate>
<asp:Label id="labelSubjectID" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "SubjectID") %>' />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Test" HeaderStyle-Width="5%" Visible="TRUE" ItemStyle-HorizontalAlign="Center" FooterStyle-CssClass="DataGridFooter" FooterStyle-HorizontalAlign="Center" FooterStyle-VerticalAlign="Top" >
<ItemTemplate>
<asp:Label id="labelTestCode" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "TestCode") %>' />
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
Added BindGrid() and the event handler buttonApprove_click. The method SetGridColumns is the one that drops grid columns. Have included that too.
private void BindGrid()
{
try
{
SetMasterDetailControlStates(IsPageInDetailsMode());
if (!ValidateArgs())
{
gridBias.Visible = false;
return;
}
foreach (ListItem displayOption in chkboxDisplay.Items)
{
if (displayOption.Selected)
{
if (displayOption.Value == "Highlight") { _showHighlighting = true; }
}
}
/*
<Snipped>...Make procedure call to get dataset
*/
DataSet ds = sp.GetDataSet();
if (sp.RC != (int)ReturnCode.SUCCESS)
{
if ((sp.RC == (int)ReturnCode.NO_RECORDS_RETURNED))
{
labelMessage.Text = "No data found for the specified filter";
}
else if ((sp.RC == (int)ReturnCode.UNHANDLED_EXCEPTION) || (ds == null))
{
labelMessage.Text = sp.ErrorMessage;
}
ds = null;
gridBias.DataSource = ds;
EnableControls(false);
SetGridColumns();
}
else
{
gridBias.TitleText = BuildGridTitleString();
gridBias.FilterText = BuildGridFilterString();
gridBias.EnableRowsPerPageEdit = true;
SetGridColumns();
//Since grid columns are dynamically added and can change between postbacks
//make sure sort column is valid, if not unset
if (gridBias.SortColumn != null && gridBias.SortColumn.Length > 0)
{
bool foundCol = false;
foreach (DataGridColumn dg in gridBias.Columns)
{
if (gridBias.SortColumn == dg.SortExpression)
{
foundCol = true;
break;
}
}
if (!foundCol)
{
gridBias.SortColumn = "";
gridBias.SortOrder = "";
}
}
if (gridBias.SortColumn.Length == 0) gridBias.SortColumn = "TestCode";
if (gridBias.SortOrder.Length == 0) gridBias.SortOrder = "ASC";
if (gridBias.PageIndex.Length != 0 &&
!gridBias.GridViewMode.Equals(CustomDataGrid.GridViewType.SHOWALL.ToString()))
gridBias.CurrentPageIndex = Convert.ToInt32(gridBias.PageIndex);
ds.Tables[0].DefaultView.Sort = gridBias.SortColumn + " " + gridBias.SortOrder;
gridBias.DataSource = ds.Tables[0].DefaultView;
EnableControls(true);
}
gridBias.HideEmptyColumns = true;
ArrayList cols = new ArrayList();
cols.AddRange(_alRecheckColumns);
gridBias.HideEmptyColumnsList = cols;
gridBias.DataBind();
}
catch (Exception ex)
{
CodeLibrary.ErrorHandling.SetLabel("Error(" + CodeLibrary.ErrorHandling.GetMethodName() + ")", ex.Message, labelMessage, true, "ErrorMsg");
}
}
private void SetGridColumns()
{
ArrayList alCols = new ArrayList();
alCols.Add(""); //Checkbox column
alCols.Add("Subject");
ArrayList alColumnsToBeDeleted = new ArrayList();
Boolean boolColExists = false;
foreach (ListItem chart in chkboxChartType.Items)
{
if (chart.Value == "%Bias")
{
if (rblBiasOptions.SelectedValue == "Subject")
{
foreach (DataGridColumn dg in gridBias.Columns)
{
boolColExists = false;
foreach (string gridColumn in alCols)
{
if (dg.HeaderText == gridColumn)
{
boolColExists = true;
break;
}
}
if (!boolColExists)
{
alColumnsToBeDeleted.Add(gridBias.Columns.IndexOf(dg));
}
}
}
}
// Loop thru the array list and delete columns from the grid.
int count = 0;
foreach (int i in alColumnsToBeDeleted)
{
gridBias.Columns.RemoveAt(i - count); //Subtract index by columns already deleted.
count++;
}
}
protected void buttonApprove_Click(object sender, EventArgs e)
{
try
{
CheckPermission(this.ModuleId, this.GetType().BaseType.ToString(), "buttonApprove_Click");
foreach (DataGridItem i in gridBias.Items)
{
//Loop thru each row and determien values to be saved to DB
if (i.ItemType == ListItemType.Item || i.ItemType == ListItemType.AlternatingItem)
{
bool cbSelected = ((CheckBox)i.FindControl("checkboxIsSelected")).Checked;
if (cbSelected)
{
bool IsApproved = true;
string strSubjectID = ((System.Web.UI.WebControls.Label)i.FindControl("labelSubjectID")).Text;
string strTestCode = ((System.Web.UI.WebControls.Label)i.FindControl("labelTestCode")).Text;
string strSampleType = ((System.Web.UI.WebControls.Label)i.FindControl("labelSampleType")).Text;
string strTestCodeAndType = ((System.Web.UI.WebControls.Label)i.FindControl("labelTestCodeAndType")).Text;
if (((System.Web.UI.WebControls.Label)i.FindControl("labelRecheckNeedsApproval")).Text == "1")
IsApproved = true;
else
IsApproved = false;
SaveToDB(strSubjectID, strTestCode, strSampleType, strTestCodeAndType,IsApproved);
}
}
}
BindGrid();
}
catch (Exception exceptionObject)
{
string strExceptionMessage = exceptionObject.Message + "-" + exceptionObject.InnerException.Message;
CodeLibrary.ErrorHandling.SetLabel("", strExceptionMessage, labelMessage, false, "ErrorMsg"); //--- Set label text
}
}

Get value of rows when it s checkbox is checked in radgrid

I have a radgride with checkbox in each rows.I want when i click on button,it checks id of each rows that checked,put into the variable..
I know this code for gridview but I do not know equivalent of this code for radgrid
foreach (GridViewRow rw in grid1.Rows)
{
CheckBox chkBx = (CheckBox)rw.FindControl("Check");
if (chkBx != null && chkBx.Checked)
{
id= grid1.Rows[0].Cells[3].Text.ToString();
}
}
if (RadGrid1.Items.Count > 0)
{
foreach (GridDataItem item in RadGrid1.Items)//loops through each grid row
{
CheckBox chkBx = (CheckBox)rw.FindControl("Check");
if (chkBx != null && chkBx.Checked)
{
//string v= item["ColumnUniqueName"].Text;
string v= item.Cells[3].Text; //accessing cell using its ColumnUniqueName
}
}
}
For more information on Radgrid rows and cell access, check http://www.telerik.com/help/aspnet-ajax/grid-accessing-cells-and-rows.html
Try this: http://www.telerik.com/community/forums/aspnet-ajax/grid/loop-through-radgrid.aspx
foreach(GridItem rw in grid1.Items)
{
CheckBox chkBx = rw.FindControl("Check") as CheckBox ;
if (chkBx != null && chkBx.Checked)
{
string id = rw.Cells[3].Text;
}
}

check/uncheckbox in gridview tracking

i have a below gridview control with a checkbox on it, so my question is when i hit on save button i able to find the checkbox which have been checked and till here no problem, but the problem started when the user tries to uncheck the checkedbox so how would i track the changes and save it into the db that has been checked. anyhelp?
List<Employee> result = new List<Employee>();
long Id = (long)Session["Id"];
result = Employee.GetEmployeeById(Id);
foreach (GridViewRow row in gv.Rows)
{
CheckBox chkBox = row.FindControl("chkSelected") as CheckBox;
if (c != null)
{
if (result.Count > 0)
{
foreach (Employee item in result)
{
Label Id = row.FindControl("lblId") as Label;
if (Id.Text == item.Id.ToString())
{
chkBox.Checked = true;
}
else
{
chkBox.Checked = false;
}
}
}
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="chkSelected" runat="server" Checked="false"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
<script language="javascript" type="text/javascript">
function SelectAll(cb)
{
var gvVar = document.getElementById("<%= gv.ClientID %>");
var cell;
if (gvVar.rows.length > 0)
{
for (i=1; i<gvVar.rows.length; i++)
{
cell = gvVar.rows[i].cells[0];
for (j=0; j<cell.childNodes.length; j++)
{
if (cell.childNodes[j].type =="checkbox")
{
cell.childNodes[j].checked = document.getElementById(cb).checked;
}
}
}
}
}
//--------------------------------------------------------------------------------------------.
function Select(cb)
{
var total = parseInt('<%= this.gv.Rows.Count %>');
var counter=0;
var cbSelectAll=document.getElementById(cb);
var gvVar = document.getElementById("<%= gv.ClientID %>");
var cell;
if (gvVar.rows.length > 0)
{
for (i=1; i<gvVar.rows.length; i++)
{
cell = gvVar.rows[i].cells[0];
for (j=0; j<cell.childNodes.length; j++)
{
if (cell.childNodes[j].type =="checkbox")
{
if(cell.childNodes[j].checked)
counter++;
else
counter--;
}
}
}
}
if(counter==total)
cbSelectAll.checked=true;
else if(counter<total)
cbSelectAll.checked=false;
}
</script>
//----------------------------------------------------------------------------------------
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && (e.Row.RowState == DataControlRowState.Normal || e.Row.RowState == DataControlRowState.Alternate))
{
CheckBox cbSelect = (CheckBox)e.Row.Cells[0].FindControl("cbSelect");
CheckBox cbSelectAll = (CheckBox)this.gv.HeaderRow.FindControl("cbSelectAll");
cbSelect.Attributes.Add("onclick", "javascript:Select('" + cbSelectAll.ClientID + "')");
cbSelectAll.Attributes.Add("onclick", "javascript:SelectAll('" + cbSelectAll.ClientID + "')");
}
}
Yes, store the original value in a hidden field. If always starting with false, you could use JavaScript to set the hidden value to true when the user clicked the checkbox. Using JQuery, you could do:
<asp:TemplateField HeaderText="Select" ItemStyle-CssClass="Checked">
<ItemTemplate>
<asp:CheckBox ID="chkSelected" runat="server" Checked="false"></asp:CheckBox>
<asp:HiddenField iD="dh" runat="server" />
</ItemTemplate>
</asp:TemplateField>
$("#<%= Grid.ClientID %>").find(".Checked > :checkbox").each(function() {
$(this).siblings("input[type='hidden']").attr("value", "True");
});
Something like that. On Server side, parse the value and if true, then you know it changed.
HTH.
It may not be the brightest idea, but you can query the database for the current state, and the compare with what you have got from the web page during a postback button click, or something like that. Or you can go with Brians answer.
It is possible to persist a list of objects into the Viewstate and access it in a consequent postback. The only thing is that the object you are trying to persist must be defined as serializable.
Update:
The ViewState approach
I feel this may be suitable for your need, and it requires a bit of linq. You'd need to create a class as follows:
[Serializable()]
public class OptionState
{
//the id of the item
int ID {get;set;}
//state of the checkbox
bool Checked {get;set;}
}
Note the Serializable attribute. This is required for the instance to persist to the viewstate.
Add the list of options to the viewstate:
var lstOptions = (from x in <your_option_store>
select new OptionState{ID = x.ID, Checked = x.Checked}).ToList();
ViewState.Add("options", lstOptions);
Here is a bit of code that should go into your button click:
foreach(GridViewRow row in gvOptions.Rows)
{
//not writing the bit of code
//which gets the ID and the
//state of checkbox of
//the gridview row being processed
OptionState currentState = GetOptionStateObjectFromRow(row);
List<OptionState> lstStates = (List<OptionState>) ViewState["options"];
OptionState originalState = lstStates.FirstOrDefault(x => x.ID == currentState.ID);
if(currentState.Checked != originalState.Checked)
{
//the appropriate db call needs to be done here.
}
}

Adding ListItems to a DropDownList from a generic list

I have a this aspx-code: (sample)
<asp:DropDownList runat="server" ID="ddList1"></asp:DropDownList>
With this codebehind:
List<System.Web.UI.WebControls.ListItem> colors = new List<System.Web.UI.WebControls.ListItem>();
colors.Add(new ListItem("Select Value", "0"));
colors.Add(new ListItem("Red", "1"));
colors.Add(new ListItem("Green", "2"));
colors.Add(new ListItem("Blue", "3"));
ddList1.DataSource = colors;
ddList1.DataBind();
The output looks like this:
<select name="ddList1" id="ddList1">
<option value="Select Value">Select Value</option>
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
My question is: Why did my values (numbers) disappear and the text used as the value AND the text? I know that it works if I use the ddList1.Items.Add(New ListItem("text", "value")) method, but I need to use a generic list as the datasource for other reasons.
Because DataBind method binds values only if DataValueField property is set. If you set DataValueField property to "Value" before calling DataBind, your values will appear on the markup.
UPDATE: You will also need to set DataTextField property to "Text". It is because data binding and adding items manually do not work in the same way. Databinding does not know the existence of type ListItem and generates markup by evaluating the items in the data source.
And here is the method that performs the data binding. You can exactly see what is going on:
protected internal override void PerformDataBinding(IEnumerable dataSource)
{
base.PerformDataBinding(dataSource);
if (dataSource != null)
{
bool flag = false;
bool flag2 = false;
string dataTextField = this.DataTextField;
string dataValueField = this.DataValueField;
string dataTextFormatString = this.DataTextFormatString;
if (!this.AppendDataBoundItems)
{
this.Items.Clear();
}
ICollection is2 = dataSource as ICollection;
if (is2 != null)
{
this.Items.Capacity = is2.Count + this.Items.Count;
}
if ((dataTextField.Length != 0) || (dataValueField.Length != 0))
{
flag = true;
}
if (dataTextFormatString.Length != 0)
{
flag2 = true;
}
foreach (object obj2 in dataSource)
{
ListItem item = new ListItem();
if (flag)
{
if (dataTextField.Length > 0)
{
item.Text = DataBinder.GetPropertyValue(obj2, dataTextField, dataTextFormatString);
}
if (dataValueField.Length > 0)
{
item.Value = DataBinder.GetPropertyValue(obj2, dataValueField, null);
}
}
else
{
if (flag2)
{
item.Text = string.Format(CultureInfo.CurrentCulture, dataTextFormatString, new object[] { obj2 });
}
else
{
item.Text = obj2.ToString();
}
item.Value = obj2.ToString();
}
this.Items.Add(item);
}
}
if (this.cachedSelectedValue != null)
{
int num = -1;
num = this.Items.FindByValueInternal(this.cachedSelectedValue, true);
if (-1 == num)
{
throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" }));
}
if ((this.cachedSelectedIndex != -1) && (this.cachedSelectedIndex != num))
{
throw new ArgumentException(SR.GetString("Attributes_mutually_exclusive", new object[] { "SelectedIndex", "SelectedValue" }));
}
this.SelectedIndex = num;
this.cachedSelectedValue = null;
this.cachedSelectedIndex = -1;
}
else if (this.cachedSelectedIndex != -1)
{
this.SelectedIndex = this.cachedSelectedIndex;
this.cachedSelectedIndex = -1;
}
}
If you are building ListItems, you have no need to use DataBind() in the first place.
Just add them to your DropDownList:
ddList1.Items.Add(new ListItem("Select Value", "0"));
ddList1.Items.Add(new ListItem("Red", "1"));
ddList1.Items.Add(new ListItem("Green", "2"));
ddList1.Items.Add(new ListItem("Blue", "3"));
DataBind() is useful when you already have a collection/dataobject (usually a DataTable or DataView) that can be used as a DataSource, by setting the DataTextField and DataValueField (as buyutec wrote).
"If you are building ListItems, you have no need to use DataBind() in the first place."
Adding directly to the dropdownlist is the easy way (and given the example code the right one) but lets say you have an unordered datasource and you want the list items sorted.
One way of achieving this would be to create a generic list of ListItem and then use the inherited sort method before databinding to the list.
There are many wys to skin a cat...

Resources