This is the problem that bothers me for the past few days
I have a page with couple user controls.
On that page, there is a grid. If a user click on a particular row, a control (li) on the user control is shown or hidden based on the condition.
What makes things complicate is the user control and grid grid are all inside the update panel, but another user control is outside updaet panel
In the rowcommand event, I assigned a Session variable, dontshow. Based on the criteria, dontshow variable will be assigned to true or false. Then the control on the user control will be shown or hidden based on dontshow condition
So far, I am encountering the problem.
let's say (li) control was shown, but after the user click gridview, dontshow is set to true. (li) control should be hidden. No it does not. I have to click other button to do postback to make it happen
The same is true for the usercontrol outside the update panel. The logic is similar
Over the past few days, I have found out that I can't set visible property of controls in user control at page_load because that happens after rowcommand event. I moved the code to pre_render event
I even tried to use different control such as placeholder, panel, etc. That still does not work
I also trace the code. The pre_render event comes after row command. dontshow variable is false. The (li) control visible is set to false. However, after rendering, I can still see the control
What should I do?
Below are the snapshot of the codes
Thank you for the help
main.aspx
.....
<%# Register Src="../usercontrol1.ascx" TagPrefix="uctest1" TagName="ctrl1" %>
<%# Register Src="../usercontrol2.ascx" TagPrefix="uctest2" TagName="ctrl2" %>
...
<ctrl1:uctest1runat="server" ID="test1" />
<asp:UpdatePanel ID="updatepantest1" runat="server" UpdateMode="Always">
<ContentTemplate>
<uctest2:ctrl2runat="server" UpdateMode="Conditional" ID="test2" />
....
<asp:GridView ...>
//grid where rowcommand was executed
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
main.aspx code behind
protected void gridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "something")
{
.....
if (x = 1)
session["dontshow"] = true
else
session["dontshow"] = false
}
}
user control aspx (usercontrol1)
....
<ul>
<li id="li1" runat="server">
<asp:label>this is test</asp:label>
</li>
<li >
<asp:label>this is test</asp:label>
</li>
<li >
<asp:label>this is test</asp:label>
</li>
</ul>
....
user control code behind (usercontrol1)
protected void Page_PreRender(object sender, EventArgs e)
{
bool dontshow = false;
if (Session["dontshow"] != null)
{
dontshow = (bool)Session["dontshow"]
}
if (dontshow)
li1.visible = false
else
li1.visible = true
}
user control aspx (usercontrol2)
....
<asp:PlaceHolder ID="placeholder1" runat="server">
<asp:label ID="label1" runat="server"></asp:label>
</asp:PlaceHolder>
....
user control code behind (usercontrol2)
protected void Page_PreRender(object sender, EventArgs e)
{
bool dontshow = false;
if (Session["dontshow"] != null)
{
dontshow = (bool)Session["dontshow"]
}
if (dontshow)
{
label1.visible =false;
}
else
{
label1.visible =true;
label1.Text ="this is test";
}
}
You could do it in your Row command like this
protected void gridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "something")
{
.....
var viewRow = (GridViewRow)(((ImageButton)e.CommandSource).NamingContainer);
HtmlGenericControl li1 = (HtmlGenericControl)viewRow.FindControl("li1");
if (x = 1)
{
session["dontshow"] = true;
li1.Visible = true;
}
else
{
session["dontshow"] = false;
li1.Visible = false;
}
}
}
Or, if you want to hide the control during data bound you could do it like this
protected void gridview_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HtmlGenericControl li1 = (HtmlGenericControl)e.Row.FindControl("li1");
if (dontshow)
li1.visible = false;
else
li1.visible = true;
}
}
Hope this helps :-)
Related
Going back from JSF to ASP.Net I have a problem in following markup:
I get a null pointer exceptin on this.value within the panel component. I even called DataBind() on the panel itself.
<asp:Panel id="pnl" runat="server" visible="<%# this.value != null%>">
<%= this.value.Foo %>
</asp:Panel>
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
if (this.value == null)
return;
this.pnl.DataBind();
}
Must i use an asp control always?
You probably have mistakes here :
You should do inside : <%# this.value.Foo %>
Capital letter : Visible {capital}).
The code inside the panel will still be executed even if the panel is not visible. It will not be rendered into the result but it will be executed. I would recommend that you use control properties and set your values via code behind on controls that are not repeating anything
<asp:Panel id="pnl" runat="server">
<asp:Literal ID="literal" runat="server" />
</asp:Panel>
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
if(this.value != null)
{
pnl.Visible = true;
literal.Text = this.value.Foo;
}
else
{
pnl.Visible = false;
}
}
In my code i added dynamically some text-boxes and labels.
Then by dropdownlist event i want to refresh the page in a way that all the added text-boxes and labels will remove from aspx
how can it be done?
I assume you're using C#.
You can redirect to the current page by doing this from your code-behind:
Response.Redirect(HttpContext.Current.Request.Url.AbsoluteUri);
Add AutoPostBack="True" for the DropDownList
Add an event to DropDownList for SelectedIndexChange
OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"
In the Code-Behind file :
private void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropDownList1.SelectedIndex == 0)
{
Label1.Visible = false;
}
else
{
Label2.Visible = false;
}
}
I got a query regarding adding dynamic buttons with dynamic onclick events on a set of updatepanels.
I've simplified the scenario as the code I have so far is way too long and tied up..I've created a test page with 3 update panels.
In terms of the actual page the first updatepanel will be for the filters which will in turn update the second update panel. 2nd update panel will consist of all the results, depending on filters..this will be a table of buttons.
On the click of any of these buttons on the second update panel, depending on the ID of the button the results will be generated in the last update panel.
The problem I'm facing is tieing in the button click event when the buttons are created.
When I create the button from the onclick from the first update panel, it adds it to the placeholder but the click event does not fire at all.
Here is some code from my testing page.
test.aspx
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" ChildrenAsTriggers="False"
UpdateMode="Conditional">
<ContentTemplate>
<asp:PlaceHolder id="ph2" runat="server"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:PlaceHolder id="ph3" runat="server"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
Codebehind:
public partial class test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Button up2button = new Button();
up2button.ID = "up2button";
ph2.Controls.Add(up2button);
up2button.Click += new EventHandler(up2button_Click); // Not being registered?
AsyncPostBackTrigger trigger1 = new AsyncPostBackTrigger();
trigger1.ControlID = "up2button";
trigger1.EventName = "Click";
UpdatePanel2.Triggers.Add(trigger1);
ScriptManager1.RegisterAsyncPostBackControl(up2button);
UpdatePanel2.Update();
}
protected void up2button_Click(object sender, EventArgs e) { //and not being fired
Button up3button = new Button();
up3button.ID = "up3button";
up3button.Click += new EventHandler(up3button_click);
ph3.Controls.Add(up3button);
AsyncPostBackTrigger trigger1 = new AsyncPostBackTrigger();
trigger1.ControlID = "up3button";
trigger1.EventName = "Click";
UpdatePanel3.Triggers.Add(trigger1);
UpdatePanel3.Update();
}
protected void up3button_click(object sender, EventArgs e) {
}
}
Thankyou for your time.
here's a quick sample, I find on the internet:
I've used a placeholder to hold the dynamically created controls - the button and textboxes on that button's click event.
and the code:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
if (ViewState["Add"] != null)
{
Button add = new Button();
add.Text = "Add";
add.Click += new EventHandler(add_Click);
PlaceHolder1.Controls.Add(add);
}
if (ViewState["textboxes"] != null)
{
int count = 0;
count = (int)ViewState["textboxes"];
for (int i = 0; i < count; i++)
{
textbox textbox_foradd = new TextBox();
textbox_foradd.ID = "textadd" + (i + 1).ToString();
PlaceHolder1.Controls.Add(textbox_foradd);
}
}
}
}
void add_Click(object sender, EventArgs e)
{
int count = 1;
if (ViewState["textboxes"] != null)
{
count += Convert.ToInt32(ViewState["textboxes"]);
}
TextBox textbox_foradd = new TextBox();
textbox_foradd.ID = "textadd" + count.ToString();
PlaceHolder1.Controls.Add(textbox_foradd);
ViewState["textboxes"] = count;
}
protected void Button1_Click(object sender, EventArgs e)
{
Button add = new Button();
add.Text = "Add";
PlaceHolder1.Controls.Add(add);
ViewState["Add"] = 1;
}
Also, you need to give unique ID to each control in case you add multiple of the same control.
Ex:
Add button with id 'ButtonA'
Add another button with id 'ButtonA'
will fail, after the postback your buttons will trigger the event properly, but the action will not do a proper refresh.
Making it looks like it is not refreshing anymore.
Instead generate a unique ID for each control you add dynamically (and save those IDs).
In the postback, recreate those controls and reassign the IDs properly.
Only then will the UI refresh properly.
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);
}
How do I get properties (e.g. Text) with asp.net controls that were created programatically when page loading when IsPostBack parameter is true?
Schema:
creating control (e.g. TextBox box = new TextBox(); box.ID = "BoxID")
display control in page (e.g. SomeControlInPageID.Controls.Add(box))
user see this textbox (with id "BoxID", but we don't have a possibility to get text property use BoxID.Text, because it control was created programatically!) in page & puts in it some text
user click in button (asp:Button) in page and start page reloading process
start Page_Load method & IsPostBack parameter takes the true value
i try to use this code to get Text property in Page_Load method, but it's not work...:
void Page_Load()
{
if (Page.IsPostBack)
{
TextBox box = SomeControlInPageID.FindControl("BoxID") as TextBox;
string result = box.Text;
}
else
{
// creating controls programatically and display them in page
...
}
}
box.Text in this code always takes null value.
The key here is you need to make sure you recreate the dynamic controls each time the page is loaded. Once the controls are created, ASP.NET will be able to fill the posted back values into those controls. I've included a full working example below. Notice I add the control in the OnInit event (which will fire before Page_Load), and then I can read the value back out in the Page_Load event if a postback has occurred.
<%# Page Language="C#" AutoEventWireup="true" %>
<html>
<body>
<form id="form1" runat="server">
<asp:Panel ID="myPanel" runat="server" />
<asp:Button ID="btnSubmit" Text="Submit" runat="server" />
<br />
Text is: <asp:Literal ID="litText" runat="server" />
</form>
</body>
</html>
<script runat="server">
protected void Page_Load(object sender, System.EventArgs e)
{
if(Page.IsPostBack)
{
var myTextbox = myPanel.FindControl("myTextbox") as TextBox;
litText.Text = myTextbox == null ? "(null)" : myTextbox.Text;
}
}
protected override void OnInit(EventArgs e)
{
AddDynamicControl();
base.OnInit(e);
}
private void AddDynamicControl()
{
var myTextbox = new TextBox();
myTextbox.ID = "myTextbox";
myPanel.Controls.Add(myTextbox);
}
</script>
Please have a look into pageLifeCycle of an aspx page. You'll have to add the textbox within the Page_Init handler. Afterwards you may access your textBox in page_load event.
protected void Page_Init(object sender, EventArgs e)
{
TextBox tb = new TextBox();
tb.ID = "textbox1";
tb.AutoPostBack = true;
form1.Controls.Add(tb);
}
protected void Page_Load(object sender, EventArgs e)
{
/// in case there are no other elements on your page
TextBox tb = (TextBox)form1.Controls[1];
/// or you iterate through all Controls and search for a textbox with the ID 'textbox1'
if (Page.IsPostBack)
{
Debug.WriteLine(tb.Text); /// only for test purpose (System.Diagnostics needed)
}
}
hth