Radio Button not firing itemcommand event in repeater - asp.net

I am working on the asp.net custom control in which I am using repeater control to show radio buttons.
I need to fire repeaters ItemCommand event when RadioButton is click.
The problem I faced is RadioButton is not capabel of firing ItemCommend event and it does not have CommendArgument, and CommandName properties.
To accomplish I created asp.net server control, drived i from RadioButton and add CommendArgument, and CommandName properties in it.
I also added a Button in it so that I can call the click event of this button programatically to fire repeaters ItemCommand event.
Now the problem I am facing is I have fired Button's click event but still ItemCommand event is not firing.
Any idea how to gat this thind done?

You can call the repeaters ItemCommand event when the OnCheckedChanged of the radio button is fired.
I think the main problem is you're not sure how to create the arguments expected by ItemCommand, here's an example which I believe will help:
ASPX:
<asp:Repeater ID="rptColors" runat="server" onitemcommand="rptColors_ItemCommand">
<ItemTemplate>
<asp:RadioButton ID="rdbColour" Text='<%# Eval("Color") %>' AutoPostBack="true" runat="server" OnCheckedChanged="Checked" /> <br />
</ItemTemplate>
</asp:Repeater>
Code behind:
public class Colours
{
public string Color { get; set; }
}
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
rptColors.DataSource = new List<Colours> { new Colours { Color = "Red" }, new Colours { Color = "Black" } };
rptColors.DataBind();
}
}
protected void Checked(object sender, EventArgs e)
{
foreach (RepeaterItem item in rptColors.Items)
{
RadioButton rdbColour = item.FindControl("rdbColour") as RadioButton;
if (rdbColour.Text.Equals((sender as RadioButton).Text))
{
CommandEventArgs commandArgs = new CommandEventArgs("SomeCommand", rdbColour.Text);
RepeaterCommandEventArgs repeaterArgs = new RepeaterCommandEventArgs(item, rdbColour, commandArgs);
rptColors_ItemCommand(rdbColour, repeaterArgs);
}
}
}
protected void rptColors_ItemCommand(object source, RepeaterCommandEventArgs e)
{
//Runs when you select the radio button in the repeater
System.Diagnostics.Debugger.Break();
}
}

Related

Change session variable for all clicks except for one button in a page

I have got 10 button/Links in aspx page. I need to maintain a session variable on only ONE button click and for all other 9 click/action I need to change the value in session variable.
How can I get this in a best way, instead of writing in those 9 click actions.
Please suggest
You can re-use the same event for multiple buttons, and check the 'sender' to see which button was clicked.
Markup:
<asp:Button ID="Button1" runat="server" OnClick="GenericButtonClick" Text="Button" />
<asp:Button ID="Button2" runat="server" OnClick="GenericButtonClick" Text="Button" />
CS:
protected void GenericButtonClick(object sender, EventArgs e)
{
Button button = sender as Button;
switch(button.ID)
{
case "Button1":
//Maintain Session Variable
break;
default:
//Change Value in Session Variable
break;
}
}
You then set all your buttons to use the same event handler
I use mostly the command event handler instead of click, so in aspx side, you would have something like this:
<asp:Button ID="Button1" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="true" />
<asp:Button ID="Button2" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="false" />
<asp:Button ID="Button3" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="false" />
And in the back end cs file, there would be only one event handler like this:
protected void DoSomething(object sender, CommandEventArgs e)
{
if (e.CommandArgument.ToString() == "true")
{
// set session
}
}
The benefit of using CommandEventHandler is that even later on you change the button to ImageButton or LinkButton, you don't need to change the event signature, it works for all.
You can make a property in which you can set the session value and you can also get value from this property. I have made it private because it is used only in that page where you need.
private static string SetGetSession
{
set { HttpContext.Current.Session["Mairaj"] = value; }
get { return HttpContext.Current.Session["Mairaj"].ToString(); }
}
Here is how you can use it
protected void btnOne_Click(object sender, EventArgs e)
{
SetGetSession = "Mairaj";
}
protected void btnTwo_Click(object sender, EventArgs e)
{
SetGetSession = "Ahmad";
}
protected void btnTh_Click(object sender, EventArgs e)
{
SetGetSession = "Minhas";
}
If you want it to be used in other pages as well you can make a class and make this property public you will be able to access it everywhere.

Repeater with Buttons doesn't fire OnItemCommand even when DataBind doesn't happen when IsPostBack is true

I've got an image button in a Repeater, which is in a User Control, and I can't get the OnItemCommand event to fire when I click it. It always gives the error: "... Invalid postback or callback argument. Event validation is enabled using ..."
When I change the image button to a link button, it doesn't give me the error, but it still doesn't fire the OnItemCommand function.
I found some other relevant answers (such as How to process events from Buttons inside Repeaters? And what's this EnableEventValidation thing?) but they all say, "Make sure you're data-binding your repeater inside of a if(!Page.IsPostBack) block." I have done that, but it didn't make a difference.
Here's the markup for the repeater:
<asp:Repeater ID="rptExpenses" OnItemDataBound="rptExpenses_ItemDataBound" OnItemCommand="Button_Command" runat="server" >
<ItemTemplate>
<asp:ImageButton ID="ibDelete" ImageUrl="~/Images/delete.png" CommandName="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
Here's some exerpts from the code-behind
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
rptExpenses.DataSource = ExpenseIds;
rptExpenses.DataBind();
}
}
protected void rptExpenses_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem)) {
var ibDelete = (ImageButton)e.Item.FindControl("ibDelete");
ibDelete.CommandArgument = e.Item.DataItem.ToString();
}
}
protected void Button_Command(object sender, EventArgs e) {
var btn = (IButtonControl)sender;
switch (btn.CommandName) {
case "Delete":
//delete it
break;
}
}
Try using this code instead:
<asp:Repeater ID="rptExpenses" runat="server">
<ItemTemplate>
<asp:ImageButton ID="ibRemove" ImageUrl="~/Images/delete.png" runat="server"
CommandName="Remove"
CommandArgument='<%# Container.DataItem %>'
OnCommand="ibRemove_Click"/>
</ItemTemplate>
</asp:Repeater>
And this in the code behind:
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
rptExpenses.DataSource = ExpenseIds;
rptExpenses.DataBind();
}
}
protected void ibRemove_Click(object sender, CommandEventArgs e)
{
var btn = (IButtonControl)sender;
switch (btn.CommandName)
{
case "Remove":
//delete it, use btn.CommandArgument to find id to remove
break;
}
}
If you still receive the ... Invalid postback or callback argument. Event validation is enabled using ... error, it most likely means that you are somewhere re-binding the repeater before the ibRemove_Click(...) event is raised.
I found the reason why this was happening in the answer to this question: Why ItemCommand doesn't fired on My Repeater
Turns out that for some reason the Page's DataBind function was invalidating the repeater's controls without passing through the repeater's OnItemDataBound function a second time.

Radio button doesn't get selected after a post back

I have an item template within repeater:
<ItemTemplate>
<li>
<input type="radio"
value="<%# GetAssetId((Guid) (Container.DataItem)) %>"
name="AssetId"
<%# SelectAsset((Guid) Container.DataItem) %> />
</li>
</ItemTemplate>
I have a method that compares ids and decides whether to check the radio button.
protected string SelectAsset(Guid uniqueId)
{
if (uniqueId == GetSomeId())
return "checked=\"checked\"";
return string.Empty;
}
SelectAsset gets hit, but it doesn't select a radio button on a post back, but it does work if I just refresh the page. What am I doing wrong here?
Answer here: How to display "selected radio button" after refresh? says that it's not possible to achieve, is this really the case?
Thank you
Update
It appears that view state isn't available for simple controls if they don't have a runat attribute. I have solved this by using a custom GroupRadioButton control. Thank you for your help.
I'd suggest using a RadioButtonList:
Page Code
<asp:RadioButtonList RepeatLayout="UnorderedList" OnSelectedIndexChanged="IndexChanged" AutoPostBack="true" ID="RadioRepeater" runat="server" />
<asp:Label ID="SelectedRadioLabel" runat="server" />
Code Behind
if (!Page.IsPostBack)
{
/* example adds items manually
- you could iterate your datasource here as well */
this.RadioRepeater.Items.Add(new ListItem("Foo"));
this.RadioRepeater.Items.Add(new ListItem("Bar"));
this.RadioRepeater.Items.Add(new ListItem("Baz"));
this.RadioRepeater.SelectedIndex = this.RadioRepeater.Items.IndexOf(new ListItem("Bar"));
this.RadioRepeater.DataBind();
}
protected void IndexChanged(object sender, EventArgs e)
{
this.SelectedRadioLabel.Text = string.Format("Selected Item Text: {0}", this.RadioRepeater.SelectedItem.Text);
}
I assume you only need to select one item.
As described in the comments, it even works to access the SelectedItem in the Page_Loadevent handler:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// previous code omitted
}
else
{
string foo = this.RadioRepeater.SelectedItem.Text;
}
}
If you are creating all your controls dynamically at run-time (directly from code), then things are a little different. Here is the code that I used:
Page Code
<form id="form1" runat="server">
</form>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
RadioButtonList rbl = new RadioButtonList();
rbl.AutoPostBack = true;
rbl.SelectedIndexChanged += rbl_SelectedIndexChanged;
rbl.Items.Add("All");
// generate your dynamic radio buttons here
for (int i = 0; i<5; i++)
{
rbl.Items.Add(string.Format("Dynamic{0}", i));
}
form1.Controls.Add(rbl);
if (!Page.IsPostBack)
{
rbl.SelectedValue = "All";
PopulateTextBox(rbl.SelectedValue);
}
}
void rbl_SelectedIndexChanged(object sender, EventArgs e)
{
RadioButtonList foo = (RadioButtonList)sender;
PopulateTextBox(foo.SelectedValue);
}
void PopulateTextBox(string selection)
{
TextBox box = new TextBox();
box.Text = selection;
form1.Controls.Add(box);
}

Handling events from dynamic controls NOT added on Page_Load?

I've read a few articles on here and the web that have informed me that I cannot simply add a new control dynamically to the page, wire it to a handler, and expect it to work.
The solution given each time is that the dynamic controls need to be added to the page on Init each time.
My problem is, my controls are NOT added to the page on init, they are added after ANOTHER postback.
the workflow is this:
Page Loads
User fills in a textbox, clicks a button
Page Posts back, creating dynamic link controls in the button_click event based on the input
User clicks one of those link controls to proceed to the next step.
so if this is the behavior I need to support, is there any way to do this? It has to happen in the button_click of step 2, because the dynamic controls are based on the input the user puts in step 2.
have I painted myself into a corner here? how else could I handle such a workflow?
After you dynamically create a link button, set a flag in your page's view state. On postback, re-create the link button if the flag is set in view state. Here's a demo:
Markup:
<asp:Button runat="server" ID="button1" OnClick="button_Click" Text="Create button A" CommandArgument="A" />
<asp:Button runat="server" ID="button2" OnClick="button_Click" Text="Create button B" CommandArgument="B" />
<asp:PlaceHolder runat="server" ID="placeHolder"></asp:PlaceHolder>
Code-behind:
public partial class Default : System.Web.UI.Page
{
private bool LinkButtonCreated
{
get { return ((bool?)this.ViewState["LinkButtonCreated"]).GetValueOrDefault(); }
set { this.ViewState["LinkButtonCreated"] = value; }
}
private string LinkButtonCommandArgument
{
get { return (string)this.ViewState["LinkButtonCommandArgument"]; }
set { this.ViewState["LinkButtonCommandArgument"] = value; }
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
if (this.LinkButtonCreated)
this.CreateLinkButton(this.LinkButtonCommandArgument);
}
protected void button_Click(object sender, EventArgs e)
{
if (!this.LinkButtonCreated)
{
string commandArgument = ((Button)sender).CommandArgument;
this.LinkButtonCreated = true;
this.LinkButtonCommandArgument = commandArgument;
this.CreateLinkButton(commandArgument);
}
}
private void CreateLinkButton(string commandArgument)
{
LinkButton linkButton =
new LinkButton
{
ID = "linkButton",
Text = "Click me",
CommandArgument = commandArgument,
};
linkButton.Click += this.linkButton_Click;
this.placeHolder.Controls.Add(linkButton);
}
private void linkButton_Click(object sender, EventArgs e)
{
LinkButton linkButton = (LinkButton)sender;
linkButton.Text = "I was clicked! Argument: " + linkButton.CommandArgument;
}
}

How to perform ondatabinding event?

Suppose there is checkBox with id chkSelect and to perform ondatabinding event.How to do that?
You can add AutoPostBack="true" and OnCheckedChanged="chkSelect_CheckChanged" to your chkSelect CheckBox, then add this in your codebehind:
protected void chkSelect_CheckChanged(object sender, EventArgs e)
{
// your code here
}
if you want to perform actions when the CheckBox is checked/unchecked.
Or add OnDataBinding="chkSelect_DataBinding" to your CheckBox and the following in your codebehind:
protected void chkSelect_DataBinding(object sender, EventArgs e)
{
// your code here
}
if you want to use the OnDataBinding event.
I suppose you want to get ondatabinding event method called.
For this your check box should have event declared as:
<asp:CheckBox runat="server" ID="chkSelect" Text="CheckBox to bind" ondatabinding="chkSelect_DataBinding"/>
or
you can also do it Page_init or OnInit method as
protected override void OnInit(EventArgs e)
{
chkSelect.DataBinding += new EventHandler(chkSelect_DataBinding);
base.OnInit(e);
}
Now to let this event fire, you can call
chkSelect.DataBind(); in page_load. This will fire ondatabinding event.

Resources