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/
Related
I'm learning webforms for my internship and currently things are not going well.
I'm in a project that need to use a web api instead of a database to get the data needed in a system built in webforms.
To simplify my problem lets say I want to bind an object to a dropdownlist.
Here's my class model
namespace BindingDataToADropdownlist
{
public class State
{
public int id;
public string sigla;
public string name;
}
}
Here's the .aspx with a simple dropdownist
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BindingDataToADropdownlist._Default" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:DropDownList ID="CboState" runat="server" Height="56px" Width="129px">
</asp:DropDownList>
</asp:Content>
And here's the code behind
namespace BindingDataToADropdownlist
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
List<State> listStates = new List<State>();
listStates.Add(new State() { id = 33, sigla = "RJ", name = "Rio de Janeiro" });
listStates.Add(new State() { id = 34, sigla = "SP", name = "Sao Paulo" });
CboState.DataTextField = "name";
CboState.DataValueField = "id";
CboState.DataSource = listStates;
CboState.DataBind();
}
}
}
I`m getting the error
"DataBinding: 'BindingDataToADropdownlist.State' does not contain a property with the name 'name' "
If i don't use
CboState.DataTextField = "name";
CboState.DataValueField = "id";
The dropdownlist works but shows BindingDataToADropdownlist.State in both itens as expected.
How can I bind the ID and name correctly?
Using your example, we can populate the drop down list by building and adding the list items manually.
private void AddStatesToDDL()
{
List<State> states = new List<State>();
states.Add(new State { id = 33, sigla = "RJ", name = "Rio de Janeiro" });
states.Add(new State { id = 34, sigla = "SP", name = "Sao Paulo" });
foreach (State state in states)
{
CboState.Items.Add(new ListItem(state.name, state.id.ToString()));
}
}
Only run this code on initial page load to avoid duplicating the items during a post back.
Use System.Web.UI.WebControls.ListItem when giving list for dropdown and you don't want to set which field is for text and value.
private List<ListItem> getItemList()
{
List<ListItem> itemList = new List<ListItem>();
itemList.Add(new ListItem {
Text = "Item1",
Value = "1"
});
itemList.Add(new ListItem
{
Text = "Item2",
Value = "2"
});
itemList.Add(new ListItem
{
Text = "Item3",
Value = "3"
});
return itemList;
}
DropDownList1.DataSource = getItemList();
DropDownList1.DataBind();
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;
}
}
}
}
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 CheckBoxList like this:
<asp:CheckBoxList ID="CBLGold" runat="server" CssClass="cbl">
<asp:ListItem Value="TGJU"> TG </asp:ListItem>
<asp:ListItem Value="GOLDOZ"> Gold </asp:ListItem>
<asp:ListItem Value="SILVEROZ"> Silver </asp:ListItem>
<asp:ListItem Value="NERKH"> NE </asp:ListItem>
<asp:ListItem Value="TALA"> Tala </asp:ListItem>
<asp:ListItem Value="YARAN"> Sekeh </asp:ListItem>
</asp:CheckBoxList>
Now I want to get the value of the selected items from this CheckBoxList using foreach, and put the values into a list.
Note that I prefer the code to be short.
List<ListItem> selected = CBLGold.Items.Cast<ListItem>()
.Where(li => li.Selected)
.ToList();
or with a simple foreach:
List<ListItem> selected = new List<ListItem>();
foreach (ListItem item in CBLGold.Items)
if (item.Selected) selected.Add(item);
If you just want the ListItem.Value:
List<string> selectedValues = CBLGold.Items.Cast<ListItem>()
.Where(li => li.Selected)
.Select(li => li.Value)
.ToList();
foreach (ListItem item in CBLGold.Items)
{
if (item.Selected)
{
string selectedValue = item.Value;
}
}
Good afternoon, you could always use a little LINQ to get the selected list items and then do what you want with the results:
var selected = CBLGold.Items.Cast<ListItem>().Where(x => x.Selected);
// work with selected...
Following suit from the suggestions here, I added an extension method to return a list of the selected items using LINQ for any type that Inherits from System.Web.UI.WebControls.ListControl.
Every ListControl object has an Items property of type ListItemCollection. ListItemCollection exposes a collection of ListItems, each of which have a Selected property.
C Sharp:
public static IEnumerable<ListItem> GetSelectedItems(this ListControl checkBoxList)
{
return from ListItem li in checkBoxList.Items where li.Selected select li;
}
Visual Basic:
<Extension()> _
Public Function GetSelectedItems(ByVal checkBoxList As ListControl) As IEnumerable(Of ListItem)
Return From li As ListItem In checkBoxList.Items Where li.Selected
End Function
Then, just use like this in either language:
myCheckBoxList.GetSelectedItems()
List<string> values =new list<string>();
foreach(ListItem Item in ChkList.Item)
{
if(Item.Selected)
values.Add(item.Value);
}
To top up on #Tim Schmelter, in which to get back the List<int> instead,
List<string> selectedValues = CBLGold.Items.Cast<ListItem>()
.Where(li => li.Selected)
.Select(li => li.Value)
.Select(int.Parse)
.ToList();
If you have a databound checklistbox it does not work to get item(j).Selected, because the control does not have a selected attribute. If you clearSelections i.e. on Load, then apparently it now understands item(j).selected.
Just in case you want to store the selected values in single column seperated by , then you can use below approach
string selectedItems = String.Join(",", CBLGold.Items.OfType<ListItem>().Where(r => r.Selected).Select(r => r.Value));
if you want to store Text not values then
Change the r.Value to r.Text
string s= string.Empty
for (int i = 0; i < Chkboxlist.Items.Count; i++)
{
if (Chkboxlist.Items[i].Selected)
{
s+= Chkboxlist.Items[i].Value + ";";
}
}
In my codebehind i created a checkboxlist from sql db in my Page_Load event and in my button_click event did all the get values from checkboxlist etc.
So when i checked some checkboxes and then clicked my button the first thing that happend was that my page_load event recreated the checkboxlist thus not having any boxes checked when it ran my get checkbox values...
I've missed to add in the page_load event the if (!this.IsPostBack)
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
// db query and create checkboxlist and other
SqlConnection dbConn = new SqlConnection(WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
string query;
try
{
query = "SELECT [name], [mail] FROM [users]";
dbConn.Open();
SqlDataAdapter da = new SqlDataAdapter(query, dbConn);
DataSet ds = new DataSet();
da.Fill(ds);
if (ds.Tables[0].Rows.Count != 0)
{
checkboxlist1.DataSource = ds;
checkboxlist1.DataTextField = "name";
checkboxlist1.DataValueField = "mail";
checkboxlist1.DataBind();
}
else
{
Response.Write("No Results found");
}
}
catch (Exception ex)
{
Response.Write("<br>" + ex);
}
finally
{
dbConn.Close();
}
}
}
protected void btnSend_Click(object sender, EventArgs e)
{
string strChkBox = string.Empty;
foreach (ListItem li in checkboxlist1.Value)
{
if (li.Selected == true)
{
strChkBox += li.Value + "; ";
// use only strChkBox += li + ", "; if you want the name of each checkbox checked rather then it's value.
}
}
Response.Write(strChkBox);
}
And the output was as expected, a semicolon separeted list for me to use in a mailsend function:
bill#contoso.com; jeff#corp.inc; sam#dot.net
A long answer to a small problem. Please note that i'm far from an expert at this and know that there are better solutions then this but it might help out for some.
I like to use this simple method to get the selected values and join them into a string
private string JoinCBLSelectedValues(CheckBoxList cbl, string separator = "")
{
return string.Join(separator, cbl.Items.Cast<ListItem>().Where(li => li.Selected).ToList());
}
I've got a very simple object:
public class DocumentType
{
private int id;
private string name;
public int ID
{
get { return this.id; }
set { this.id = value; }
}
public string Name
{
get { return this.name; }
set { this.name = value; }
}
}
I've got a list of DocumentType objects: List<DocumentType> documentTypes = getDocuments();
I'm working on a custom control where I'm trying to dynamically create a repeater and dynamically bind it to my object list. Here's my code:
private Repeater docList;
docList = new Repeater();
docList.DataSource = documentTypes;
docList.DataBind();
foreach (RepeaterItem repeatItem in docList.Items)
{
// if condition to add HeaderTemplate Dynamically only Once
if (repeatItem.ItemIndex == 0)
{
RepeaterItem headerItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Header);
HtmlGenericControl hTag = new HtmlGenericControl("h4");
hTag.InnerHtml = "Header";
repeatItem.Controls.Add(hTag);
}
// Add ItemTemplate DataItems Dynamically
RepeaterItem repeaterItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Item);
Label lbl = new Label();
// This part is completely broken!
lbl.Text = string.Format("Content: {0} {1} <br />", (DocumentType)repeaterItem.DataItem).ID, repeaterItem.NamingContainer);
repeatItem.Controls.Add(lbl);
// Add SeparatorTemplate Dynamically
repeaterItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Separator);
LiteralControl ltrlHR = new LiteralControl();
ltrlHR.Text = "<hr />";
repeatItem.Controls.Add(ltrlHR);
}
The header and separator work great. I can't figure out how to bind the item template to the current item to get it to display. I know what I have in there right now is completely broken, but I've tried several variations with no luck.
Thanks in advance for any help or pointers in the right direction!
The problem you are having is that you are assuming that the RepeaterItem contains the data. It does not. It contains the information on how to display the individual item. You need to use that index to get back into the data source. I'm not sure if there's a better way, but below is how I got it to work...
List<DocumentType> documentTypes = new List<DocumentType>();
documentTypes.Add(new DocumentType(){ ID=1, Name="Bob"});
documentTypes.Add(new DocumentType() { ID = 2, Name = "Tom" });
documentTypes.Add(new DocumentType() { ID = 3, Name = "Chick" });
Repeater docList = new Repeater();
docList.DataSource = documentTypes;
docList.DataBind();
foreach (RepeaterItem repeatItem in docList.Items)
{
int index = repeatItem.ItemIndex;
DocumentType docType = ((IList<DocumentType>)docList.DataSource)[index];
// if condition to add HeaderTemplate Dynamically only Once
if (index == 0)
{
HtmlGenericControl hTag = new HtmlGenericControl("h4");
hTag.InnerHtml = "Header";
repeatItem.Controls.Add(hTag);
}
// Add ItemTemplate DataItems Dynamically
RepeaterItem repeaterItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Item);
Label lbl = new Label();
// This part is completely broken!
lbl.Text = string.Format("Content: {0} {1} <br />", docType.ID, repeaterItem.NamingContainer);
repeatItem.Controls.Add(lbl);
// Add SeparatorTemplate Dynamically
LiteralControl ltrlHR = new LiteralControl();
ltrlHR.Text = "<hr />";
repeatItem.Controls.Add(ltrlHR);
}
StringBuilder sb = new StringBuilder();
docList.RenderControl(new HtmlTextWriter(new StringWriter(sb)));
Text = sb.ToString();