I have a problem with PagedDataSource and UpdatePanel.When I use AsyncPostBackTrigger in my buttons, paging in my page disappear.
Here's asp code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DataList ID="DataListGallery" runat="server" RepeatColumns="3" RepeatDirection="Horizontal" OnItemDataBound="DataListGallery_ItemDataBound" >
<ItemTemplate>
<asp:HiddenField ID="FieldPhoneId" Value='<%# Eval("Phone_InfoID") %>' runat="server" />
<asp:ImageButton ID="btnShop" OnClick="btnShop_Click" ImageUrl="images/cart.gif" CssClass="left_bt_item" title="header=[خريد] body=[ ] fade=[on]" runat="server" />
<asp:ImageButton CssClass="left_bt_item" title="header=[مورد علاقه] body=[ ] fade=[on]" OnClick="btnFavourite_Click" ID="btnFavourite" ImageUrl="images/unfav.png" runat="server" />
.
.
.
Here's C# code(load event):
protected void Page_Load(object sender, EventArgs e)
{
//http://www.aspdotnetfaq.com/Faq/how-to-determine-whether-an-asynchronous-partial-postback-has-occurred-on-page.aspx
// get a reference to ScriptManager and check if we have a partial postback
if (ScriptManager.GetCurrent(this.Page).IsInAsyncPostBack)
{
// partial (asynchronous) postback occured
// insert Ajax custom logic here
}
// enable property is re-creating page controls
else if (!Page.IsPostBack || enable)
{
//enable = false;
if (Page.Request["Page"] != null || Page.Request["Page"] != "")
{
.
.
.
And a button with AsyncPostBackTrigger:
protected void btnFavourite_Click(object sender, ImageClickEventArgs e)
{
// Access to real ImageButton from repeater
ImageButton ib = (ImageButton)sender;
HiddenField hf = (HiddenField)ib.Parent.FindControl("FieldPhoneId");
Favourite objFav = new Favourite(Convert.ToInt32(hf.Value));
Guid userId = objFav.GetUserIdFromUserName(User.Identity.Name);
using (var context = new MobileGalleryEntities())
{
try
{
// Delete favorited
if (objFav.HadFavorited(User.Identity.Name))
{
int phoneInfoId = Convert.ToInt32(Convert.ToInt32(hf.Value));
// Remove favourite
objFav.RemoveFromFavourite(userId);
// Change image
ib.ImageUrl = "~/images/unfav.png";
}
// Add favorite
else
{
// Add phone
objFav.AddToFavourite(userId);
// Change image
ib.ImageUrl = "~/images/favs.gif";
}
}
catch (Exception ex)
{
}
}
}
Here's DataBound event:
protected void DataListGallery_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (User.Identity.IsAuthenticated)
{
try
{
// Get LoginView for access to ImageButton on it.
var loginView = e.Item.FindControl("LoginView1");
ImageButton btnCom = (ImageButton)e.Item.FindControl("btnCompare");
//ImageButton btnFav = (ImageButton)loginView.FindControl("btnFavourite");
ImageButton btnFav = (ImageButton)e.Item.FindControl("btnFavourite");
btnFav.Visible = true;
ImageButton btnShop = (ImageButton)e.Item.FindControl("btnShop");
btnShop.Visible = true;
//HiddenField hf = (HiddenField)loginView.FindControl("FieldPhoneId");
HiddenField hf = (HiddenField)e.Item.FindControl("FieldPhoneId");
List<int> listFav = (List<int>)Session["Fav"];
if (listFav.Contains(int.Parse(hf.Value)))
btnFav.ImageUrl = "~/images/favs.gif";
}
catch(Exception ex)
{
}
}
else
{
ImageButton btnFav = (ImageButton)e.Item.FindControl("btnFavourite");
btnFav.Visible = false;
ImageButton btnShop = (ImageButton)e.Item.FindControl("btnShop");
btnShop.Visible = false;
}
}
When I fire btnFavourite button, paging in my page disapear. but when i use FullPostBack it's work.
Notice that when I use FullPostBack, I re-create controls such as paging control and other control but when I use AsyncPostBackTrigger I didn't re-create controls.
What am I doing?
Thanks.
I have to re-create controls again the same as FullPostBack.
Related
I have a dropdownlist in a usercontrol as shown below
<asp:dropdownlist id="ddlLanguage" runat="server" AutoPostBack="true" EnableViewState="true" onselectedindexchanged="ddlLanguage_SelectedIndexChanged">
</asp:dropdownlist>
my selectedchanged event is not getting fired even once
in code behind
if (!IsPostBack)
{
//dt - is list of languages availbale in DB
//value[0]-contains lang currently to be binded to dropdownlist based
//remaining values (values [1]) to are to be populated to textbox
LoadModuleInfo(dt,values)
}
private void LoadModuleInfo(System.Data.DataTable dtLanguages, string[] values)
{
this.txbxModuleName.Text = values[1];
this.ddlLanguage.DataSource = dtLanguages;
this.ddlLanguage.DataTextField = "language_description";
this.ddlLanguage.DataValueField = "language";
this.ddlLanguage.DataBind();
// set up selections on the screen
this.ddlLanguage.SelectedIndex = this.getIndex(dtLanguages, values[0]);
}
protected void ddlLanguage_SelectedIndexChanged(object sender, System.EventArgs e)
{
//get new values ( values[0] and values[1])
LoadModuleInfo(dtLanguages, values);
}
protected int getIndex(DataTable dt, string recordId)
{
int intCt = 0;
foreach (System.Data.DataRow dr in dt.Rows)
{
if (dr[0].ToString() == recordId)
{
break;
}
else
{
intCt++;
}
}
return intCt;
}
i have wriiten the above code, but selectedchanged event is not fired for dropdownlist control available in USERCONTROL.
Please help.
If you page not refreshed at all .. most probably you have a javascript error in the page
Kindly remove below line from your code and try
this.ddlLanguage.DataValueField = "language";
or
change this too language to language_description
I have a gridview that is being dynamically populated using a custom template, but the command fields are static. Upon clicking the command fields, the controls are understandably lost. This problem doesn't affect me during edit, because once the gridview is rebound, it would know it is in edit mode and create the dynamic edit template fields. But once I make changes to these fields, which are textboxes, I would need to click on the Update command field to instantiate my update method. Upon clicking, the controls are immediately lost, so in my update method I cannot find the controls to which changes have been made. Any ideas how to solve this? I will post code if needed.
The Grid View Template. Here is where the databindings happen upon dynamic generation. Getting the data from the table and reproducing it on the grid view works fine.
public class GridViewTemplate : System.Web.UI.Control, System.Web.UI.ITemplate
{
// static attributes here
// constructor
public GridViewTemplate(DataControlRowType type, string columnName, string categoryID, string itemControl, string editControl, string footerControl, string dataBinds)
{
DataRowType = type; // Header, DataRow,
st_columnName = columnName; // Header name
st_categoryId = categoryID;
if (itemControl != null)
st_itemControl = itemControl.ToUpper(); // Control type for Item Template
if (editControl != null)
st_editControl = editControl.ToUpper(); // Control type for Edit Template
if (footerControl != null)
st_footerControl = footerControl.ToUpper(); // Control type for Footer Template
if (dataBinds != null)
st_dataBinds = dataBinds;
}
public void InstantiateIn(Control container)
{
switch (DataRowType)
{
case DataControlRowType.Header:
{
// Build the header for this column
Label lb_header = new Label();
lb_header.Text = "<b>" + st_columnName + "</b>";
lb_header.ID = st_categoryId;
container.Controls.Add(lb_header);
}
break;
case DataControlRowType.DataRow:
{
if (Regex.IsMatch(st_categoryId,"^(xxI_)")) // item mode
{
if (st_itemControl.Equals(LABEL))
{
// For Label
}
else if (st_itemControl.Equals(TEXTBOX))
{
TextBox dcrt_textbox = new TextBox();
dcrt_textbox.ID = st_categoryId;
dcrt_textbox.Visible = true;
dcrt_textbox.Enabled = false;
dcrt_textbox.DataBinding += new EventHandler(this.TextBox_DataBinding);
container.Controls.Add(dcrt_textbox);
}
else if (st_itemControl.Equals(CHECKBOX))
{
// For checkbox
}
}
else if (Regex.IsMatch(st_categoryId, "^(xxE_)")) // edit mode
{
if (st_editControl.Equals(LABEL))
{
// For label
}
else if (st_editControl.Equals(TEXTBOX))
{
TextBox dcrt_textbox = new TextBox();
dcrt_textbox.ID = st_categoryId;
dcrt_textbox.Visible = true;
dcrt_textbox.EnableViewState = true;
dcrt_textbox.AutoPostBack = false;
dcrt_textbox.ViewStateMode = ViewStateMode.Enabled;
dcrt_textbox.DataBinding += new EventHandler(this.TextBox_DataBinding);
container.Controls.Add(dcrt_textbox);
}
else if (st_editControl.Equals(CHECKBOX))
{
// For checkbox
}
}
}
break;
case DataControlRowType.EmptyDataRow:
// To be implemented when necessary
break;
case DataControlRowType.Pager:
// To be implemented when necessary
break;
case DataControlRowType.Separator:
// To be implemented when necessary
break;
default:
break;
}
}
public void TextBox_DataBinding(Object sender, EventArgs e)
{
TextBox tb_databound = (TextBox)sender;
GridViewRow row = (GridViewRow)tb_databound.NamingContainer;
string RawValue = DataBinder.Eval(row.DataItem, st_columnName).ToString();
tb_databound.Text = RawValue;
}
public void Label_DataBinding(Object sender, EventArgs e)
{
Label lb_databound = (Label)sender;
GridViewRow row = (GridViewRow)lb_databound.NamingContainer;
string RawValue = DataBinder.Eval(row.DataItem, st_columnName).ToString();
lb_databound.Text = RawValue;
}
public void CheckBox_DataBinding(Object sender, EventArgs e)
{
CheckBox cb_databound = (CheckBox)sender; // get the control that raised this event
GridViewRow row = (GridViewRow)cb_databound.NamingContainer; // get the containing row
string RawValue = DataBinder.Eval(row.DataItem, st_columnName).ToString();
if (RawValue.ToUpper().Equals("TRUE"))
{
cb_databound.Checked = true;
}
else
{
cb_databound.Checked = false;
}
}
}
}
The onEdit and onUpdate methods.
protected void onRowEditing(object sender, GridViewEditEventArgs e)
{
gv.EditIndex = e.NewEditIndex;
tableBind(ViewState["table"]); // View state contains the table, which is then passed to a bind method that binds the gridview.
}
protected void onRowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = gv_rebateTable.Rows[e.RowIndex];
// at this point, xxE_tier (a textbox in edit mode) was destroyed
TextBox tb = row.FindControl("xxE_tier") as TextBox;
}
Gridview:
<asp:GridView ID="gv" EnableViewState="true" ViewStateMode="Enabled" OnRowEditing="onRowEditing" OnRowCancelingEdit="onRowCancelingEdit" OnRowUpdating="onRowUpdating" OnRowDeleting="onRowDeleting" EnableModelValidation="true" ShowFooter="true" OnRowCommand="onRowCommand" AutoGenerateColumns="False" runat="server">
<Columns>
<asp:ButtonField Text="Analysis" ButtonType="Button" HeaderText="" ShowHeader="True" />
<asp:CommandField EditText="Edit" ButtonType="Button" HeaderText="" ShowEditButton="True" ShowHeader="True" ValidationGroup="Edit_Group"/>
<asp:CommandField EditText="Delete" ButtonType="Button" HeaderText="" ShowDeleteButton="True" ShowHeader="True" />
</Columns>
</asp:GridView>
I have a TextBox in a repeater that is populated from the database in the ItemDataBound event. When I tried to get the text inside the TextBox in a Button_Click event I found the TextBox.Text empty. How can I get the Text?
foreach (RepeaterItem repeated in repEdit.Items)
{
DropDownList drp = (DropDownList)FindControlRecursive(repeated, "drpdown");
TextBox txt = (TextBox)FindControlRecursive(repeated, "txt");
CheckBox chk = (CheckBox)FindControlRecursive(repeated, "chk");
if (drp != null && !string.IsNullOrEmpty(drp.Attributes["ID"]))
{
loc.GetType().GetProperty(drp.Attributes["ID"].Split('#')[0] + "ID").SetValue(loc, int.Parse(drp.SelectedValue), null);
}
if (txt != null && !string.IsNullOrEmpty(txt.Attributes["ID"]))
{
if (txt.Attributes["ID"].Contains("#int"))
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, int.Parse(txt.Text), null);
}
else if (txt.Attributes["ID"].Contains("#decimal"))
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, decimal.Parse(txt.Text), null);
}
else
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, txt.Text, null);
}
}
if (chk!=null && !string.IsNullOrEmpty(chk.Attributes["ID"]))
{
loc.GetType().GetProperty(chk.Attributes["ID"].Split('#')[0]).SetValue(loc, chk.Checked, null);
}
}
HTML
<asp:Repeater ID="repEdit" runat="server" OnItemDataBound="repEdit_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Visible="false"></asp:Label>
<asp:TextBox ID="txt" runat="server" Visible="false"></asp:TextBox>
<asp:CheckBox ID="chk" runat="server" Visible="false" />
<asp:DropDownList ID="drpdown" runat="server" Visible="false">
</asp:DropDownList>
<br />
</ItemTemplate>
</asp:Repeater>
Here is the itemdatabound event
protected void repEdit_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Label name = e.Item.FindControl("lblName") as Label;
TextBox text = e.Item.FindControl("txt") as TextBox;
CheckBox chk = e.Item.FindControl("chk") as CheckBox;
DropDownList drp = e.Item.FindControl("drpdown") as DropDownList;
Button but = e.Item.FindControl("butEdit") as Button;
//butEdit.Visible = true;
if (but != null)
{
but.Visible = true;
}
if (e.Item.ItemType == ListItemType.Item)
{
KeyValuePair<string, Dictionary<int, string>> kvp = (KeyValuePair<string, Dictionary<int, string>>)e.Item.DataItem;
if (name != null)
{
if (kvp.Key.Contains("#datetime"))
{
return;
}
name.Visible = true;
name.Text = kvp.Key.Split('#')[0].ToString();
}
if (kvp.Key.Contains("#int") || kvp.Key.Contains("#decimal"))
{
text.Visible = true;
text.ID = kvp.Key;
text.EnableViewState = true;
text.Attributes["ID"] = kvp.Key;
text.Text = kvp.Value[0].ToString();
if (kvp.Key.Split('#')[0] == "ID")
{
text.Enabled = false;
}
}
Here is your Repeater. It has a PlaceHolder and Button.
<asp:Repeater ID="rpNotifications" runat="server"
OnItemDataBound="rpNotifications_ItemDataBound">
<ItemTemplate>
<asp:PlaceHolder ID="commentHolder" runat="server"></asp:PlaceHolder>
<asp:Button runat="server" ID="btnComment"
Text="Comment" CssClass="btn blue"
OnClick="btnComment_Click" CommandArgument='<%# Eval("id") %>' />
</ItemTemplate>
</asp:Repeater>
The button has the command argument set as the Id of the data I am binding to it.
Next here is where you need to Bind your Repeater. If you don't Bind it in the Page_Init the resulting values in the dynamically created controls will be lost.
protected void Page_Init(object sender, EventArgs e)
{
rpNotifications.DataSource = {datasource-here}
rpNotifications.DataBind();
}
And here is why (Image from: http://msdn.microsoft.com/en-us/library/ms972976.aspx)
Dynamically Create Control on ItemDataBound
You will need to add the textbox to the placeholder as this is the only way to dynamically assign an ID to the control.
protected void rpNotifications_ItemDataBound(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item
|| e.Item.ItemType == ListItemType.AlternatingItem)
{
Common.Models.Item item = (Common.Models.Item)e.Item.DataItem;
// Create new Control
TextBox txtComment = new TextBox();
txtComment.ID = String.Format("txtComment{0}", item.id.ToString());
// Ensure static so you can reference it by Id
txtComment.ClientIDMode = System.Web.UI.ClientIDMode.Static;
// Add control to placeholder
e.Item.FindControl("commentHolder").Controls.Add(txtComment);
}
}
Get Value On Button Click
Now you need to create the event handler for the button and get the resulting value
protected void btnComment_Click(object sender, EventArgs e)
{
// This is the ID I put in the CommandArgument
Guid id = new Guid(((Button)sender).CommandArgument);
String comment = String.Empty;
// Loop through the repeaterItems to find your control
foreach (RepeaterItem item in rpNotifications.Controls)
{
Control ctl = item.FindControl(
String.Format("txtComment{0}", id.ToString()));
if (ctl != null)
{
comment = ((TextBox)ctl).Text;
break;
}
}
}
Try to get ASP.Net controls using below code
DropDownList drp = (DropDownList)repeated.FindControl("drpdown");
TextBox txt = (TextBox)repeated.FindControl("txt");
CheckBox chk = (CheckBox)repeated.FindControl("chk");
Then you can get values from there respective properties.
I have an UpdatePanel, in it a GridView, and in it a Repeater. There is a button to add comment. This button post backs but id does not run the function code behind. Here is my code
<updatepanel>
<gridview>
<repeater>
<asp:Button ID="kitapVarYorumEkle" runat="server"
CommandArgument='<%#Eval("id") %>'
CommandName='<%# GridView1.Rows.Count.ToString() %>'
Text="Yorum ekle" class="blueButton"
OnClick="kitapVarYorumEkle_Click" />
</repeater>
</gridview>
</updatepanel>
Code inside the js is:
protected void kitapVarYorumEkle_Click(object sender, EventArgs e)
{
kitapVarYorum temp = new kitapVarYorum();
if (Session["id"] != null)
{
temp.uyeId = Convert.ToInt32(Session["id"]);
}
Button btn = (Button)sender;
temp.kitapVarId = Convert.ToInt32(btn.CommandArgument);
string text = "";
GridViewRow row = GridView1.Rows[Convert.ToInt32(btn.CommandName)];
if (row != null)
{
TextBox txt = row.FindControl("txtYorum") as TextBox;
if (txt != null)
{
text = txt.Text;
}
}
temp.icerik = text;
var db = Tools.DBBaglanti();
db.kitapVarYorums.InsertOnSubmit(temp);
db.SubmitChanges();
// Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
I have tried it outside the the controls and it works
Have you tried the ItemCommand approach?
<asp:Button
CommandArgument='<%#Eval("id") %>'
CommandName="yourCommandNameOfChoice"
Text="Yorum ekle"
ID="kitapVarYorumEkle"
class="blueButton" runat="server"
OnClick="kitapVarYorumEkle_Click" />
now add an ItemCommand event for your repeater:
protected void yourRepeater_ItemCommand(object source , RepeaterCommandEventArgs e)
{
switch(e.CommandName)
{
case "yourCommandNameOfChoice":
// Your Code Here
break;
}
}
I am creating a survey page that has a list of questions and answers that can be radiobuttonlists, checkboxlists or textboxes. These controls are added dynamically to a Repeater in its ItemDataBound event using Controls.Add.
I've managed to render the page ok but when I submit the form and iterate over the controls in the repeater to get the selectedvalues of the radiobuttons and textbox values, FindControl returns null. What do I need to do to get get the selected values? I've tried iterating over the RepeaterItems but that returned null too. I've tried different types of FindControl but it never resolves the control types.
It works if I add a declarative DataBinder in the Repeater like this
<asp:Repeater ID="rptSurvey" runat="server" Visible="true" EnableViewState="true" >
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Question") %>
</ItemTemplate>
</asp:Repeater>
However, I want want to dynamically add the controls but in doing this i cant get the selectedvalues when submitting. This is tha main structure of my code...
<html>
<asp:Repeater ID="rptSurvey" runat="server" Visible="true">
</asp:Repeater>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" />
</html>
protected void Page_Load(object sender, EventArgs e)
{
...
if (!IsPostBack)
{
rptSurvey.DataSource = GetQuestions();
rptSurvey.DataBind();
}
...
}
protected void rptSurvey_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
string question = (DataBinder.Eval(e.Item.DataItem, "Question")).ToString();
litQuestion = new Literal();
litQuestion.Text = question;
RadioButtonList rblAnswer = (RadioButtonList)item;
rptSurvey.Controls.Add(rblAnswer);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
...
Dictionary<int, string> answers = new Dictionary<int, string>();
try
{
var list = FindControls(rptSurvey, c => c is RadioButtonList || c is CheckBoxList || c is TextBox);
foreach (Control item in list)
{
QuestionId = int.Parse(Questions.Rows[list.IndexOf(item)][0].ToString());
if (item is TextBox)
{
TextBox txtAnswer = (TextBox)item;
answers.Add(QuestionId, txtAnswer.Text);
}
else if (item is RadioButtonList)
{
RadioButtonList rblAnswer = (RadioButtonList)item;
answers.Add(QuestionId, rblAnswer.SelectedItem.Text);
}
else if (item is CheckBoxList)
{
// Iterate through the Items collection of the CheckBoxList
string cblMultiAnswer = "";
for (int i = 0; i < cblAnswer.Items.Count; i++)
{
if (cblAnswer.Items[i].Selected)
{
cblMultiAnswer += cblAnswer.Items[i].Value + ",";
}
}
answers.Add(QuestionId, cblMultiAnswer);
}
}
bSurvey.BLInsertSurveyAnswers(answers, dateCreated, _userEmail);
}
}
public static List<Control> FindControls(Control parent, Predicate<Control> match)
{
var list = new List<Control>();
foreach (Control ctl in parent.Controls)
{
if (match(ctl))
list.Add(ctl);
list.AddRange(FindControls(ctl, match));
}
return list;
}
you have to create the control tree first (always - not only on non-postbacks). do it in the oninit or onpreload event.
look here: https://web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx