ASP.NET - User control custom data binding - asp.net

I develop user control Date of Birth, which contains 3 DropDownList.
I need to make data binding, but I dunno how.
public partial class DofControl : System.Web.UI.UserControl {
public const int YearsCount = 100;
int _year;
Months _month;
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack ) {
Bind();
}
if (SessionWrapper.JustInserted)
{
Bind();
SessionWrapper.JustInserted = false;
}
}
public object DataSource {
get; set;
}
private void Bind() {
int[] years = new int[YearsCount];
int from = DateTime.Now.Year - 5;
int to = from - 100;
for (int i = 0; i < YearsCount; i++) {
years[i] = to;
to++;
}
ddlYear.DataSource = years;
ddlYear.DataBind();
ddlMonth.DataSource = Enum.GetNames(typeof(Months));
ddlMonth.DataBind();
_year = Int32.Parse(ddlYear.SelectedValue);
_month = (Months)Enum.Parse(typeof(Months), ddlMonth.SelectedValue);
BindDays(_year, _month);
if (DataSource==null)
{
ddlYear.SelectedValue = years.Max().ToString();
ddlMonth.SelectedValue = Months.January.ToString();
ddlDay.SelectedValue = "1";
}
else
{
ddlYear.SelectedValue = Convert.ToDateTime(DataSource).Year.ToString();
ddlMonth.SelectedValue = Enum.GetName(typeof(Months), Convert.ToDateTime(DataSource).Month);
ddlDay.SelectedValue = Convert.ToDateTime(DataSource).Day.ToString();
}
}
enum Months { January = 1 //....... }
//Is this right?
[Bindable(true,BindingDirection.TwoWay)]
public DateTime Date {
private get {
return DateTime.Parse(string.Format("{0}/{1}/{2}", ddlDay.Text, ddlMonth.Text, ddlYear.Text));
}
set
{
ddlYear.SelectedValue = value.Year.ToString();
ddlMonth.SelectedValue = value.Month.ToString();
ddlDay.SelectedValue = value.Day.ToString();
}
}
protected void ddlMonth_SelectedIndexChanged(object sender, EventArgs e) {
_year = int.Parse(ddlYear.SelectedValue);
_month = (Months)Enum.Parse(typeof(Months), ddlMonth.SelectedValue);
BindDays(_year, _month);
}
protected void ddlYear_SelectedIndexChanged(object sender, EventArgs e) {
_year = int.Parse(ddlYear.SelectedValue);
_month = (Months)Enum.Parse(typeof(Months), ddlMonth.SelectedValue);
BindDays(_year, _month);
}
public bool IsLeapYear(int year) { //..... }
private void BindDays(int year, Months month) {
List<int> days = new List<int>();
switch (month) {
case Months.January:
case Months.March:
for (int i = 1; i <= 31; i++)
days.Add(i);
break;
case Months.February:
//does not matter
}
}
I use DofControl in a page Update.aspx inside asp:DetailsView.
<asp:ObjectDataSource ID="odsOneStudent" runat="server"
SelectMethod="GetStudentById"
..////
<asp:DetailsView
//......
<Fields>
<asp:BoundField DataField="SurName" HeaderText="SurName" />
<asp:TemplateField HeaderText="Dof">
<EditItemTemplate>
<uc:Dof runat="server" ID="dfDof" Date='<%#Eval("Dof") %>' />
</EditItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
I does not work, I get an error "ddlMonth' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value"
Am I miss anything?
update: I get an error: "Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control"

When you set the SelectedValue of a DropDownList the value must be contained in the list's items.
Check where you are setting the SelectedValue that the value you are using is correct and contained in the DropDownList.Items

Related

Save Cancel button event handler is not working in Radscheduler advance insert form

In my application I have a radschedular , when creating a new appointment I am opening in advance mode by specifying StartInsertingInAdvancedForm="True"
My code is given below
.aspx
<telerik:RadScheduler RenderMode="Lightweight" runat="server" ID="rs_course_schedule" CustomAttributeNames="Completed"
StartInsertingInAdvancedForm="True" StartEditingInAdvancedForm="True"
FirstDayOfWeek="Monday" LastDayOfWeek="Friday" Reminders-Enabled="true" SelectedView="WeekView"
RowHeight="30px" AppointmentStyleMode="Simple" OnAppointmentDataBound="RadScheduler1_AppointmentDataBound"
OnAppointmentCommand="rs_course_schedule_OnAppointmentCommand"
OnAppointmentCreated="RadScheduler1_AppointmentCreated" OverflowBehavior="Auto" Skin="Web20"
OnAppointmentInsert="rs_course_schedule_OnAppointmentInsert">
<AdvancedForm Modal="true"></AdvancedForm>
<AppointmentTemplate>
<div class="appointmentHeader">
<asp:Panel ID="RecurrencePanel" CssClass="rsAptRecurrence" runat="server" Visible="false">
</asp:Panel>
<asp:Panel ID="RecurrenceExceptionPanel" CssClass="rsAptRecurrenceException" runat="server"
Visible="false">
</asp:Panel>
<asp:Panel ID="ReminderPanel" CssClass="rsAptReminder" runat="server" Visible="false">
</asp:Panel>
<%#Eval("Subject") %>
</div>
<div>
Assigned to: <strong>
<asp:Label ID="UserLabel" runat="server" Text='<%# Container.Appointment.Resources.GetResourceByType("Faculty") == null ? "None" : Container.Appointment.Resources.GetResourceByType("Faculty").Text %>'></asp:Label>
</strong>
<br />
<asp:CheckBox ID="CompletedStatusCheckBox" runat="server" Text="Completed? " TextAlign="Left"
Checked='<%# !String.IsNullOrEmpty(Container.Appointment.Attributes["Completed"]) && Boolean.Parse(Container.Appointment.Attributes["Completed"]) %>'
AutoPostBack="true" OnCheckedChanged="CompletedStatusCheckBox_CheckedChanged"></asp:CheckBox>
</div>
</AppointmentTemplate>
<ResourceStyles>
<telerik:ResourceStyleMapping Type="Faculty" Key="1" BackColor="red"></telerik:ResourceStyleMapping>
<telerik:ResourceStyleMapping Type="Faculty" Key="2" BackColor="Pink"></telerik:ResourceStyleMapping>
<telerik:ResourceStyleMapping Type="Faculty" Key="3" BackColor="OrangeRed"></telerik:ResourceStyleMapping>
</ResourceStyles>
</telerik:RadScheduler>
in code behind
public partial class Schedule : System.Web.UI.UserControl
{
#region Object Instantiation
readonly BEL_LMS _objLms = new BEL_LMS();
readonly BL_LMS _blLms = new BL_LMS();
#endregion
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
PopulateSchedular();
AddTeachers();
SetDate();
}
}
private void AddTeachers()
{
_objLms.ActivityId = Session["activity_id"].ToString();
DataTable dtFaculty = _blLms.AssignedFaculty(_objLms);
ResourceType resources = new ResourceType("Faculty");
if (dtFaculty.Rows.Count > 0)
{
resources.DataSource = dtFaculty;
resources.KeyField = "userid";
resources.TextField = "acct_name";
resources.ForeignKeyField = "UserId";
rs_course_schedule.ResourceTypes.Add(resources);
}
}
private void SetDate()
{
rs_course_schedule.SelectedDate = DateTime.Now;
}
private void PopulateSchedular()
{
_objLms.Flag = "fetch";
_objLms.ActivityId = "11";
DataTable dtTable = _blLms.FetchScheduleForCourse(_objLms);
if (dtTable.Rows.Count > 0)
{
rs_course_schedule.DataKeyField = "ID";
rs_course_schedule.DataStartField = "Start";
rs_course_schedule.DataEndField = "End";
rs_course_schedule.DataSubjectField = "Subject";
rs_course_schedule.DataDescriptionField = "Description";
//rs_course_schedule.DataReminderField = "Reminder";
rs_course_schedule.DataSource = dtTable;
rs_course_schedule.DataBind();
}
}
protected void CompletedStatusCheckBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox CompletedStatusCheckBox = (CheckBox)sender;
//Find the appointment object to directly interact with it
SchedulerAppointmentContainer appContainer = (SchedulerAppointmentContainer)CompletedStatusCheckBox.Parent;
Appointment appointment = appContainer.Appointment;
_objLms.ActivityId = appointment.ID.ToString();
_objLms.Flag = "update";
int affectedRow = _blLms.UpdateCourse(_objLms); // update checkbox data for that particular schedule
rs_course_schedule.Rebind();
}
protected void RadScheduler1_AppointmentDataBound(object sender, SchedulerEventArgs e)
{
if (e.Appointment.Attributes["Completed"] == "True")
{
e.Appointment.BackColor = System.Drawing.Color.Red;
}
}
protected void RadScheduler1_AppointmentCreated(object sender, AppointmentCreatedEventArgs e)
{
}
protected void rs_course_schedule_OnAppointmentInsert(object sender, AppointmentInsertEventArgs e)
{
SchedulerDataSource.InsertParameters["End"].DefaultValue = e.Appointment.End.ToString();
SchedulerDataSource.InsertParameters["Start"].DefaultValue = e.Appointment.Start.ToString();
SchedulerDataSource.InsertParameters["Subject"].DefaultValue = e.Appointment.Start.ToString();
SchedulerDataSource.InsertParameters["Description"].DefaultValue = e.Appointment.Description;
SchedulerDataSource.InsertParameters["CourseID"].DefaultValue = "1";
//SchedulerDataSource.InsertParameters["User"].DefaultVal;
}
protected void rs_course_schedule_OnAppointmentCommand(object sender, AppointmentCommandEventArgs e)
{
string name = e.CommandName;
}
}
}
Now when I am trying to insert a new appointment this form is opening
But in Save and Cancel button click is not occurring..
How I can solve this issue ?

DevExpress modify label in templateitem

I am working with DevExpress platform.
I have a axGridview that contains an ItemTemplate with a Label, i need just modify in every row with value.
With asp.net and GridView i used to manage FindControl in RowDataboundEvent, but here i really need help. The FindCellTemplate function always returns NULL.
here my code:
<dx:ASPxGridView ID="gvRecapiti" ClientIDMode="Static" ClientInstanceName="gvRecapiti" Width="100%" runat="server" AutoGenerateColumns="False"
OnHtmlRowCreated="gvRecapiti_HtmlRowCreated" >
<Columns>
<dx:GridViewDataColumn Caption="RecapitoTipo" >
<SettingsHeaderFilter>
<DateRangePickerSettings EditFormatString=""></DateRangePickerSettings>
</SettingsHeaderFilter>
</dx:GridViewDataColumn>
<dx:GridViewDataTextColumn FieldName="DescRecapito" >
<DataItemTemplate>
<dx:ASPxLabel ID="lblRecapito" ClientIDMode="Static" runat="server" ClientInstanceName="lblRecapito" Text='<%# Eval("DescRecapito") %>' ></dx:ASPxLabel>
</DataItemTemplate>
</dx:GridViewDataTextColumn>
</Columns>
</dx:ASPxGridView>
using DevExpress.Web;
namespace ProvaGridItem
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack != false)
{
BindGrid();
}
}
private void BindGrid()
{
List<Recapito> R = new List<Recapito>();
for (int i=0;i<5;i++)
{
Recapito Recapito = new Recapito();
Recapito.DescRecapito = "Recapito: " + i;
Recapito.RecapitoTipo="RecapitoTipo: "+i;
R.Add(Recapito);
}
gvRecapiti.DataSource = R;
gvRecapiti.DataBind();
}
protected void gvRecapiti_HtmlRowCreated(object sender, DevExpress.Web.ASPxGridViewTableRowEventArgs e)
{
if (e.RowType != DevExpress.Web.GridViewRowType.Data) return;
ASPxLabel lblRecapitoTipo = (ASPxLabel)gvRecapiti.FindRowCellTemplateControl(e.VisibleIndex, null, "lblRecapitoTipo");
lblRecapitoTipo.Text = "Label Updated by code!!";
}
internal class Recapito
{
public string RecapitoTipo { get; set; }
public string DescRecapito { get; set; }
}
}
}
(ASPxLabel)gvRecapiti.FindRowCellTemplateControl(e.VisibleIndex, null, "lblRecapitoTipo");
This should have column to find control. so that first get column in a variable and then find template control of that column.Please go through with below code.
GridViewDataTextColumn col = gvRecapiti.Columns["lblRecapito"] as GridViewDataTextColumn;
ASPxLabel lblRecapitoTipo = gvRecapiti.FindRowCellTemplateControl(e.VisibleIndex, col , "lblRecapitoTipo") as ASPxLabel;
and then you can change lblRecapitoTipo label properties as you want.In your case it is
lblRecapitoTipo.Text = "Label Updated by code!!";

ASP.NET GridView RowDataBound TemplateField FindControl is null after invalid data entered

I am having trouble with my GridView RowDataBound event after I click on Save to save the data to the database.
I have a grid with 5 columns: Tag Name, Current Timestamp, Current Value, New Date, New Value.
The idea is the user will enter into the New Date/New Value to update the data in the database. The Current Timestamp and Current Value are what is already stored in the database.
I use a JQuery editor to enter the date.
When I click on Save, I have server side validation in place to check the entered values. If the data is valid, a message under the text in the New Value column is displayed to indicate this. If the validation fails, then a message in the New Value column is displayed.
New Date and New Value columns are TemplateField's. The New Value TemplateField contains a panel with two labels - one for OK status and the other for error.
The error occurs in MyDataGrid_RowDataBound when I call any e.Row.FindControl(...) which is triggered from the Save button click when I rebind.
It works ok if a valid value has been entered but if an invalid value is entered then it errors. In order to simplify the scenario, enter 100 for a valid value and anything else for an invalid.
This WebForm has been the trouble of my life. Maybe I shouldn't have used a GridView.
Anyway, I would appreciate any help here to identify the issue. And maybe a better approach to the form code.
I've took the code from my solution and moved it into a standalone solution to reproduce the issue. I've removed the database access and populated a datastructure. This is only ever done (once) in the Page Load when the page is initially loaded.
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="stylesheet" href="Styles/jquery-ui-timepicker-addon.css" />
<link rel="stylesheet" href="Styles/jquery-ui-1.10.1.custom.css" />
<link rel="stylesheet" href="Styles/jquery-ui-1.10.1.custom.min.css" />
<script src="Scripts/jquery-1.9.1.js"></script>
<script src="Scripts/jquery-ui-1.10.1.custom.js"></script>
<script src="Scripts/jquery-ui-1.10.1.custom.min.js"></script>
<script src="Scripts/jquery-ui-timepicker-addon.js"></script>
</head>
<body>
<script type="text/javascript">
/** Disable backkey */
$(document).unbind('keydown').bind('keydown', function (event) {
var doPrevent = false;
if (event.keyCode === 8) {
var d = event.srcElement || event.target;
if ((d.tagName.toUpperCase() === 'INPUT' && (d.type.toUpperCase() === 'TEXT' || d.type.toUpperCase() === 'PASSWORD' || d.type.toUpperCase() === 'FILE'))
|| d.tagName.toUpperCase() === 'TEXTAREA') {
doPrevent = d.readOnly || d.disabled;
} else {
doPrevent = true;
}
}
if (doPrevent) {
event.preventDefault();
}
});
$(function () {
$(".datetimepicker").datetimepicker({
changeMonth: true,
changeYear: true
});
});
$(function () {
$(".datepicker").datepicker({
changeMonth: true,
changeYear: true
});
});
$(function () {
$(".timepicker").timepicker({ showTimezone: false });
});
</script>
<form id="form1" runat="server">
<div>
<asp:GridView ID="MyDataGrid" runat="server"
EnableModelValidation="True"
DataKeyNames="Id"
AutoGenerateColumns="False"
AutoGenerateSelectButton="False"
EmptyDataText="There is no plant data configured."
OnRowDataBound="MyDataGrid_RowDataBound">
<Columns>
<asp:BoundField DataField="Name" SortExpression="Name" HeaderText="Tag Name"></asp:BoundField>
<asp:BoundField DataField="Date" SortExpression="Date" HeaderText="Current Timestamp"></asp:BoundField>
<asp:BoundField DataField="Value" SortExpression="Value" HeaderText="Current Value"></asp:BoundField>
<asp:TemplateField HeaderText="New Date<BR/>MM/DD/YYYY HH:MM">
<ItemTemplate>
<asp:TextBox ID="txtNewDate" runat="server" CssClass="datetimepicker"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="New Value">
<ItemTemplate>
<asp:TextBox ID="txtNewValue" runat="server"></asp:TextBox>
<asp:Panel ID="ErrorPanel" runat="server">
<br />
<asp:Label ID="lblError" runat="server" ForeColor="Red"></asp:Label>
<asp:Label ID="lblStatus" runat="server" ForeColor="#66cc00"></asp:Label>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="SaveButton" runat="server"
Text="Save Values"
ToolTip="Save the current changes."
OnClick="SaveButton_Click" />
</div>
</form>
</body>
</html>
Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
private const int COL_NEW_DATE = 3;
private const int COL_NEW_VALUE = 4;
bool canEdit = true;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
PopulateDataGrid();
}
}
private void PopulateDataGrid()
{
// this is where i load from the database
List<RowData> data = new List<RowData>() {
new RowData() { Date = new DateTime(2000,1,1), Editable = true, Name = "Data Item 1", Value = 100.0 },
new RowData() { Date = new DateTime(2000,1,1), Editable = false, Name = "Data Item 2", Value = 120.0 },
new RowData() { Date = new DateTime(2000,1,1), Editable = true, Name = "Data Item 3", Value = 19.0 }
};
this.MyDataGrid.DataSource = data;
this.MyDataGrid.DataBind();
ViewState["GridData"] = this.MyDataGrid.DataSource;
}
private void SaveData()
{
for (int i = Page.Validators.Count - 1; i >= 0; i--)
Page.Validators.Remove(Page.Validators[i]);
ValidateData();
List<RowData> rowDataList = (List<RowData>)ViewState["GridData"];
if (this.IsValid)
{
foreach (GridViewRow row in this.MyDataGrid.Rows)
{
if (row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow && row.Enabled)
{
RowData dataItem = rowDataList[row.DataItemIndex];
var txtNewValue = row.Cells[COL_NEW_VALUE].FindControl("txtNewValue") as TextBox;
var txtNewDate = row.Cells[COL_NEW_DATE].FindControl("txtNewDate") as TextBox;
if (dataItem != null && txtNewDate != null && txtNewValue != null && !string.IsNullOrEmpty(txtNewValue.Text) && !string.IsNullOrEmpty(txtNewDate.Text))
{
var newValue = double.Parse(txtNewValue.Text);
var newDate = DateTime.Parse(txtNewDate.Text);
dataItem.InfoText = "Value written successfully for " + txtNewDate.Text;
dataItem.ErrorText = string.Empty;
dataItem.EnteredDateCache = string.Empty;
dataItem.EnteredValueCache = string.Empty;
if ((dataItem.Date.HasValue && DateTime.Compare(newDate, dataItem.Date.Value) >= 0) || !dataItem.Date.HasValue)
{
dataItem.Date = newDate;
dataItem.Value = newValue;
}
}
}
}
// save any outstanding changes if valid removed from demo
}
ViewState["GridData"] = rowDataList;
}
private void ValidateData()
{
List<RowData> rowDataList = (List<RowData>)ViewState["GridData"];
foreach (GridViewRow row in this.MyDataGrid.Rows)
{
if (row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow && row.Enabled)
ValidateDataRow(rowDataList, row);
}
}
private void ValidateDataRow(List<RowData> rowDataList, GridViewRow gridViewRow)
{
RowData rowData = rowDataList[gridViewRow.DataItemIndex];
bool valueOK = false;
var txtNewValue = gridViewRow.Cells[COL_NEW_VALUE].FindControl("txtNewValue") as TextBox;
var txtNewDate = gridViewRow.Cells[COL_NEW_DATE].FindControl("txtNewDate") as TextBox;
var labelError = gridViewRow.Cells[COL_NEW_VALUE].FindControl("lblError") as Label;
var labelInfo = gridViewRow.Cells[COL_NEW_VALUE].FindControl("lblStatus") as Label;
labelInfo.Text = string.Empty;
labelError.Text = string.Empty;
rowData.InfoText = string.Empty;
rowData.ErrorText = string.Empty;
rowData.EnteredDateCache = txtNewDate.Text;
rowData.EnteredValueCache = txtNewValue.Text;
if (rowData != null && (!string.IsNullOrEmpty(txtNewValue.Text) || !string.IsNullOrEmpty(txtNewDate.Text)))
{
if (!txtNewValue.Text.IsNumber())
{
rowData.ErrorText = rowData.Name + " must be a number.";
AddCustomValidatorForCell(rowData.ErrorText, gridViewRow, 4);
}
else
{
if (txtNewValue.Text != "100")
{
rowData.ErrorText = rowData.Name + " is invalid.";
AddCustomValidatorForCell(rowData.ErrorText, gridViewRow, 4);
}
else
{
valueOK = true;
}
}
}
}
private void AddCustomValidatorForCell(string errorMessage, GridViewRow gridViewRow, int cellIndex)
{
var labelError = gridViewRow.Cells[cellIndex].FindControl("lblError") as Label;
var divInfoError = gridViewRow.Cells[cellIndex].FindControl("ErrorPanel") as Panel;
labelError.Text = errorMessage;
labelError.ToolTip = errorMessage;
labelError.Attributes.Add("style", "color: red;");
CustomValidator validatePower = new CustomValidator()
{
IsValid = false,
ErrorMessage = errorMessage,
EnableViewState = false,
};
Page.Validators.Add(validatePower);
}
protected void SaveButton_Click(object sender, EventArgs e)
{
SaveData();
this.MyDataGrid.DataSource = ViewState["GridData"];
this.MyDataGrid.DataBind();
}
protected void MyDataGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow)
{
var rowData = e.Row.DataItem as RowData;
if (rowData != null)
{
DataControlFieldCell txtNewDate = (DataControlFieldCell)e.Row.Cells[COL_NEW_DATE];
DataControlFieldCell txtNewValue = (DataControlFieldCell)e.Row.Cells[COL_NEW_VALUE];
e.Row.Cells[1].Text = rowData.Date.HasValue ? rowData.Date.ToString() : string.Empty;
e.Row.Cells[2].Text = rowData.Value.HasValue ? rowData.Value.Value.ToString() : string.Empty;
txtNewValue.Enabled = txtNewDate.Enabled = (canEdit & rowData.Editable);
if (!string.IsNullOrEmpty(rowData.EnteredDateCache))
txtNewDate.Text = rowData.EnteredDateCache;
if (!string.IsNullOrEmpty(rowData.EnteredValueCache))
txtNewValue.Text = rowData.EnteredValueCache;
(e.Row.FindControl("lblStatus") as Label).Text = rowData.InfoText;
(e.Row.FindControl("lblError") as Label).Text = rowData.ErrorText;
//(e.Row.FindControl("ErrorPanel") as Panel).Visible = (!string.IsNullOrEmpty(rowData.InfoText) || !string.IsNullOrEmpty(rowData.ErrorText));
}
}
}
[Serializable()]
private class RowData
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime? Date { get; set; }
public double? Value { get; set; }
public string ValidationRule { get; set; }
public string ErrorText { get; set; }
public string InfoText { get; set; }
public string EnteredDateCache { get; set; }
public string EnteredValueCache { get; set; }
public bool Editable { get; set; }
}
}
public static class StringExtensionMethods
{
public static bool IsNumber(this String str)
{
double Number;
if (double.TryParse(str, out Number)) return true;
return false;
}
}
Looks like I was incorrectly setting the controls incorrectly in the RowDataBound event. This should be:
if (e.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow)
{
var rowData = e.Row.DataItem as RowData;
if (rowData != null)
{
DataControlFieldCell txtNewDate = (DataControlFieldCell)e.Row.Cells[COL_NEW_DATE];
if (!string.IsNullOrEmpty(rowData.EnteredValueCache))
{
var txtNewValue = (e.Row.FindControl("txtNewValue") as TextBox);
txtNewValue.Enabled = txtNewDate.Enabled = (canEdit & rowData.Editable);
txtNewValue.Text = rowData.EnteredValueCache;
}
(e.Row.FindControl("lblStatus") as Label).Text = rowData.InfoText;
(e.Row.FindControl("lblError") as Label).Text = rowData.ErrorText;
}
}
Remove the following lines from SaveData:
(row.FindControl("lblStatus") as Label).Text = dataItem.InfoText;
(row.FindControl("lblError") as Label).Text = dataItem.ErrorText;
Remove the following from ValidateDataRow:
labelInfo.Text = string.Empty;
labelError.Text = string.Empty;
I am assuming that calling the following:
DataControlFieldCell txtNewValue = (DataControlFieldCell)e.Row.Cells[COL_NEW_VALUE];
if (!string.IsNullOrEmpty(rowData.EnteredValueCache))
txtNewValue.Text = rowData.EnteredValueCache;
Will remove the controls from the template column when the data is set (which would be on the invalid value as it is not cleared in the cache) which is why I saw the error when an invalid value was entered.

Sort Order Dropdown in Gridview

I have a Gridview control with two columns: One is ID (a label) and the other is Sort Order (dropdown list). The dropdown is numbered from 1 to n, where n is the number of rows in the Gridview.
For example:
ID Sort Order
001 1
002 2
003 3
004 4
After I change the value in the dropdown list for one of the rows - for example, I'll change the Sort Order dropdown for ID 002 from 2 to 3 - the gridview should be updated like this:
ID Sort Order
001 1
003 2
002 3
004 4
I need the logic to accomplish this within the SelectedIndexChanged event for the dropdown, as well as the code to perform the update to the database.
If i correctly understood your problem then find solution of your problem as below :
Code Behind
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindGrid();
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList objDropDownList = e.Row.FindControl("DropDownList1") as DropDownList;
objDropDownList.DataSource = CustomSorting.GetAll();
objDropDownList.DataTextField = "SOText";
objDropDownList.DataValueField = "SOID";
objDropDownList.DataBind();
HiddenField objHiddenField = e.Row.FindControl("HiddenField1") as HiddenField;
string currSortOrder = (!string.IsNullOrEmpty(objHiddenField.Value) ? objHiddenField.Value :
"0");
objDropDownList.SelectedIndex = objDropDownList.Items.IndexOf(objDropDownList.Items.FindByValue(currSortOrder));
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList objDropDownList = sender as DropDownList;
string test = objDropDownList.SelectedValue;
GridViewRow currRow = objDropDownList.NamingContainer as GridViewRow;
Label objLabel = currRow.FindControl("Label1") as Label;
HiddenField objHiddenField = currRow.FindControl("HiddenField1") as HiddenField;
List<TestClass> lstTestClass = PageData;
if (lstTestClass.Exists(x => x.SortOrder == Convert.ToInt32(test)))
lstTestClass.Find(x => x.SortOrder == Convert.ToInt32(test)).SortOrder =
Convert.ToInt32(objHiddenField.Value);
if (lstTestClass.Exists(x => x.ID == objLabel.Text))
lstTestClass.Find(x => x.ID == objLabel.Text).SortOrder = Convert.ToInt32(test);
PageData = lstTestClass;
BindGrid();
}
protected List<TestClass> PageData
{
get
{
return (Session["_PageData"] == null) ? TestClass.GetAll() : Session["_PageData"] as List<TestClass>;
}
set
{
Session["_PageData"] = value;
}
}
protected void BindGrid()
{
GridView1.DataSource = PageData.OrderBy(x=>x.SortOrder);
GridView1.DataBind();
}
}
public class CustomSorting
{
public int SOID { get; set; }
public string SOText { get; set; }
public static List<CustomSorting> GetAll()
{
return new List<CustomSorting>(){
new CustomSorting(){SOID=1,SOText="1"},
new CustomSorting(){SOID=2,SOText="2"},
new CustomSorting(){SOID=3,SOText="3"},
new CustomSorting(){SOID=4,SOText="4"},
};
}
}
public class TestClass
{
public string ID { get; set; }
public int SortOrder { get; set; }
public static List<TestClass> GetAll()
{
return new List<TestClass>(){
new TestClass(){ID="001",SortOrder=1},
new TestClass(){ID="002",SortOrder=2},
new TestClass(){ID="003",SortOrder=3},
new TestClass(){ID="004",SortOrder=4}
}.OrderBy(x=>x.SortOrder).ToList();
}
}
ASPX changes:
<asp:GridView ID="GridView1" runat="server"
OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("ID")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Sort Order">
<ItemTemplate>
<asp:HiddenField ID="HiddenField1" runat="server" Value='<%#Eval("SortOrder") %>' />
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True"
OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

The problem when loading a web user control dynamicly

The web user control: FilterLabel
<span style=" display:block; float:left; margin:5px; padding: 5px; border: 1px inset #000000; font-family: Tahoma; font-size: small;">
<asp:Label ID="lblFilterDisplay" runat="server" Text="Product/Service: This is a testing"></asp:Label>
<asp:ImageButton ID="btnRemove" runat="server" ImageUrl="~/Images/remove.png" OnClick="btnRemove_Click" />
And the part of behind codes for this web user control:
public event EventHandler RemoveClick;
......
public void btnRemove_Click(object sender, EventArgs e)
{
if (RemoveClick != null)
RemoveClick(this, EventArgs.Empty);
}
Next, the web user control "FilterLabel" will be used in another web user control "FilterList":
<%# Register TagPrefix="uc" TagName="FilterLabel" Src="~/Controls/FilterLabel.ascx" %>
<asp:Panel ID="FilterList" runat="server" Width="100%" GroupingText="Filter List" CssClass="filterList">
</asp:Panel>
And the part of behind codes of this web user control is:
protected override void OnInit(EventArgs e)
{
if (IsPostBack)
{
BindFilters();
}
}
public void BindFilters()
{
List<FilterLabel> filters = Filters;
foreach (FilterLabel filter in filters)
{
FilterList.Controls.Add(filter);
}
}
public List<FilterLabel> Filters
{
get
{
List<FilterLabel> filters = Session["Filters"] as List<FilterLabel>;
if (filters == null)
{
filters = new List<FilterLabel>();
}
return filters;
}
}
public void AddFilter(string filterName, string filterContent, string filterValue = null)
{
FilterLabel filter = LoadControl("~/Controls/FilterLabel.ascx") as FilterLabel;
filter.ID = "Filter";
filter.FilterContent = filterContent;
filter.FilterName = filterName;
filter.Value = filterValue;
filter.RemoveClick += new EventHandler(RemoveFilter);
List<FilterLabel> filters = Filters;
filters.Add(filter);
Session["Filters"] = filters;
BindFilters();
}
private void RemoveFilter(object sender, EventArgs e)
{
//some handling codes
}
So now the problem is the btnRemove_Click event isn't activated when I click the image button "btnRemove".
You should try with bubble event. with your solution you will need on each postback to rebind event handler on each usercontrol for existing filters
public int FilterCount
{
get{
if(ViewState["filter_count"] == 0){
FilterCount = 0;
}
return (int)ViewState["filter_count"];
}
set{
ViewState["filter_count"] = value;
}
}
protected void RecreateFilterControlls()
{
for(int i =0; i < FilterCount; i++){
FilterLabel filter = LoadControl("~/Controls/FilterLabel.ascx") as FilterLabel;
FilterList.Controls.Add(filter);
filter.RemoveClick += new EventHandler(RemoveFilter);
}
}
protected override void OnInit(EventArgs e)
{
if (IsPostBack)
{
RecreateFilterControlls();
}
}
// this is for button which will add new FilterLabel UserControl
protected void AddNewFilter_Click(object sender, EventArgs e)
{
// just create filter
AddFilter(<FilterNameTextBox|combobox>, <FilterContentTextBox>, <filterValue>);
}
public void AddFilter(string filterName, string filterContent, string filterValue = null)
{
FilterLabel filter = LoadControl("~/Controls/FilterLabel.ascx") as FilterLabel;
filter.ID = "Filter";
filter.FilterContent = filterContent;
filter.FilterName = filterName;
filter.Value = filterValue;
filter.RemoveClick += new EventHandler(RemoveFilter);
// increament filter count
FilterCount++;
}
private void RemoveFilter(object sender, EventArgs e)
{
//some handling codes
//remove control which caused this event
FilterList.Controls.Remove(sender); // or you will need to ask for IndexOf(sender);
FilterCount--;
}
the rest will be handled by ViewState it self, so you don't need to bind data back to FilterLabel back

Resources