I think this is a "doh" moment caused by me not having dome WebForms dev for a few years..
I have a repeater which which contains a bunch of checkboxes:
<asp:Repeater EnableViewState="true" ID="IDTypesRepeater" runat="server" OnItemDataBound="IdTypesRepeaterItemDataBound">
<HeaderTemplate/>
<ItemTemplate>
<asp:CheckBox EnableViewState="true" ID="chkIdType" Text="<%# ((KeyValuePair<string,int>)Container.DataItem).Key %>" runat="server" />
<asp:HiddenField ID="idType" Value="<%# ((KeyValuePair<string,int>)Container.DataItem).Value %>" runat="server"/>
<br />
</ItemTemplate>
</asp:Repeater>
I need to get the checkboxes that are selected in the code behind:
foreach (RepeaterItem repeaterItem in IDTypesRepeater.Items)
{
if ( ((CheckBox)repeaterItem.FindControl("chkIdType")).Checked )
{
// Do something
}
}
But on postback, this code isn't working! I know about always databinding a repeater, so I've done this:
protected void Page_Load(object sender, EventArgs e)
{
IDTypesRepeater.DataSource = DocTemplateHelper.GetApplicableIDTypes().Where(type => type.Value != 0);
IDTypesRepeater.DataBind();
}
So this repopulates the repeater, but the Update code never finds any checked checkboxes.. Any ideas?
Bind in the Page_Init event
protected void Page_Init(object sender, EventArgs e)
{
IDTypesRepeater.DataSource = DocTemplateHelper.GetApplicableIDTypes().Where(type => type.Value != 0);
IDTypesRepeater.DataBind();
}
Be sure to use the !Page.IsPostBack method in your pageload.
Otherwise, the Repeater will keep getting reset, and all your checkboxes
will be in there default value (unchecked)
This should fix it. You are binding the control on postback hence losing the values. You can bind it after handling any event to show the updated record.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
IDTypesRepeater.DataSource = DocTemplateHelper.GetApplicableIDTypes().Where(type => type.Value != 0);
IDTypesRepeater.DataBind();
}
}
Related
I'm having a problem trying to find a label control that is inside a GridView.
Please see my codes below:
<asp:GridView ID="MyGridView" runat="server">
<Columns>
<asp:TemplateField HeaderText="Date">
<ItemTemplate>
<asp:TextBox runat="server" ID="txtDate" MaxLength="10" Width="70" />
<asp:ImageButton ID="imgScoreDate" runat="server" ImageUrl="~/images/calendar.gif" />
<ajaxtoolkit:CalendarExtender ID="txtDate_CalendarExtender" runat="server" Enabled="True" Format="MM/dd/yyyy" TargetControlID="txtDate" PopupButtonID="imgDate" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label ID="lblName" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And here is my .cs file:
protected void LoadGridView()
{
//Do something else
foreach (GridViewRow row in MyGridView.Rows)
{
//Tried A
System.Web.UI.WebControls.Label lblName = row.FindControl("lblName") as System.Web.UI.WebControls.Label;
lblName.Text = "Name";
//Tried B
((System.Web.UI.WebControls.Label)row.FindControl("lblName")).Text = "Name";
}
}
I debug this code and it seems to work fine because my breakpoint is being hit each time the debugger runs. It even loops through my foreach block the same count as to how many rows my GridView has.
But I don't understand why my lblName control doesn't get the "Name" text as a value? Am I missing anything here? I tried both //Tried A and //Tried B methods but they both doesn't update my label's text.
Any help would be appreciated!
Thanks! Cheers!
You want to call LoadGridView inside PreRender. Basically, you want to call it after GridView is bound with data.
protected void Page_PreRender(object sender, EventArgs e)
{
LoadGridView();
}
Look at PreRender event of ASP.NET Page Life Cycle.
On your gridview add:
<asp:GridView OnRowDataBound="MyGridView_RowDataBound" ... />
Then define MyGridView_RowDataBound:
void CustomersGridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
Label l = (Label) e.Row.FindControl("lblName");
}
What I think is happening is the control is not recreated server side in its current spot.
try this
on .aspx page
<asp:GridView ID="MyGridView" runat="server"
onrowdatabound="MyGridView_RowDataBound" .../>
code behind ::
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
LoadGridView();
}
}
void LoadGridView()
{
DataTable dt = new DataTable();
// dt= call ur database method to get data
MyGridView.DataSource = dt;
MyGridView.DataBind();
}
protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label lbl_Name = (Label)e.Row.FindControl("lblName");
lbl_Name.Text = "Name";
}
}
cheers!
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="lbShowGroup" CommandName="View" CommandArgument='<%# Eval("Topic") %>'
runat="server" Text="View"></asp:Button>
</ItemTemplate>
</asp:TemplateField>
Code behind:
protected void tblTopics_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "View")
{
Response.Redirect("Group.aspx?Topic=" + e.CommandArgument.ToString());
}
}
Debugging doesn't reach the RowCommand event, but when I change the button control to LinkButton, it works. What's wrong?
Do you databind your grid on postbacks?
You must not bind your grid on postbacks in Page_Load, only when something has changed that causes the GridView to reload data(f.e. Sorting,Paging) and only in the appropriate even-handlers.
So wrap the databinding in a PostBack-check:
protected void Page_Load(Object sender, EventArgs e)
{
if(!IsPostBack)
{
DataBindGrid();
}
}
Another possible reason: Have you disabled ViewState somewhere?
I had the same issue and found out that my problem was in the Master Page where EnableViewState="false".
I changed the Master page to use EnableViewState="True".
And the rowcommand event fired as expected.
I have a LinkButton in aspx page.
<asp:TextBox ID="textBoxNote" runat="server" />
<asp:LinkButton ID="linkButtonUpdateNote" Text="Update" OnClick="ButtonUpdateNoteClicked" runat="server" />
the click event handler has the following code
protected void ButtonUpdateNoteClicked(object sender, EventArgs e)
{
var note = textBoxNote.Text;
}
On Postback textBoxNote.Text is empty. I don't get the posted value. How to get the value?
It seems like you are possibly resetting the value in your Page_Load.
Check that you are using IsPostback check in the Page_Load function. see - http://msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx
private void Page_Load()
{
if (!IsPostBack)
{
DoThisOnce();
}
DoThisOnEachPostback();
}
I have nested repeaters on my aspx page.In the outer repeater I am displaying a list of products and in the inner repeater I am displaying a list of additional options associated with each product.The inner repeater contains a checkbox,textbox,label and other stuff.I would like to find the controls inside the outer repeater when a user selects a checkbox in the inner repeater.In order to handle this I am using the following code.
<asp:Repeater ID="OuterRepeater" runat="server"
onitemdatabound="OuterRepeater_ItemDataBound" >
<ItemTemplate>
<asp:Label ID="CodeLabel" runat="server" Text='<%# Eval("Code") %>'></asp:Label>
<asp:Repeater ID="InnerRepeater" runat="server" OnItemCreated="InnerRepeater_ItemCreated">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="true"/>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
......
.......
</ItemTemplate>
</asp:Repeater>
......
......
</ItemTemplate>
</asp:Repeater>
protected void InnerRepeater_ItemCreated(object sender, RepeaterItemEventArgs e)
{
RepeaterItem ri = (RepeaterItem)e.Item;
if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem
)
{
CheckBox cb = ri.FindControl("CheckBox1") as CheckBox;
cb.CheckedChanged += new EventHandler(CheckBox1_CheckedChanged);
}
}
private void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = (CheckBox)sender;
if (cb.Checked)
{
//do something
}
else
{
//do something
}
}
But the checkedChanged event of the checkbox is not firing for some reason.Also I am not sure how to access the textbox of the outer repeater in the checked changed event of the innter repeater checkbox control.
Could someone please help me with this?
Thanks
It does not fire the CheckedChanged event, since you have declared the event handler as private, You have to make it Protected or Public
Protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
You can access the Textbox control like..
private void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
Textbox textbox1 = (TextBox)checkBox.Parent.FindControl("TextBox1");
String textboxText = textbox1.Text;
}
It doesn't look like you defined an event handler in your markup.
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="true" OnCheckedChanged="CheckBox1_CheckedChanged" />
Muhammad Akhtar's answer helped me a lot today!
I just needed to set a specific ID to my dynamic generated checkboxes inside my reapeater to recover the origin of the event, and do the rest of the processing, and it worked perfectly.
chkAtivo.ID = DataBinder.Eval(e.Item.DataItem, "id").ToString();
Reovered just as the sample.
Cant vote up yet, but thank you.
I'm getting some strange behaviour with viewstate being lost on postback for a .net application using Sitecore. I'm assuming it might be some config variable somewhere but I'm new to Sitecore and don't really know where to start looking.
UPDATE: Sitecore has now gotten back to us with an answer. We had recently added the dtSearch module, and AutomaticDataBind was set to true in the dtSearch.config which overrides the setting in the web config. We've now removed it and it works fine again.
I've made a mini test if that might help. It's two usercontrols on one page, both with a repeater. When updating the viewstate gets lost so even if I'm binding the updated repeater again the data for the other one will be lost.
Usercontrol 1:
<asp:Repeater runat="server" ID="Repeater1" OnItemDataBound="Repeater1_ItemBind">
<ItemTemplate>
<li>
<asp:Literal runat="server" ID="Literal1"></asp:Literal>
</li>
</ItemTemplate>
</asp:Repeater>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<string> myTestList1 = new List<string>();
myTestList1.Add("a");
myTestList1.Add("b");
Repeater1.DataSource = myTestList1;
Repeater1.DataBind();
}
}
protected void Repeater1_ItemBind(object sender, RepeaterItemEventArgs e)
{
Literal Literal1 = (Literal)e.Item.FindControl("Literal1");
Literal1.Text = (string)e.Item.DataItem;
}
Usercontrol 2:
<asp:Repeater runat="server" ID="Repeater2" OnItemDataBound="Repeater2_ItemBind" OnItemCommand="Repeater2_Command">
<ItemTemplate>
<li>
<asp:Literal runat="server" ID="Literal2"></asp:Literal>
<asp:LinkButton ID="Update" CommandName="Update" runat="server">
update
</asp:LinkButton>
</li>
</ItemTemplate>
</asp:Repeater>
private string test = String.Empty;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
test = "a";
Repeater2.DataSource = test;
Repeater2.DataBind();
}
}
protected void Repeater2_ItemBind(object sender, RepeaterItemEventArgs e)
{
char c = (char)e.Item.DataItem;
Literal Literal2 = (Literal)e.Item.FindControl("Literal2");
Literal2.Text = c.ToString();
}
protected void Repeater2_Command(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Update")
{
test = "b";
Repeater2.DataSource = test;
Repeater2.DataBind();
}
}
Does anyone have any ideas what might be going on? Let me know if I need to provide any more information. The most annoying thing is that it was working last week but I have no idea what has changed!
Thanks,
Annelie
Do you have System.Web.UI.WebControls.Repeater in the "typesThatShouldNotBeExpanded" section of your web.config?
I've found that there are definitely some things that don't work with the regular PostBack model in Sitecore... but this Repeater should be OK.
One trouble area is having FieldRenderers inside Repeaters. They don't seem to restore the Item property correctly on Postback.
As far as I can see, this thread describes exactly the same problem, but with DataGrid. See if setting AutomaticDataBind to 'false' in web.config helps.