How to start a dropdownlist with an empty values?
Does anyone have any suggestions as to how I can get round this
problem, aside from creating a blank manager entry in the table, which
is obviously not ideal!
Many thanks!
ASPX PAGE
<asp:Repeater ID="GeneralRepeater" runat="server"
OnItemDataBound="GeneralRepeater_OnItemDataBound">
<ItemTemplate>
<tr>
<td>
DxPoc:
<asp:DropDownList ID="GeneralDDL" DataTextField="DiagnosisCode"
DataValueField="DiagnosisCode" runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
CODE BEHIND:
protected void GeneralRepeater_OnItemDataBound(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
DropDownList myDDL = (DropDownList)e.Item.FindControl("GeneralDDL");
Diagnosis oDiagnosis = new Diagnosis();
DataView dv = new DataView(oDiagnosis.GetDiagnosis());
myDDL.DataSource = dv;
myDDL.DataTextField = "DiagnosisCode";
myDDL.DataValueField = "DiagnosisCode";
myDDL.DataBind();
}
}
You will want to insert code like this into your ItemDataBound function, after the DDL has been databound:
ListItem LI = New ListItem("(empty item)", "0");
myDDL.Items.Insert(0, LI);
myDDL.SelectedValue = "0";
Use the following:
dropDownList.DataSource = AddHeaderItem
(
list.ToDictionary
(instance => instance.Key.ToString(), instance => instance.Value),
true,
"Please Select an Item..."
);
// Add a header item to a Dictionary ..
public static Dictionary<String, String> AddHeaderItem
(Dictionary<String, String> items, Boolean addHeaderItem,
String headerItemText = "")
{
var headerItem = new Dictionary<String, String>();
if (addHeaderItem)
{
headerItem["-1"] = headerItemText;
}
//else { }
return headerItem.Concat(items).ToDictionary
(item => item.Key, item => item.Value);
}
Are you looking for this?
Alter your listitem by setting AppendDataBoundItems="true"
<asp:DropDownList ID="GeneralDDL" AppendDataBoundItems="true" DataTextField="DiagnosisCode" DataValueField="DiagnosisCode"
runat="server">
<asp:ListItem Text="--Select--" Value=""></asp:ListItem>
</asp:DropDownList>
Related
I have created Checkbox list and Button to store Checked Values in ASP.Net application using C# as follows,
<asp:CheckBoxList ID="CheckBoxList1" runat="server" Width="120px">
</asp:CheckBoxList>
<asp:Button ID="AddCheckedData" Height="25px" runat="server" Text="Add Checked Data"
onclick="AddCheckedData_Click"/>
I have binded CheckBoxList in Code behind as,
public void bindchecklist()
{
B.SFS_CODE = Convert.ToInt32(TxtHQCode.Text);
B.id = 7; //tblparent AND tblchild
ds8 = A.DATA8(B);
CheckBoxList1.DataSource = ds8.Tables[0];
CheckBoxList1.DataTextField = "EMP_NAME";
CheckBoxList1.DataValueField = "EMP_CODE";
CheckBoxList1.DataBind();
}
And the button click event to store the selected values in DataBase as follows,
string selemployee = string.Empty;
foreach (ListItem item in CheckBoxList1.Items)
{
if (item.Selected)
{
selemployee = item.Value;
B.id = 8;//insert into DCR_CHECKED
B.Emp_Code = selemployee;
ds8 = A.DATA8(B);
}
}
Now,i have another button to edit the CheckBoxList Selection.Now,i want to retrieve the data from database and check the checkboxes which are availabe(inserted checkbox values in databse when click save button) in DataBase when Clicking Edit Button.
Please try:
for each (DataRow row in resultTable.Rows)
{
if (Convert.ToBoolean(row["bit_column_name"]))
{
// check box is "1" (checked) in the database
.....
}
}
foreach (DataTable table in ds8.Tables)
{
foreach (DataRow dr in table.Rows)
{
String S = Convert.ToString(dr["EMP_CODE"].ToString());
foreach (ListItem item in CheckBoxList2.Items)
{
if (S == item.Value)
{
item.Selected = true;
}
}
}
}
I've been looking for a way to use my repeater with multiple variables such as Creation date, file path, and parent folder, I was able to data bind to a string list to be able to populate the file path and I have a method that will put text into the labels but it only repeats the first item in the list for all label fields. Is there a way to pass multiple variables to the repeater for each of these fields?
.aspx
<asp:Repeater id="repLinks" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<tr>
<td>
<asp:HyperLink runat="server" NavigateUrl='<%# Container.DataItem.ToString() %>' Text="<%# Container.DataItem.ToString().Split('\\').Last() %>" />
</td>
<td>
<asp:Label ID="CRD" runat="server" Text="Label"></asp:Label>
</td>
<td>
<asp:Label ID="USR" runat="server" Text="Label"></asp:Label>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
.aspx.cs
public List<string> CD = new List<string>();
public List<string> lLinks = new List<string>();
public List<string> folder = new List<string>();
public string root = "";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Welcomes User
string Uname = Environment.UserName;
UserName.Font.Size = 17;
UserName.Text = "Welcome: " + Uname;
Get_Vars();
//Define your list contents here
repLinks.DataSource = lLinks;
repLinks.DataBind();
}
}
protected void Get_Vars()
{
//gives path and constructs lists for directory paths and file links
root = "C:\\Users\\James\\Documents\\Visual Studio 2015\\WebSites";
//adds files to list
foreach (var path in Directory.GetDirectories(#root))
{
foreach (var path2 in Directory.GetFiles(path))
{
lLinks.Add(path2);
CD.Add(File.GetCreationTime(path2).ToString());
//CD.Add(File.GetCreationTime(path2).Date.ToString("yyyy-mm-dd"));
string[] temp = Path.GetDirectoryName(path2).Split(new string[] { "\\" }, StringSplitOptions.None);
folder.Add(temp[temp.Length-1]);
}
}
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
foreach (RepeaterItem item in repLinks.Items)
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
for(int k=0;k<CD.Count;k++) {
var lbl = (Label)item.FindControl("CRD");
//int k = 0;
lbl.Text = CD[k];
}
}
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var lbl = (Label)item.FindControl("USR");
int k = 0;
lbl.Text = folder[k];
k++;
}
}
}
Remove your ItemDataBound event handler. You don't need that just to bind some text to a label. It's better to do that declaratively.
You should encapsulate the data in a model.
public class CD
{
public string Name {get; set;}
public string Link {get; set;
public string Folder {get; set;}
//additional properties about the CD here
}
Then create a list of these, and bind that to your repeater.
List<CD> cds = new List<CD>();
//populate your list with data. Here's manually populating with one
CD cd = new CD
{
Name = "Dark Side of the Moon",
Link = "http://www.google.com/pinkfloyd",
Folder = "C:\\Users\\etc"
};
cds.Add(cd);
repLinks.DataSource = cds;
repLinks.DataBind();
Lastly, strongly type your repeater and then you can access the properties.
<asp:Repeater id="repLinks" runat="server" ItemType="CD" OnItemDataBound="Repeater1_ItemDataBound">
<!-- omit some stuff -->
<%#: Item.Name %>
Don't store related values in unrelated variables. Create an object which represents any given element in your repeater. Something like this:
public class MyObject
{
public string CD { get; set; }
public string Link { get; set; }
public string Folder { get; set; }
}
Use a list of that object as your data source:
public List<MyObject> MyObjects = new List<MyObject>();
And populate that list with your data:
foreach (var path2 in Directory.GetFiles(path))
{
string[] temp = Path.GetDirectoryName(path2).Split(new string[] { "\\" }, StringSplitOptions.None);
MyObjects.Add(new MyObject {
CD = File.GetCreationTime(path2).ToString(),
Link = path2,
Folder = temp[temp.Length-1]
});
}
Bind to the list:
repLinks.DataSource = MyObjects;
repLinks.DataBind();
And in the repeater you can bind to the object's properties:
<%# ((MyObject)Container.DataItem).CD %>
or
<%# ((MyObject)Container.DataItem).Link %>
etc.
Whenever you have a logical grouping of data elements, group them. It becomes a whole lot easier to maintain than trying to keep a bunch of separate variables synchronized.
Ok here is the scenario. I have created a completely data driven Radgrid with only 2 static buttons on the page, Save and Cancel. The Radgrid is created dynamically, as well as all the data in the grid (from MS SQL). Here is the tricky part, I have a template column that will contain a control. The type of control is determined again by the data in SQL. I.e., data is 6, I need to return a RadTextBox populated with data from SQL, 5 = RadComboBox, also populated... you get the jist. I have a total of 50 records, so I have around 50 controls, all populated with data which can change and be saved. That is the hard part. I have been stuck for 2 days trying to figure out how to get to the RadGrids cell level, find the control, determine what type of control it is, retrieve the lastest data from that control and save it back out to the Database. The code works, I just need help finding the controls and saving the data...
I need to hit the Save button, which in turn gets all the data and saves it to db. I cannot show you all my code because the codebehind is close to 600 lines. but I will demonstrate with one.
I am giving the controls IDs based on a unique value from that row, so ID="c" = x where x is the unique value.
page.aspx
<form id="formUnionActivityProtestor" runat="server">
<asp:HiddenField ID="hiCaseId" runat="server" />
<asp:HiddenField ID="hiCaseSequence" runat="server" />
<telerik:RadScriptManager runat="server" ID="RadScriptManager1" ScriptMode="Release">
</telerik:RadScriptManager>
<div id="headDiv">
<h2>Blah blah blah</h2>
<h3>blah zeyblah</h3>
<telerik:RadButton runat="server" ID="btnSaveUA" CausesValidation="true" OnClick="btnSaveUA_Click"
Text="Save Union Activity" Skin="Web20" Font-Size="12px" Width="145" Font-Bold="true">
</telerik:RadButton>
<telerik:RadButton runat="server" ID="btnCancel" OnClientClicking="ReadOnly"
Text="Cancel Changes" Skin="Web20" Font-Size="12px" Width="145" Font-Bold="true">
</telerik:RadButton>
</div>
<hr />
<div id="gridContainer" runat="server">
<asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
</div>
</form>
page.aspx.cs
protected void Page_Init(object sender, System.EventArgs e)
{
radgrid = new RadGrid();
radgrid.ID = "radgrid";
radgrid.PreRender += new EventHandler(radUAGrid_PreRender);
PlaceHolder1.Controls.Add(radgrid);
this.radgrid.NeedDataSource += new GridNeedDataSourceEventHandler(this.grid_NeedDataSource);
radgrid.ItemDataBound += new Telerik.Web.UI.GridItemEventHandler(this.radgrid_ItemDataBound);
radgrid.MasterTableView.DataKeyNames = new string[] { "q_SortValue" };
radgrid.MasterTableView.AutoGenerateColumns = false;
radgrid.MasterTableView.ShowHeader = false;
radgrid.BorderColor = System.Drawing.Color.Gray;
GridBoundColumn boundColumn;
boundColumn = new GridBoundColumn();
boundColumn.ItemStyle.Width = 600;
boundColumn.ItemStyle.CssClass = "prompt";
boundColumn.DataField = "q_Prompt";
radgrid.MasterTableView.Columns.Add(boundColumn);
GridTemplateColumn templateColumn = new GridTemplateColumn();
templateColumn.ItemTemplate = new TemplateColumn("q_QuestionnaireTypeID");
//templateColumn.ItemStyle.Width = 0;
templateColumn.DataField = "q_QuestionnaireTypeID";
templateColumn.UniqueName = "q_QuestionnaireTypeID";
radgrid.MasterTableView.Columns.Add(templateColumn);
boundColumn = new GridBoundColumn();
boundColumn.Display = false;
boundColumn.ItemStyle.CssClass = "hidecol";
boundColumn.DataField = "t_QuestionnaireTypeDescription";
radgrid.MasterTableView.Columns.Add(boundColumn);
}
public partial class TemplateColumn : System.Web.UI.Page ,ITemplate //adding template fields
{
string fieldName = "";
int controlTypeID = 0;
DataTable dt;
int counter = 1;
UnionActivity refMgr = new UnionActivity(Global.ICEConnectionString);
public TemplateColumn(string fieldName)
{
this.fieldName = fieldName;
}
public int getQuestionTypeID(int count)
{
int k = (from DataRow dr in dt.Rows.OfType<DataRow>()
where (int)dr["q_SortValue"] == count
select (Int32)dr["q_QuestionnaireTypeID"]).FirstOrDefault();
return k;
}
public void InstantiateIn(Control container)
{
if (counter == 1)
{
dt = UnionActivityDataTable.dt;
}
controlTypeID = getQuestionTypeID(counter);
if (controlTypeID == 5)
{
int QID = (from DataRow dr in dt.Rows.OfType<DataRow>()
where (int)dr["q_SortValue"] == counter
select (int)dr["q_QuestionnaireInstanceID"]).FirstOrDefault();
int QQID = (from DataRow dr in dt.Rows.OfType<DataRow>()
where (int)dr["q_SortValue"] == counter
select (int)dr["q_QuestionnaireInstanceQuestionID"]).FirstOrDefault();
string answer = (from DataRow dr in dt.Rows.OfType<DataRow>()
where (int)dr["q_SortValue"] == counter
select (string)dr["a_Answer"]).FirstOrDefault();
DataTable dt1;
dt1 = getDropDownList(QID, QQID);
RadComboBox cb = new RadComboBox();
foreach (DataRow row in dt1.Rows)
{
RadComboBoxItem item = new RadComboBoxItem();
item.Text = row["DisplayValue"].ToString();
item.Value = row["DDID"].ToString();
if (answer == item.Text)
{
cb.SelectedValue = item.Value;
}
cb.Items.Add(item);
item.DataBind();
}
string x = (from DataRow dr in dt.Rows.OfType<DataRow>()
where (int)dr["q_SortValue"] == counter
select Convert.ToString((int)dr["a_QuestionnaireInstanceQuestionID"])).FirstOrDefault();
cb.ID = "c" + x;
container.Controls.Add(cb);
}
}
DataTable getDropDownList(int QID, int QQID)
{
DataTable dt2 = new DataTable();
try
{
using (refMgr)
{ //retrieving qicr_QuestionnaireInstanceCaseReferenceID
using (DataTable getDropDownData = refMgr.DynamicDropDownData(QID, QQID))
{
if (getDropDownData != null)
{
dt2 = getDropDownData;
}
}
}
}
catch (Exception ex)
{
}
return dt2;
}
}
after page load I look at the source and this is the insert for the combobox...
<td class="rcbInputCell rcbInputCellLeft" style="width:100%;">
<input name="radgrid$ctl00$ctl22$c12" type="text" class="rcbInput radPreventDecorate" id="radgrid_ctl00_ctl22_c12_Input" value="Kiosk" readonly="readonly" />
</td>
I need to attach a method to the save button, but I dont know the first place to start. Telerik is good about getting the page built dynamically, but not saving the data back out. (or even finding the controls...)
I have seen something like this done for survey generation. The only difference is that it wasn't using a Grid. Is there a reason why you need to use a grid rather than just dynamically building the controls on the page?
I can suggest a way so that you can easily obtain the values from dynamic controls.
You can introduce an interface that all your survey controls need to implement.
interface ISurveyControl
{
// expose some common properties
int QuestionID {get; set;}
object Value {get; set;}
// and others as required
}
Then create an extension for every type of control that you need in your survey
public class SurveyTextBox : RadTextBox, ISurveyControl
{
public int QuestionID {get; set;}
public object Value
{
get { return Text; }
set { Text = value.ToString(); }
}
}
public class SurveyComboBox : RadComboBox, ISurveyControl
{
public int QuestionID {get; set;}
public object Value
{
get { return SelectedValue; }
set { SelectedValue = value.ToString(); }
}
}
Make sure you use these extended controls when building the survey and populate the common properties correctly.
Then all you need is a helper function to find all ISurveyControl controls from a container, regardless of whether it's a grid or a page.
List<ISurveyControl > FindSurveyControls(Control container)
{
// you can use linq to find all ISurveyControl within the container
// you may need to make this recursive as well
}
You can then iterate through the controls on save, knowing that they hold enough information such as the QuestionID and so on.
I have a generated checkboxlist that is generated by selecting options on another checkboxlist:
CheckBoxList typefilter = new CheckBoxList { ID = "typefilter" + CheckBoxList1.Items[i].Text };
typefilter.RepeatDirection = RepeatDirection.Horizontal;
SortedList<int, string> filterValueList = new SortedList<int, string>();
typefilter.DataTextField = "Value";
typefilter.DataValueField = "Key";
typefilter.DataSource = getFilterOptions(int.Parse(CheckBoxList1.Items[i].Value));
typefilter.DataBind();
phSelectedItem.Controls.Add(typefilter);
Now the problem is if I want to give my generated checkboxlist a SelectedIndexChanged, how do I go about doing it?
Edit (After using the suggested handler method, clicking the checkbox will destroy the entire checkboxlist):
Entire method's code
protected void cbl_RentalCategory_SelectedIndexChanged(object sender, EventArgs e)
{
if (cbl_RentalCategory.Items.Count > 0)
{
Label selectedType = new Label { ID = "Title" };
selectedType.Text = "<h3>Rental Items</h3>";
phSelectedItem.Controls.Add(selectedType);
}
for (int i = 0; i < cbl_RentalCategory.Items.Count; i++)
{
if (cbl_RentalCategory.Items[i].Selected)
{
Label selectedType = new Label { ID = "selectedType" + cbl_RentalCategory.Items[i].Text };
selectedType.Text = cbl_RentalCategory.Items[i].Text + "<br/>";
phSelectedItem.Controls.Add(selectedType);
CheckBoxList typefilter = new CheckBoxList { ID = "typefilter" + cbl_RentalCategory.Items[i].Text };
typefilter.RepeatDirection = RepeatDirection.Horizontal;
SortedList<int, string> filterValueList = new SortedList<int, string>();
typefilter.AutoPostBack = true;
typefilter.SelectedIndexChanged += typefilter_SelectedIndexChanged;
typefilter.DataTextField = "Value";
typefilter.DataValueField = "Key";
typefilter.DataSource = getFilterOptions(int.Parse(cbl_RentalCategory.Items[i].Value));
typefilter.DataBind();
phSelectedItem.Controls.Add(typefilter);
Label nextLine = new Label { ID = "nextLine" + cbl_RentalCategory.Items[i].Text };
nextLine.Text = "<br/>";
phSelectedItem.Controls.Add(nextLine);
}
}
}
getFilterOptions():
private SortedList<int, string> getFilterOptions(int typeID)
{
SortedList<int, string> filterValueList = new SortedList<int, string>();
string strConnectionString = ConfigurationManager.ConnectionStrings["SOMEDB"].ConnectionString;
SqlConnection conn = new SqlConnection(strConnectionString);
using (SqlCommand cmd = new SqlCommand("Select * FROM SOMEWHERE WHERE ID=#ID", conn))
{
conn.Open();
cmd.Parameters.AddWithValue("#ID", typeID);
cmd.ExecuteNonQuery();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
filterValueList.Add(int.Parse(reader["ID"].ToString()), reader["InformationHeader"].ToString());
}
conn.Close();
}
return filterValueList;
}
Here is how you can do this.Set Autopostback to true and create selectedindexchanged method. Make sure you run this code only first time when page loads.
if(!IsPostBack){
CheckBoxList typefilter = new CheckBoxList { ID = "typefilter" + CheckBoxList1.Items[i].Text };
typefilter.RepeatDirection = RepeatDirection.Horizontal;
SortedList<int, string> filterValueList = new SortedList<int, string>();
typefilter.AutoPostBack = true;
typefilter.SelectedIndexChanged += typefilter_SelectedIndexChanged;
typefilter.DataTextField = "Value";
typefilter.DataValueField = "Key";
typefilter.DataSource = getFilterOptions(int.Parse(CheckBoxList1.Items[i].Value));
typefilter.DataBind();
phSelectedItem.Controls.Add(typefilter);
}
and here is you selectedindex change method
public void typefilter_SelectedIndexChanged(object sender, EventArgs e)
{
//your code
}
If i correctly understood your problem, you need to dynamically create checkboxlist and this dynamically generated checkboxlist should also support AutoPostBack with SelectedChange Event.
Steps to run Sample :
Step-1 : Create a simple website in Visual Studio
Step-2 : Place below code in default.aspx.cs file, leave using namespace as they are.
Step-3 : Place aspx code in default.aspx file
Expected Output :
A checkbox list will come on default page load.
Select any item of dropdown.
Code will generate seperate checkboxlist (subitem) list for each selection.
Select any item in seperately generated checkboxlist and selected value will be shown in Label on screen.
public partial class _Default : System.Web.UI.Page
{
string[] arrMasterDDLSelItem;
protected void Page_Load(object sender, EventArgs e)
{
if (masterCheckBoxList.SelectedItem != null)
{
arrMasterDDLSelItem = new string[masterCheckBoxList.Items.Count];
ListItem objListItem;
for (int index = 0; index < masterCheckBoxList.Items.Count; index++)
{
objListItem = masterCheckBoxList.Items[index] as ListItem;
if (objListItem.Selected)
arrMasterDDLSelItem[index] = objListItem.Text;
}
if (arrMasterDDLSelItem.Count() > 0)
RecreateControls(arrMasterDDLSelItem);
}
}
protected void typefilter_SelectedIndexChanged(object sender, EventArgs e)
{
CheckBoxList objCheckBoxList = sender as CheckBoxList;
ListItem objListItem;
string selectedItems=string.Empty;
foreach (var item in objCheckBoxList.Items)
{
objListItem=item as ListItem;
if (objListItem.Selected)
selectedItems += " " + objListItem.Text + ",";
}
Label1.Text = selectedItems;
}
private SortedList<int, string> getFilterOptions(string selItem)
{
SortedList<int, string> filterValueList = new SortedList<int, string>();
for (int index = 0; index < 10; index++)
filterValueList.Add(index, "SubItem -" + index.ToString() + " For " + selItem);
return filterValueList;
}
private void RecreateControls(string[] masterSelectedItem)
{
foreach (var item in masterSelectedItem)
{
if (item != null)
{
CheckBoxList typefilter = new CheckBoxList { ID = "typefilter" + item };
typefilter.RepeatDirection = RepeatDirection.Horizontal;
SortedList<int, string> filterValueList = new SortedList<int, string>();
typefilter.AutoPostBack = true;
typefilter.SelectedIndexChanged += new System.EventHandler(typefilter_SelectedIndexChanged);
typefilter.DataTextField = "Value";
typefilter.DataValueField = "Key";
typefilter.DataSource = getFilterOptions(item);
typefilter.DataBind();
ContentPlaceHolder MainContent = (ContentPlaceHolder)this.Master.FindControl("MainContent");
MainContent.Controls.Add(typefilter);
}
}
}
}
ASPX Code :
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content><asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:CheckBoxList ID="masterCheckBoxList" runat="server" AutoPostBack="true">
<asp:ListItem Text="Type-1" Value="1"></asp:ListItem>
<asp:ListItem Text="Type-2" Value="2"></asp:ListItem>
<asp:ListItem Text="Type-3" Value="3"></asp:ListItem>
</asp:CheckBoxList>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Panel ID="pnlDropDownList" runat="server">
</asp:Panel>
</asp:Content>
Apologies code may have optimization scope as written in very limited period to give only idea of solution to your problem. But tested and working fine with above mentioned details.
Note Reference of this example is taken from
http://www.aspsnippets.com/Articles/Creating-Dynamic-DropDownList-Controls-in-ASP.Net.aspx
Is there any specific reason why you are creating CheckBoxList from code behind?
As I understand your requirement is: show a master checkbox list (RentalCategory) and for each selection of the checkbox, show a label (selectedType*) and another checkbox list (typefilter*).
For this kind of requirement I would use a repeater control that has the selectedType Label and typefilter CheckBoxList in the item template, assigning SelectedIndexChanged event handler for typefilter at design time only.
From the codebehind, I'll execute 2 select statements (one on the master table-RentalCategory, another on details table-typefilter with appropriate filter condition: where #ID in (<IDs of selected checkboxes in RentalCategory list>) ) in one go [assumtion: you don't have too much of data]
This will give me a DataSet with 2 DataTables. I'll add 1 DataRelation and use this complete DataSet to bind with master checkbox list as well as repeater (with Row.GetChildRows or CreateChildView).
For understanding the concept check:
http://support.microsoft.com/kb/306154
http://www.aspnettutorials.com/tutorials/controls/nestedrepeaters-csharp/
Sorting works fine, if I use the local IIS in windows, but not working online.. Please help!
Here is the code:
AllowPaging="false" AllowSorting=true
ShowHeaderWhenEmpty="True"
onrowdeleting="gridvwAssessments_RowDeleting"
onselectedindexchanged="gridvwAssessments_SelectedIndexChanged"
onpageindexchanging="gridvwAssessments_PageIndexChanging"
OnRowEditing="EditAssessment" OnRowUpdating="UpdateAssessment" OnRowCancelingEdit="CancelEdit"
onsorting="gridvwAssessments_Sorting" >
<Columns>
<asp:TemplateField ItemStyle-Width="100px" HeaderText="NAME" SortExpression="Res_Name">
<ItemTemplate>
<asp:Label ID="lblFirstName" runat="server" Text='<%# Eval("Res_Name")%>'></asp:Label>
<asp:HiddenField ID="assessmentId" runat="server" Value='<%# Eval("Id")%>' />
</ItemTemplate>
</asp:TemplateField>
CSS:
protected void gridvwAssessments_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = ((DataTable)((GridView)sender).DataSource);
Image sortImage = new Image();
if (dt != null)
{
//Sort the data.
if (Session["Assessment_SortDir"] != null)
{
if (Session["Assessment_SortDir"].ToString() == "ASC")
{
Session["Assessment_SortDir"] = "DESC";
sortImage.ImageUrl = "Images\\Desc.gif";
}
else
{
Session["Assessment_SortDir"] = "ASC";
sortImage.ImageUrl = "Images\\Asc.gif";
}
}
else
{
Session["Assessment_SortDir"] = "ASC";
sortImage.ImageUrl = "Images\\Asc.gif";
}
dt.DefaultView.Sort = e.SortExpression + " " + Session["Assessment_SortDir"].ToString();
gridvwAssessments.DataSource = dt;
gridvwAssessments.DataBind();
int columnIndex = 0;
foreach (DataControlFieldHeaderCell headerCell in gridvwAssessments.HeaderRow.Cells)
{
if (headerCell.ContainingField.SortExpression == e.SortExpression)
{
columnIndex = gridvwAssessments.HeaderRow.Cells.GetCellIndex(headerCell);
}
}
gridvwAssessments.HeaderRow.Cells[columnIndex].Controls.Add(sortImage);
}
}
I think the issue is with dt.Defaultview.Sort.
Using DefaultView has always had me run into sorting issues. I usually try to create a new view instead. You may want to give it a try...
DataView dv = new DataView(dt);
dv.Sort = String.Format("{0} {1}", e.SortExpression, Session["Assessment_SortDir"]);
gridvwAssessments.DataSource = dv;
// or you can use dv.ToTable(...);