In my webpage, I have Calendar, Table and button.
After selecting date, it will fire the databind() method of table. There are checkboxes with autopostback =true. Once checked, the Table disappears. I have no idea on how to retain the table with the checked checkboxes after post back.
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString.Get("Id") != null)
{
if (!IsPostBack)
{
Calendar1.Visible = false;
}
}
}
protected void Calendar1_SelectionChanged(object sender, EventArgs e)
{
Label1.Text = Calendar1.SelectedDate.ToShortDateString();
//Set datasource = (cal.selectedDate), the invoking override
// DataBind() method to create table
}
Calendar1.Visible = false;
}
I've tried to databind the table again else (IsPostBack) but i wasn't able to achieve my goals, instead, it created another table on top of the existing table
This is the method to create Table with checkboxes
public override void DataBind()
{
TableRow myTableRow = default(TableRow);
TableCell myTableCell = default(TableCell);
if (source != null && !(mDate == DateTime.MinValue))
{
for (int i = 0; i <= 23; i++)
{
foreach (DataRow row in source.Tables["Object"].Rows)
{
myTableCell = new TableCell();
CheckBox cb = new CheckBox();
cb.AutoPostBack = true;
cb.Attributes.Add("id", row["objid"].ToString());
cb.InputAttributes.Add("rowID", mDate.Date.AddHours(i).ToString());
myTableCell.Controls.Add(cb);
myTableCell.HorizontalAlign = HorizontalAlign.Center;
myTableRow.Cells.Add(myTableCell);
TimeSheetTable.Rows.Add(myTableRow);
}
}
}
else
{
throw new ArgumentException(" Invalid Date.");
}
}
Dynamically generated tables need to be regenerated on every postback. For subsequent postbacks, viewstate will be reloaded, but you have to recreate the table, cells, and controls in the same exact fashion, otherwise web forms complains about it. You need to do this during Init I believe; if checkbox checked status changed, the web forms framework will update the Checked property after load, so that will be taken care of.
I usually use a repeater or listview control as dynamic controls can be painful and the ListView is pretty flexible. Databinding takes care of rebuilding the control tree for you.
Related
I've a custom combobox template because of some binding stuff that won't work with the 'default' ComboBoxColumn.
To make it look 'nice' I've one template for the edit mode (a Combobox) and one for the 'normal' mode (a Label).
Now, because of that I've to commit the edit made to the combobox manually inside the CellEditEnding event
private bool changeCommitInProgress = false;
private void table_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if (e.EditingElement is ContentPresenter && e.EditAction == DataGridEditAction.Commit)
{
if (!changeCommitInProgress)
{
changeCommitInProgress = true;
DataGrid grid = (DataGrid)sender;
grid.CommitEdit(DataGridEditingUnit.Row, false);
changeCommitInProgress = false;
}
}
}
The problem with this is, that it'll remove the focus from the entire datagrid. Just to be on the safe side, these are the only properties I changed on the datagrid (aside from the Name property and the ItemsSource):
grid.AutoGenerateColumns = false;
grid.IsSynchronizedWithCurrentItem = true;
grid.SelectionUnit = DataGridSelectionUnit.Cell;
This is a fun question. I have done similar with a nested DataList where I had to add a new row after last entry and focus on the first textbox of the newly generated row, maybe you can extrapolate my strategy to fit your situation?
protected void calcAvg(object sender, CommandEventArgs e)
{
int row = Convert.ToInt32(e.CommandArgument.ToString()) - 1;
DataListItem ActiveRow = dlMeasurements.Items[row];
// Snipped code doing stuff with current row
// Compare how many rows completed to number of rows requested
if (!(row + 1 == Convert.ToInt32(txtSample.Text)))
{
// Create new row
DataRow drNew = nextMeas.Tables[0].NewRow();
nextMeas.Tables[0].Rows.Add(drNew);
// Change item index and rebind
dlMeasurements.EditItemIndex = row + 1;
dlMeasurements.DataSource = nextMeas.Tables[0];
dlMeasurements.DataBind();
//Set focus with the Script Manager
smInspection.SetFocus((TextBox)(dlMeasurements.Items[row + 1].FindControl("txtRead1")));
}
else
{
// Otherwise close the measurements and show exit button
dlMeasurements.EditItemIndex = -1;
dlMeasurements.DataSource = nextMeas.Tables[0];
dlMeasurements.DataBind();
btnSaveAndPrint.Visible = true;
}
}
}
On my page I have 3 textboxes that hold values for Title, Description, Tips and keywords. When I click on a button it inserts the values into the database. When it posts back, the values are staying in the textboxes, and this is what I want.
The next part of the page has textboxes for Question, CorrectAnswer, Wrong1, Wrong2, Wrong3. When I click on the button to insert them into the database, that works, and after the button fires its event I have those 5 textboxes have a text value of null, so I can continue on adding the question and answers.
But when that button causes its postback, the values in the first textboxes disappear, and I don't want that because I have validation on the title textbox, because you can't add any questions and answers without the title in the textbox.
So how do I keep the values in the first textboxes when the second button causes a postback?
Here is the code for the two buttons, and the btnAddQandA is the button that causes a postback..
protected void btnAddQuizTitle_Click(object sender, EventArgs e)
{
daccess.AddQuizName(tbTitle.Text, taDescription.InnerText, taTips.InnerText, tbKeywords.Text);
Session["TheQuizID"] = daccess.TheID;
string myID = (string)(Session["TheQuizID"]);
int theID = Int32.Parse(myID);
if (tbKeywords.Text != null)
{
string TheKeywordHolder = "";
foreach (ListItem LI in cblGrades.Items)
{
if (LI.Selected == true)
{
TheKeywordHolder = TheKeywordHolder + LI.Value + ",";
}
}
daccess.AddQuizKeywords(theID, tbKeywords.Text);
}
}
protected void btnAddQA_Click(object sender, EventArgs e)
{
int theID = (int)Session["TheQuizID"];
daccess.AddQuizQA(tbQuestion.Text, tbCorrect.Text, tbWrong1.Text, tbWrong2.Text, tbWrong3.Text, theID);
tbQuestion.Text = null;
tbCorrect.Text = null;
tbWrong1.Text = null;
tbWrong2.Text = null;
tbWrong3.Text = null;
}
and here is my pageload event
DataAccess daccess = new DataAccess();
protected void Page_Load(object sender, EventArgs e)
{
daccess.CblGradesDS();
cblGrades.DataSource = daccess.DsCbl;
cblGrades.DataValueField = "GradeID";
cblGrades.DataTextField = "Grade";
cblGrades.RepeatColumns = 8;
cblGrades.RepeatDirection = RepeatDirection.Horizontal;
cblGrades.DataBind();
daccess.CblSubjectsDS();
cblSubjects.DataSource = daccess.DsCbl2;
cblSubjects.DataValueField = "SubjectID";
cblSubjects.DataTextField = "SubjectName";
cblSubjects.RepeatColumns = 4;
cblSubjects.RepeatDirection = RepeatDirection.Horizontal;
cblSubjects.DataBind();
if (!IsPostBack)
{
}
}
These issues are usually caused by control IDs (UniqueIDs to be specific) that do not match before and after the postback. This causes inability of finding values in viewstate. This happens when you modify the controls collection (typically in codebehind) or when you change controls' visibility. It may also happen when you modify IDs before Page_Load event when viewstate is not yet populated. It's good to know how ASP.NET lifecycle works. http://spazzarama.com/wp-content/uploads/2009/02/aspnet_page-control-life-cycle.jpg
I have used template CheckBox in gridview for multiple rows deletion, when I select multiple rows by selecting the CheckBox and perform the delete operation it seems to be selected CheckBox is not returning true on the code below.
protected void Button6_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
LinkButton ch = new LinkButton();
ch = (LinkButton)row.FindControl("l1");
id = Convert.ToInt16(ch.CommandArgument);
CheckBox chs = new CheckBox();
chs = ((CheckBox)row.FindControl("c1"));
if (chs.Checked == true)
{
DeleteSelected(id);
}
}
}
private void DeleteSelected(short id)
{
var ch = from a in empd.Employees where (a.ID == id) select a;
empd.Employees.DeleteAllOnSubmit(ch);
empd.SubmitChanges();
display_emp();
}
Could someone please assist me why CheckBox is not returning true value in calling function.
Well now I have fixed the connection everything, please just refresh the database.Please get the web application in the below link.
http://www.ziddu.com/download/20716096/WebApplication.zip.html
Please help me on why selected checkbox are not returning true in the code.
Details: Add if(IsPostback) at the start otherwise it just resets your grid controls. Example below
Solution:
if (!IsPostBack)
{
empd = new Employee_DetailsDataContext();
empd.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["DemosConnectionString1"].ConnectionString;
display_emp();
}
I know I must be missing something. If I make changes to a datagriditem in the ItemDataBound event of the RadGrid the changes are not visible the first time the page loads, I don't see the changes to the DataItem until I refresh the grid via the CommandItem for refresh. I have verified that the ItemDataBound event is fired and the values that I am replacing do infact have the correct values.
background:
I have a class that creates the RadGrid. It is then instantiated and loaded into the .aspx page via the code behind for the .aspx. This is a master/detail datagrid if that makes any difference.
protected void Page_Init(object source, EventArgs e)
{
this.__activeBatchesRadGrid = ActiveBatchesRadGrid.GridDefinition("ActiveBatchesRadGrid");
this.PlaceHolder1.Controls.Add(this.__activeBatchesRadGrid);
this.__activeBatchesRadGrid.ItemDataBound += new GridItemEventHandler(ActiveBatchesRadGrid_ItemDataBound);
}
private void ActiveBatchesRadGrid_ItemDataBound(object sender, GridItemEventArgs e)
{
GridDataItem _dataItem = e.Item as GridDataItem;
if (_dataItem == null) return;
BatchStatusType _batchStatus = EnumUtils.GetValueFromName<BatchStatusType>(_dataItem["BatchStatusName"].Text);
Dictionary<BatchStatusType, BatchStatusType> _batchStatusTypes =
BatchTransitions.GetBatchStatusTransition(_batchStatus);
GridButtonColumn _btnPromote =
((GridButtonColumn) this.__activeBatchesRadGrid.MasterTableView.GetColumn("MasterPromoteRecord"));
GridButtonColumn _btnDelete =
((GridButtonColumn)this.__activeBatchesRadGrid.MasterTableView.GetColumn("MasterDeleteRecord"));
foreach (KeyValuePair<BatchStatusType, BatchStatusType> _item in _batchStatusTypes)
{
_btnPromote.Text = _item.Value.ToString();
_btnPromote.ConfirmText = string.Format("Are you sure you want to promote this batch to {0} status?",
_item.Value);
_btnDelete.Text = string.Format("Demote batch to {0} status.", _item.Key.ToString());
_btnDelete.ConfirmText = string.Format("Are you sure you want to demote this batch to {0} status?",
_item.Key);
}
}
I thought I would post the solution I put together that takes care of this problem. I do however, still believe that the proper implementation that I originally posted should work. If it works for all items other than the first datagrid row then I believe there is a shortcoming in the control.
private void ActiveBatchesRadGrid_ItemDataBound(object sender, GridItemEventArgs e)
{
GridDataItem _dataItem = e.Item as GridDataItem;
if (_dataItem == null) return;
if (_dataItem.KeyValues == "{}") { return; }
int _counter = 0;
Dictionary<String, String> _batchStatusTypes =
BatchTransitions.GetBatchStatusTransition(
EnumUtils.GetValueFromName<BatchStatusType>(_dataItem["BatchStatusName"].Text));
//accessing the cell content directly rather than trying to access the property of the GridEditCommandColumn
((ImageButton)(((GridEditableItem)e.Item)["MasterEditrecord"].Controls[0])).ImageUrl = "/controls/styles/images/editpencil.png";
//accessing the cell content directly rather than trying to access the property of the GridButtonColumn
ImageButton _imgbtnPromote = (ImageButton)((GridDataItem)e.Item)["MasterPromoteRecord"].Controls[0];
ImageButton _imgbtnDelete = (ImageButton)((GridDataItem)e.Item)["MasterDeleteRecord"].Controls[0];
foreach (KeyValuePair<String, String> _kvp in _batchStatusTypes)
{
if (_counter == 0)
{
const string _jqueryCode = "if(!$find('{0}').confirm('{1}', event, '{2}'))return false;";
const string _confirmText = "Are you sure you want to change the status of this batch {0}?";
_imgbtnPromote.Attributes["onclick"] = string.Format(_jqueryCode, ((Control) sender).ClientID,
string.Format(_confirmText, _kvp.Value),
_kvp.Value);
_imgbtnDelete.Attributes["onclick"] = string.Format(_jqueryCode, ((Control) sender).ClientID,
string.Format(_confirmText, _kvp.Key), _kvp.Key);
_counter++;
continue;
}
_imgbtnPromote.ImageUrl = "~/controls/styles/images/approve.png";
_imgbtnPromote.ToolTip = string.Format("{0} batch", _kvp.Value);
_imgbtnDelete.ImageUrl = "/controls/styles/images/decline.png";
_imgbtnDelete.ToolTip = string.Format("{0} batch", _kvp.Key);
}
}
I am making conditional formatting changes to the data in my gridview using a RowDataBound event:
void gvReg_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DateTime lastUpdate DateTime.Parse(DataBinder.Eval (e.Row.DataItem, "LAST_UPDATE");
if (lastUpdate < DateTime.Today.AddMonths(-1))
{
Hyperlink hypLastUpdate = (Hyperlink)e.Row.FindControl("hypLastUpdate";
hypLastUpdate.CssClass = "Error";
hypLastUpdate.NavigateUrl = "http://www.someExampleErrorPage.com";
}
}
}
This works, and sets the proper CssClass to the hyperlink (which makes it a jarring shade of bold red), but once the gridview is sorted (via the user clicking a column heading) the css class is reset on hypLastUpdate and it loses both it's style and associated NavigateUrl property.
The control hypLastUpdate is contained in a template field in a gridview, and it's text value is databound to a field called "LAST_UPDATE".
Is this a planned behavior (is sorting supposed to break the conditional formatting done in RowDataBound events?) or is there something I can check to make sure I am not doing something incorrectly?
I am not using the DataBind method anywhere in the code behind, and viewstate is turned on for the gridview in question.
--EDIT--
It ended up being a mistake in event handling.
I was doing:
gvReg.Sorted += {SomeEventHandler}
Inside of the page load event, but only when it wasn't a postback. This function called gvReg.DataBind after the grid view was sorted. I removed the handler wire up and instead added the event handler function to the OnSorted event. I guess assigned delegates to a gridview are not saved in ViewState between callbacks?
Hi here is a quick example of what I meant on my comment. This is the only way i could think of it:
protected void gvReg_Sorting(object sender, GridViewSortEventArgs e)
{
GridView gridView = (GridView)sender;
if (e.SortExpression.Length > 0)
{
foreach (DataControlField field in gridView.Columns)
{
if (field.SortExpression == e.SortExpression)
{
cellIndex = gridView.Columns.IndexOf(field);
break;
}
}
if (pSortExpression != e.SortExpression)
{
pSortDirection = SortDirection.Ascending;
}
else
{
pSortDirection = (pSortDirection == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending);
}
pSortExpression = e.SortExpression;
}
//Retrieve the table from the database
pSortOrder = pSortDirection == SortDirection.Ascending ? "ASC" : "DESC";
List<Partners> partnerList = GetPartnerList();
gvReg.DataSource = partnerList;
gvReg.DataBind();
}