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
Related
Do web controls ever appear like you are changing their values but actually retain the previous value?
I created a pop-up modal for users to edit an item. When the user clicks edit on an item on the main page, the following sequence happens:
The item's ID is passed to the Page_Load event of the modal page, and is used to populate the page control's with the item's data.
The user changes a value in a control. Ex: Changes text in a TextBox contol.
The user clicks save, triggering the Click event which creates a DataTransferObject with the values in the textboxes, which will be stored.
However, on step 3, the control's new value (TextBox.Text) still holds the value that it orginially had, not the value the user put in.
Add.aspx:
<%# MasterType VirtualPath="../MasterPages/Popup.Master" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:TextBox ID="TextBoxDescription" runat="server"></asp:TextBox>
<telerik:RadButton ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click"/>
</asp:Content>
Add.aspx.cs
//Cannot access the new values here
protected void btnSave_Click(object sender, EventArgs e)
{
//This will print the new text on Create, but the old text on Edit
System.Diagnostics.Debug.WriteLine(TextBoxDescription.Text);
}
//works properly
protected void Page_Load(object sender, EventArgs e)
{
objIDParam = Convert.ToInt64(Request.QueryString["ObjectID"]);
editMode = (objIDParam != 0) ? true : false;
if(editMode)
PopulateFields(objID);
}
//works properly
private void PopulateFields(long objID)
{
MyObject obj = GetObjectByID(objID);
TextBoxDescription.Text = obj.Description;
}
It is worth noting that this popup page is used for both creating items AND editing items. Create works fine (i.e. The item isn't saved with all blanks, but rather the user input). Editing an item will properly pull all that data back in, and let the user edit the fields, however I can't access the changed values in my code.
You need to check for IsPostBack in the Page_Load method.
The Page_Load gets called before the btnSave_Click method, so the TextBoxDescription.Text is getting reset to obj.Description before the btn_Save method runs.
Try returning out of Page_Load if you're posting back:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
objIDParam = Convert.ToInt64(Request.QueryString["ObjectID"]);
editMode = (objIDParam != 0) ? true : false;
if(editMode)
PopulateFields(objID);
}
Have a look at ASP.NET Page Life Cycle Overview for more info.
On my aspx page there is a RadioButtonList and it contains list items named “additions” and “termination”. Also there two gridview “GV_addition” and “GV_termination”. On selecting the radio button “addition”, then the gridview “GV_addition” will be shown. When item “termination” is selected, then the gridview “GV_termination” will be shown.
On radio button changed event, it is working correctly. But my problem is , when I click browser back button, the radio button selection and corresponding grid view not showing correctly. I got issue, “Gv_termination” is showing when radio button “addition” is selected. This issue is showing only when I click browser back button.
Please find my below code
<asp:RadioButtonList ID="RadioButtonList1" runat="server"
onselectedindexchanged="RadioButtonList1_SelectedIndexChanged" AutoPostBack="true">
<asp:ListItem Text="addition" Value="addition"> </asp:ListItem>
<asp:ListItem Text="termination" Value="termination"></asp:ListItem>
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (RadioButtonList1.SelectedIndex == 0)
{
GV_addition.Visible = true;
GV_termination.Visible = false;
}
else
{
GV_termination.Visible = true;
GV_addition.Visible = false;
}
}
I could not understand why the why the radio button selection and corresponding gridview visiblity is not working on the browsers back button event. Can any one help me to solve this issue?
Please try below steps. For me the same scenario worked.
I could see the values are updating correctly, but the updated radio checked states are not updating in to the UI. So I have set it using javacript on the Onload event of a body.
Add the Onload event on the body.
<body onload="setRadioButonStatus()">
and add the following Javascript.
function setRadioButonStatus() {
var rbtn1 = document.getElementById('RadioButton1');
var rbtn2 = document.getElementById('RadioButton2');
if (rbtn1.hasAttribute("checked"))
rbtn1.checked = true;
if (rbtn2.hasAttribute("checked"))
rbtn2.checked = true;
}
Seems like you aren't creating a "default" scenario. You can do this, and tie the logic together more closely by doing something like this on every Page_Load and leaving it out of your event.
protected void Page_Load(object sender, EventArgs e)
{
GV_addition.Visible = RadioButtonList1.SelectedIndex == 0;
GV_termination.Visible = RadioButtonList1.SelectedIndex == 1;
}
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
}
I have a username TextBox and a Label which should update to (V or X) when the TextBox text is changed. The label is updated only if, for example I press a button which automatically refreshes the page.
Here is the code:
<asp:TextBox ID="username" runat="server" OnTextChanged="checkUsername" Width="80%"></asp:TextBox>
<asp:Label ID="usernameCheck" runat="server" CssClass="checkL"></asp:Label>
And the aspx.cs
protected void checkUsername(object sender, EventArgs e)
{
if (username.Text.Length < 3 || username.Text.Length > 15)
{
//---Label = X (in red)
usernameCheck.Text = "\u2715";
}
else
{
if (myBl.checkUsername(Convert.ToString(username)))
{
//---Label = X (in red)
usernameCheck.Text = "\u2715";
}
else
{
//---Label = V (in green)
usernameCheck.Text = "\u2713";
}
}
}
Thanks for any help.
You need to add AutoPostBack="true" to your TextBox. This will cause it to post back and for that server side event to fire.
There are much better ways of doing what you are trying to accomplish though, most of which do not require a full page postback. I would try to make an AJAX call using the javascript change event, and using something like a callback method.
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.
How do I determine if the checkbox is checked or not checked?
Very perplexed why this is not working - it is so simple!
On my web form:
<asp:CheckBox ID="DraftCheckBox" runat="server" Text="Save as Draft?" />
<asp:Button ID="PublishButton" runat="server" Text="Save" CssClass="publish" />
Code behind which runs in the click event for my save button:
void PublishButton_Click(object sender, EventArgs e)
{
if (DraftCheckBox.Checked)
{
newsItem.IsDraft = 1;
}
}
When debugging it never steps into the If statement when I have the checkbox checked in the browser. Ideas?!
I think there maybe some other code affecting this as follows...
In Page_load I have the following:
PublishButton.Click += new EventHandler(PublishButton_Click);
if (newsItem.IsDraft == 1)
{
DraftCheckBox.Checked = true;
}
else
{
DraftCheckBox.Checked = false;
}
newsItem is my data object and I need to set the checkbox checked status accordingly.
When the save button is hit I need to update the IsDraft property based on the checked status of the checkbox:
void PublishButton_Click(object sender, EventArgs e)
{
if (IsValid)
{
newsItem.Title = TitleTextBox.Text.Trim();
newsItem.Content = ContentTextBox.Text.Trim();
if (DraftCheckBox.Checked)
{
newsItem.IsDraft = 1;
}
else
{
newsItem.IsDraft = 0;
}
dataContext.SubmitChanges();
}
}
So, isDraft = 1 should equal checkbox checked, otherwise checkbox should be un-checked. Currently, it is not showing this.
Specify event for Button Click
<asp:Button ID="PublishButton" runat="server" Text="Save" onclick="PublishButton_Click" />
What i can see you have not got a OnClick on your button. So like this:
<asp:CheckBox ID="DraftCheckBox" runat="server" Text="Save as Draft?" />
<asp:Button ID="PublishButton" runat="server" OnClick="PublishButton_Click"
Text="Save" CssClass="publish" />
And then the function should work like it is:
protected void PublishButton_Click(object sender, EventArgs e)
{
if (DraftCheckBox.Checked)
{
newsItem.IsDraft = 1;
}
}
Please replace code as following code..
void PublishButton_Click(object sender, EventArgs e)
{
if (DraftCheckBox.Checked==True)
{
newsItem.IsDraft = 1;
}
}
Try adding onclick="PublishButton_Click" in the button field on the form. And I don't know if it makes a difference, but generated event handlers are protected void.
For me the best solution in the end has been to create 2 separate pages: 1 for editing a news articles & 1 for a new news article. So Ill never then be in the position of a new news data object being created when the page reloads.
Both page return to the article index list page when the save button is pressed and that seems to work with being able to save the state of the draft checkbox and then show the state on the edit page.
The checkbox.checked isn't used in the context you want it to (this is a boolean that if true, will make the checkbox look checked).
What you could do is to use instead a checkboxlist. Then you could do the following:
foreach(Listitem li in CheckBoxList1.Items)
{
if (li.Selected)
{
NewsItem.Isdraft = 1;
}
}