I have a simple checkbox list and I'm using a for statement to retrieve the selected values into one string. This has to be simple, but everything is returning false when it evaluates if it is selected.
ASP Code
<asp:CheckBoxList runat="server" ID="ckblInterests" ClientIDMode="Static" RepeatColumns="2" />
ASP.NET Code:
string interests = "";
for (int i = 0; i < ckblInterests.Items.Count; i++)
{
if (ckblInterests.Items[i].Selected)
{
interests += ckblInterests.Items[i].Value + ", ";
}
}
}
The inside if statement evaluates as false each time it loops through. It does count 10 items in the list correctly. I'm stumped at something so simple. Can someone help me identify what might be causing the if statement to return false?
You have code that's dynamically adding the checkboxes to the list on page load (or some other event). This is resulting in the state of those checkboxes being cleared and re-added on each postback. Your page load should probably have an if(!page.ispostback) around that section so that you aren't clearing the content.
With the Following Code (Mostly yours)
Aspx
<div>
<asp:CheckBoxList runat="server" ID="ckblInterests" ClientIDMode="Static" RepeatColumns="2">
<asp:ListItem>Awesome</asp:ListItem>
<asp:ListItem>Tasty</asp:ListItem>
<asp:ListItem>Terrible</asp:ListItem>
</asp:CheckBoxList>
</div>
<asp:Button runat="server" ID="test" OnClick="test_Click" />
<asp:Label runat="server" ID="label"></asp:Label>
c#
protected void test_Click(object sender, EventArgs e)
{
string interests = "";
for (int i = 0; i < ckblInterests.Items.Count; i++)
{
if (ckblInterests.Items[i].Selected)
{
interests += ckblInterests.Items[i].Value + ", ";
}
}
this.label.Text = interests;
}
I was able to produce the following. This is of course after clicking the button.
Are you binding to a datasource that you have not mentioned?
make sure while binding the checkboxlist in page load you have set this check if (!Page.IsPostBack) { ...bind your data }
this should do the trick
I think you need to check the CHECKED property, not SELECTED.
Related
I have a listview populated from the database. I also have a dynamically calculated value (users inputted postcode relative distance to all database postcode)
I tried adding a label which I can successfully access in the ItemTemplate for the ListView through the ItemDataBound event:
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
if (CategoryList.SelectedIndex == 5)
{
var lb = e.Item.FindControl("lbPostcodeDistance") as Label;
if (!string.IsNullOrEmpty(tbPostcode.Text))
{
lb.Text = "Distance from: " + tbPostcode.Text;
lb.Visible = true;
}
}
}
}
Above works fine, however, I need to dynamically add an actual value to lb.Text.
The value is calculated in my public IEnumerable<...> ListView1_GetData(), here is a snippet of code:
var inRangeWalks = new List<InRangeWalks>();
foreach (var walk in grabAllWalks)
{
double dis = //calculation here
if (dis <= radius)
{
inRangeWalks.Add(new InRangeWalks(dis, walk));
}
}
inRangeWalks.Sort((x, y) => x.DistanceFromPostcode.CompareTo(y.DistanceFromPostcode));
}
return inRangeWalks.Select(x => x.Walk); //ListView only wants walks, thus returned ordered Walks.
The code above works perfectly, but I need to add the dis value to each item in the ItemTemplate. I've been trying to do it using the ItemDataBound event but I am not sure if this is correct, or even possible.
Here is my ItemTemplate:
<ItemTemplate>
<div class="row">
...
<h6><b>Location:</b> <%# Item.Location%>, <%# Item.Postcode%></h6>
<asp:Label ID="lbPostcodeDistance" runat="server" Text="Label" Visible="false"></asp:Label>
</div>
</ItemTemplate>
How else could I show an additional dynamically calculated value, exactly where the label is in the ItemTemplate?
Ok I actually ended up using Rahul's advice in the comments, and made my ListView use my custom data source.
Was a little bit of a pain to get it up and running but it's now working great!
If someone wants to implement their own data structure, just remember on the ASPX page change the ItemType to the new structure i.e. ItemType="MyProject.Folder.ClassName". And then you can access the property with model binding like: text=<%# Item.MyObject.Property %>
I have this checkboxlist that it's items fills with linq datasource now I want to check some of these check boxes programmatically...
this is my checkboxlist:
<asp:CheckBoxList ID="CheckBoxList1" runat="server" DataSourceID="LinqDataSource2" DataTextField="ProjectGroupTitle" DataValueField="ProjectGroupID"></asp:CheckBoxList>
and this is my code trying to check some of these check boxes so far:
for (int i = 0; i < CheckBoxList1.Items.Count; i++)
{
if (CheckBoxList1.Items[i].Text == j.ProjectGroupTitle)
{
CheckBoxList1.Items[i].Selected = true;
}
}
when I checked this piece of code in debug mode I realized that CheckBoxList1.Items.Count value is 0 which is odd as I have multiple value in my database that linq datasource is responsible for fetching them for checkboxlist...
could someone help me fix this code?
Check the Request.Form variables while debugging. And please provide as with more information. (is it an aspx or an ascx code behind. is there any update Panel ...)
try to test your code in page render:-
<asp:CheckBoxList ID="CheckBoxList1" runat="server" DataSourceID="LinqDataSource2" DataTextField="ProjectGroupTitle" DataValueField="ProjectGroupID" OnDataBound="SelectCheckbox"></asp:CheckBoxList>
public void SelectCheckbox(object sender, EventArgs e)
{
for (int i = 0; i < CheckBoxList1.Items.Count; i++)
{
if (CheckBoxList1.Items[i].Text == j.ProjectGroupTitle)
{
CheckBoxList1.Items[i].Selected = true;
}
}
}
My code is:
private void Add_Items()
{
for (int x = 1; x < 53; x++)
{
ListBox1.Items.Add("Item" + x);
ListBox1.DataValueField = "Value" + x;
}
}
None of these items raises SelectedIndexChanged event when clicked.
Please assist.
Make sure autopostback is enabled, like in this examle:
<asp:ListBox ID="listBoxLocation" runat="server" AutoPostBack="True"
OnSelectedIndexChanged="listBoxLocation_SelectedIndexChanged" EnableViewState="True">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
</asp:ListBox>
Or to dynamically populate:
Protected void Button1_Click (object sender, System.EventArgs e)
{
ListBox1.Items.Add(new ListItem("Carbon", "C"));
ListBox1.Items.Add(new ListItem("Oxygen", "O"));
}
From: http://msdn.microsoft.com/en-us/library/14atsyf5%28v=vs.85%29.aspx
First.
The ListBox1.DataValueField should not be set to every item. This property sets the field on the data object (each row) to capture the value from. Here is the MSDN link for this property http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.datavaluefield(v=vs.110).aspx.
Next, I am assuming you have all the front end code wired up something like.
<asp:ListBox ID="ListBox1" OnSelectedIndexChanged="ListBox1_SelectedIndexChanged" runat="server"></asp:ListBox>
This has the selected changed event wired up. However for this control to actually Post the data back you need to provide one more attribute. Add
AutoPostBack="true"
To your control as.
<asp:ListBox ID="ListBox1" OnSelectedIndexChanged="ListBox1_SelectedIndexChanged" AutoPostBack="true" runat="server"></asp:ListBox>
This starts the magic. MSDN for AutoPostBack: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.autopostback(v=vs.110).aspx
Your code is very vague, and im going to make the assumption that your ListBox has not been linked up to a SelectedIndexChanged event in the correct way.
If you are dynamically creating the ListBox link it up as below:
public void initialize()
{
ListBox lb = new ListBox();
lb.SelectedIndexChanged += lb_SelectedIndexChanged;
}
private void lb_SelectedIndexChanged(object sender, EventArgs e)
{
//Do Selected Index Changed Code Here
}
If you have a view/form with the control on, simply make sure that the ListBox's event has been set or naturally it will not trigger.
*EDIT 1
As noted in other answers your control is required to have PostBack set. You should also be checking the PostBack state of your page to ensure you are not redrawing your controls continuously, as this will keep resetting your Dynamically added controls.
I try to create a dynamic table with some textboxes depending on a object List.
Then I add it in an Panel contained in UpdatePanel.
Everything works great, except that some times, the postback is async, and some times, all the page reloads. There is no rule, some times it will work twice before being full postback, and some times more. Can't find a logic with this behaviour.
Here is a piece of my aspx code:
<asp:UpdatePanel ID="udpTableDechets" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="pnlTableDechets" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
Here is a piece of my code behind:
protected override void OnLoad(EventArgs e)
{
generateTableDechets();
base.OnLoad(e);
}
private void generateTableDechets()
{
Table tbl = new Table { ID = "dechets", ClientIDMode = ClientIDMode.Static };
TableRow trDec = new TableRow();
tbl.Controls.Add(trDec);
TableCell tdDecReel = new TableCell();
trDec.Controls.Add(tdDecReel);
TextBox txtDechet = new TextBox { ID = string.Concat("txtDechet_", product.Nom), ClientIDMode = ClientIDMode.Static, AutoPostBack = true };
txtDechet.TextChanged+=new EventHandler(txtDechet_TextChanged);
tdDecReel.Controls.Add(txtDechet);
pnlTableDechets.Controls.Add(tbl);
}
protected void txtDechet_TextChanged(object sender, EventArgs e)
{
// Get the value, and update the object containing values
// Then update labels in table thanks to another method
}
UPDATE 1
Actually, I tried the same in static, and I have exactly the same behaviour.
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox runat="server" AutoPostBack="true" OnTextChanged="txt_TextChanged" />
</ContentTemplate>
</asp:UpdatePanel>
Is it normal for you ? Is it a known bug ? Have I forgive something ?
How can I do to be sure every textChanged request will execute asynchronously.
Thank you in advance for your answers
Update 2
The problem seems to occur when I press Enter key or when I hilight the textbox content to replace it.
Solution
I finally did it thanks to the IPostBackEventHandler Interface (see here).
I manage the event manually, and catch it in the RaisePostBackEvent() method. So here, thanks to the control ID passed in parameter, I can do my stuff.
Thank you for your answers
It is a comman issue while creating a website that contain dynamic controls.
If you want to fire event each time you should call code behind from javascript.
Since javascript is executed each time.
ex.
function SaveClick() {
Page.GetPostBackEventReference(objBtnSave);
__doPostBack("objBtnSave", "OnClick");
}
May be this will resolve your problem.
In static, I made it work adding the ChildrenAsTriggers="true" Property, or specifying an AsyncPostBackTrigger on each dynamic control with the TextChanged event.
But this does not work with my dynamic code.
I am creating a custom view in a SharePoint visual Web Part using ASP.NET (Visual C#) and have a CheckBoxList, and a button.
MarkUp for the List & Button:
<td>
<asp:checkboxlist ID="cblYearLst" runat="server" EnableViewState="true" />
</td>
<td>
<asp:Button ID="btnRefineSearch" Text="Refine Search" runat="server" />
</td>
I add items to the CheckBoxList on PreRender:
if (!IsPostBack)
{
if (LstYears != null)
{
for (int i = 0; i < LstYears.Count(); i++)
{
cblYearLst.Items.Add(new ListItem(LstYears[i], LstYears[i]));
}
}
}
And I call the event Handler for the button on Page_Load:
btnRefineSearch.Click += new EventHandler(this.btnRefineSearch_Click);
All of the CheckBox list-items do not stay selected after the button is clicked. I can retrieve the selected values, but they won't display as selected. When I add the Click event handler for the button in the pre-render event, the data is displayed appropriately but the selected values can no longer be retrieved by my Click event.
Any ideas on what might be causing this behaviour??
Did you try moving the binding of the checkboxlist into the page_load instead of pre_render? Just an idea because it seems like the page is losing selections on postback and you are regenerating the options each time.
UPDATE: I created a quick page and this works correctly. Do you have your viewstate turned off for the entire page in your page directive, or possibly in the web.config? I see you have it enabled on the checkboxlist but maybe there is a global setting throwing you off.
protected void Page_Load(object sender, EventArgs e)
{
btnRefineSearch.Click += new EventHandler(this.btnRefineSearch_Click);
List<string> LstYears = new List<string>();
LstYears.Add("one");
LstYears.Add("two");
LstYears.Add("three");
LstYears.Add("four");
if (!IsPostBack)
{
if (LstYears != null)
{
for (int i = 0; i < LstYears.Count; i++)
{
cblYearLst.Items.Add(new ListItem(LstYears[i], LstYears[i]));
}
}
}
}
private void btnRefineSearch_Click(object sender, EventArgs args)
{
Response.Write(cblYearLst.SelectedValue);
}
I figured out the issue, since I have AutoEventWireUp set to true as Keenan has suggested it should all work if I do it in the page_load.
The problem was that Page_Load was being called twice, and I discovered that this was because I was redirecting the user to the same URL with QueryString parameters. After I made the much needed changes, my code works very well.
+1 Keenan for your help and thank you (#jfmags) for tipping me off by telling me you think it is something else.
:D