Dynamically loading usercontrol in updatepanel - c#

So I'm trying to dynamically load a usercontrol into a placeholder in another usercontrol inside a updatepanel.
basically I've got this markup:
<asp:UpdatePanel ID="upPopup" runat="server">
<ContentTemplate>
<UC:Popup runat="server" ID="UC_Popup" />
</ContentTemplate>
</asp:UpdatePanel>
And then this markup inside that usercontrol (Popup):
<div id="modal">
<asp:PlaceHolder ID="phPopupPlaceholder" runat="server"></asp:PlaceHolder>
<asp:Label ID="lblModal" runat="server"></asp:Label>
</div>
In the codebehind of the popup usercontrol I have:
public void Show(UserControl control) {
this.phPopupPlaceholder.Controls.Add(control);
this.lblModal.Text = "Loaded";
}
And I call this show method elsewhere with:
Popup.show(new MyUserControl());
Nothing loads into the placeholder though.
But in the show method I can load regular server-controls fine like this:
this.phPopupPlaceholder.Controls.Add(new Label(){ Text = "Label!" });
Can anyone explain to me why regular controls are loaded fine, but my usercontrol isn't loaded?

Okay, I learned that I HAVE to use LoadControl method apparently, but I don't quite understand why this is necessary :/

Related

Missing page controls when calling SelectedIndexChanged of DropDownList (asp.NET)

Here is my problem :
I have an asp:Panel in which I dynamically create a list of .ascx controls.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Panel runat="server" ID="myPanel">
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
The controls are correctly created. I also have a button calling an "onserverclick" event :
<button runat="server" id="myButton" onserverclick="myButton_Click" type="button" class="button"> My Button </button>
And finally, I created an asp:DropDownList like this one, with a server event triggered on SelectedIndexChanged :
<asp:DropDownList runat="server" ID="myDdl" AutoPostBack="true" OnSelectedIndexChanged="myDdl_SelectedIndexChanged" OnDataBound="myDdl_DataBound"></asp:DropDownList>
In response to the two events (myButton_Click and myDdl_SelectedIndexChanged), I'm trying to parse the child controls of myPanel, like this :
ControlCollection controls = myPanel.Controls;
This is the very first line of code within the two response methods.
When clicking on myButton, all the controls of myPanel are correctly retrieved.
BUT
When calling the SelectedIndexChanged event of myDdl, the only child control retrieved in the ControlCollection is the first one, although I can clearly see them on the webpage.
I would appreciate some help, I'm stuck on this since yesterday :(
Thank you !
EDIT
Here is how I'm creating my controls during the page creation:
while(condition)
{
MyControl newControl = (MyControl)Page.LoadControl("~/Controls/MyControl.ascx");
// Setting MyControl attributes
....
myPanel.Controls.Add(newControl);
}

Refresh ASP.NET ListView from Event handler

So, I have an event that is fired always when a text file is updated. This is the event handler:
private void FileWasChanged()
{
this.runsList.Items.Clear();
runningModels = RunsFile.ReadFile(Constants.active_runs_loc, Constants.run_file_name);
this.runsList.DataSource = runningModels;
this.runsList.DataBind();
this.updatePanel.Update();
}
Within this method I am clearing the ListView (runsList), reading the contents of the file and then binding the new data to the ListView. The updatepanel is then updated. But that does not happen, the page stays static until I press F5. Here's the layout:
<section>
<asp:ScriptManager ID="scriptManager1" runat="server" ></asp:ScriptManager>
<asp:UpdatePanel id="updatePanel" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:ListView ID="runsList" runat="server">
<LayoutTemplate>
<ul>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<asp:Label Text="<%# Container.DataItem %>" runat="server" />
</li>
</ItemTemplate>
</asp:ListView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger controlid="runsList"/>
</Triggers>
</asp:UpdatePanel>
</section>
So I am trying to give the user of the web site real time information from the text file. For example, when I change a line in the text file, that line should be added to the web page. The event itself works fine (tested with break points and console project), but for some reason the async update does not do anything.
I tried to look for similar problems, but everyone is using a button for the asyncpostbacktrigger. However, I am very new to C# so I may be misunderstanding how UpdatePanel and ListView DataBind work.
Any help appreciated!
Cheers,
Tetsii
Edit: The FileWasChanged is a handler that is called from FileSystemWatcher OnChanged event. The handler updates the view if called from Page_Load or an async button trigger.

UpdatePanel Questions

I have an update panel that lives in a control that lives on a masterpage. Is it possible to access the updatepanel and cause it to fire in the code-behind of another aspx page that this control is added to at run-time?
There is one case where a button is clicked on page X, and when that button is clicked, I need the update-panel to run. I have tried this so far with no luck:
Code-Behind
udp = FindControl("udpWishlist") as UpdatePanel;
if (udp != null){
udp.Update();
}
Snippet from control of the UpdatePanel I'm trying to use
<!--update wishlist on cartadd-->
<asp:UpdatePanel ID="udpWishlist" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:LinkButton ID="lbwishlist" runat="server" href="/wishlist.aspx"></asp:LinkButton>
</ContentTemplate>
<Triggers>
</Triggers>
</asp:UpdatePanel>
Well, you can create a public Method inside the user control, like this:
public void Update()
{
udpWishlist.Update();
}
Inside the page that contains the UserControl:
YourUserControlType uc = (YourUserControlType)Page.FindControl("YourUserControlID");
uc.Update();
Since the update panel lives in another .aspx, it's out of scope for FindControl(). You may be able to do something like:
udp = this.Page.Master.FindControl("udpWishlist") as UpdatePanel;

change masterpage image src from page in update panel C#

I have a master page that contains an image as follow:
<asp:Image ID="imgCompanyLogo" runat="server" ImageUrl="image path" />
and in a child page I want to edit the property ImageUrl as follow:
Image imgCompanyLogo = (Image)Page.Master.FindControl("imgCompanyLogo");
imgCompanyLogo.ImageUrl = ResolveUrl("~/images/CompanyLogo/Logo.png");
and it doesn't give me an exception, but it doesn't change anything.
Note: I have an UpdatePanel in the child page.
Since the image is sitting outside of the UpdatePanel, server side changes will not be executed on the image after a partial postback. Your only option is to inject JavaScript into the page and change the image URL.
Use the ScriptManager.RegisterStartupScript Method to inject JavaScript after the partial postback.
Something like the following will work for you:
C#
protected void btnPostback_Click(object sender, EventArgs e)
{
imgCompanyLogo.ImageUrl = ResolveUrl("~/images/CompanyLogo/Logo.png");
ScriptManager.RegisterStartupScript(btnPostback,this.GetType(), "myScript", "ChangeImage('" + ImageUrl + "');",false);
}
JavaScript
function ChangeImage(imgURL) {
//make sure the ID of the image is set correctly
document.getElementById('imgCompanyLogo').src = imgURL;
}
Wrap image by UpdatePanel with UpdateMode="Always"
Master Page:
<asp:UpdatePanel runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Image runat="server" ID="Image1" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
public void SetImageUrl(string url)
{
Image1.ImageUrl = url;
}
Child Page:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Button Text="Click Me" runat="server" OnClick="UpdateImage" />
</ContentTemplate>
</asp:UpdatePanel>
protected void UpdateImage(object sender, EventArgs e)
{
((Main)Master).SetImageUrl("~/Images/0306d95.jpg");
}
The code above works well for me.
Have a look at Sys.WebForms.PageRequestManager Class. Define handler in javascript and may change the image source.
If your code is being run after an async postback (per your UpdatePanel) then changes to anything outside the UpdatePanel will not be rendered. Content in the master page would definitely seem to qualify.
If this is what you're trying to do, this model won't really work. You will need to use some client script to effect changes to already-rendered content when working with this model.
An UpdatePanel is a construct to identify an area that's updated through ajax. The page is not actually reloaded. So an postback can never change content that's outside of the UpdatePanel (or control bound to that panel) that sourced it.
Here's a basic implementation (using jQuery). Add a hidden field to pass the new source to the client. This must be inside the UpdatePanel. Change this value from the server when you want the image to update with new_image_src.Value=ResolveUrl(...);
<asp:HiddenField ClientIdMode="Static" runat="server" id="new_image_src"
value="" EnableViewState="false">
Give your image a static id too to make life easier:
<asp:Image ClientIdMode="Static" runat="server" id="dynamic_image" ImageUrl="..." >
Add javascript to the page (should NOT be in the UpdatePanel):
function updateImage() {
var new_src=$('#new_image_src');
if (new_src) {
$('#dynamic_image').attr('src',new_src);
/// erase it - so it won't try to update on subsequent refreshes
new_src.val('');
}
}
$(document).ready(function() {
/// adds an event handler after page is refreshed from asp.net
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(updateImage);
});
This wouldn't be difficult to do without jquery either but seems more common than not these days.

ASP.NET: Custom Control Reloads Whole Page

I'm working on a ASP.NET site with C# code.
Now the trouble starts when I create a custom control programmatically. The control displays in a panel, but when I click one of the buttons of the control it does nothing. If I click them twice, the user control disappears.
Using the debugger, I found that it's doing a postback, which is strange because I tried using buttons and setting the usesubmitbehavior to false; it's still sending postbacks.
Here is where the control is inserted on the default.aspx file
<asp:UpdatePanel runat="server" ID="contentHolderUpdatePanel"
UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel runat="server" ID="contentPanel">
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Here is the ASPX from ListadoAuditoria of the control.
<asp:UpdatePanel runat="server" ID="auditorTableUpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Table runat="server" ID="auditorTable" BorderWidth="0" Width="100%">
<asp:TableHeaderRow HorizontalAlign="Center">
<asp:TableHeaderCell>Button
</asp:TableHeaderCell>
</asp:TableHeaderRow>
</asp:Table>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel runat="server" ID="formHolderUpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label runat="server" ID="testLabel" Text="bbbbbbbbbbbbb" ></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
The method that the button invokes should change the text of the label testLabel from "bbbbbbbbbbbbb" to "aaaaaaaaaaa". Obviously I'm doing an auditorTableUpdatePanel.Update() after I modify the text.
The control CS
protected void Page_Load(object sender, EventArgs e)
{
loadAudits();
}
public void loadAudits()
{
for(int i=0;i<10;++i)
{
TableRow row = new TableRow();
TableCell cell1 = new TableCell();
ImageButton deleteButton = new ImageButton();
deleteButton.ImageUrl = "~/image.gif";
deleteButton.Click += generateNewPart;
deleteButton.EnableViewState = true;
deleteButton.ID = i.ToString();
cell1.Controls.Add(deleteButton);
row.Cells.Add(cell1);
auditorTable.Rows.Add(row);
}
}
public void generateNewPart(object sender, EventArgs e)
{
tumadre.Text = "aaaaaaaaaaaa";
formHolderUpdatePanel.Update();
}
And here is the code when I generate the control and insert it into the panel:
Panel panel = (Panel)Page.FindControl("contentPanel");
UpdatePanel updatePanel = (UpdatePanel)Page.FindControl("contentHolderUpdatePanel");
ListadoAuditorias listadoAuditorias = (ListadoAuditorias)LoadControl("~/CargaDeAuditoria/ListadoAuditorias.ascx");
panel.Controls.Add(listadoAuditorias);
updatePanel.Update();
I looked over the Internet and didn't found anything.
I'm not sure where exactly the code to dynamically add the controls is, but it must be called on EVERY postback to re-add the controls. You can't just add it once and forget about it. When you postback, the page will re-render with the markup in your aspx page (which does not have your dynamic controls, obviously). The values from the dynamically added controls will still be in ViewState, but the controls will not be re-rendered.
I'm not entirely sure what I'm looking at; I don't know if the "code of the control" is the code for the ListadoAuditorias control that you're loading. If so, I didn't notice any buttons.
So I could be wrong here, but the first thing that pops out at me is that it looks like you're loading the ListadoAuditorias control and then adding it to a normal Panel control. If one of the controls inside of ListadoAuditorias triggers a postback, and it's not contained within an UpdatePanel, then yes, I'd expect the page to do a postback and reload, unless you have specified the ChildrenAsTriggers and UpdateMode properties to be something other than their default values (I think). So I would just suggest that you take a look at where you are adding your controls. Make sure that they're contained within an UpdatePanel, if that's what your intention is.
Also, note that the UseSubmitBehavior property of the Button control does not prevent the button from initiating a postback. That property only determines whether the button gets rendered as <input type="submit" /> or <input type="button" />. In the latter case (when you set UseSubmitBehavior to false) the control still renders javascript in the HTML element's onclick attribute to cause a postback.
EDIT: I've amended my explanation regarding UpdatePanel control to mention the ChildrenAsTriggers and UpdateMode properties.

Categories

Resources