change masterpage image src from page in update panel C# - 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.

Related

What is the correct way to put multiple controls inside update panel?

I have one registration form which contains 3 to 4 dropdown controls and 2 datepickers and now when dropdown controls value are selected(selectedindex change are fired)
then i dont want my page to postback.
I have use update panel to stop this behaviour of post like below:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<%--Update Panel for date picker%>
<asp:UpdatePanel ID="UpdatePanelDatepicker" runat="server">
<ContentTemplate>
<telerik:RadDatePicker ID="rdpDate1" runat="server">
</telerik:RadDatePicker>
</ContentTemplate>
</asp:UpdatePanel>
<%--Update Panel for Dropdown--%>
<asp:UpdatePanel ID="updatepaneldata" runat="server">
<ContentTemplate>
<telerik:RadComboBox ID="ddlCountry" runat="server">
</telerik:RadComboBox>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</asp:UpdatePanel>
So i just wanted to ask that is this correct way to put multiple controls under update panels??
Subscribe to ajax event of initializeRequest on client-side. In this event we can cancel an ajax postback if we need to.
The initializeRequest method is raised before processing of the asynchronous request starts. You can use this event to cancel a postback.
In this event, we will check if an async postback is being initiated due to ddlCountry, and if yes then we cancel the ajax post back so no post back occurs.
To solve your problem just do the following : Add following JavaScript to your aspx page. In code below, the pageLoad method is automatically called by ASP.Net Framework on client-side when browser loads the page and after all scripts have been loaded as well as all client-side objects created.
JavaScript to cancel combobox post back
<script type="text/javascript">
function pageLoad()
{
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CancelComboBoxPostback);
}
function CancelComboBoxPostback(sender, args)
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'ddlCountry') {
args.set_cancel(true);
}
}
</script>
The following is only a recommendation and not a part of the solution to your specific problem: Also, I would recommend to stay away from nested update panels as this can cause unexpected results if developer is not aware of how nested update panels work. In your situation, a single update panel should suffice as in markup below instead of nested update panels that you have used in your original markup.
Markup without nested update panels
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<telerik:RadDatePicker ID="rdpDate1" runat="server">
</telerik:RadDatePicker>
<telerik:RadComboBox ID="ddlCountry" runat="server">
</telerik:RadComboBox>
</ContentTemplate>
</asp:UpdatePanel>
Honestly, the UpdatePanel I find is more trouble than it is worth.
UpdatePanel controls are a central part of Ajax functionality in
ASP.NET. They are used with the ScriptManager control to enable
partial-page rendering. Partial-page rendering reduces the need for
synchronous postbacks and complete page updates when only part of the
page has to be updated. Partial-page rendering improves the user
experience because it reduces the screen flicker that occurs during a
full-page postback and improves Web page interactivity.
I often find the controls implementation causes more problems then it is worth. So I often implement my own Ajax services, to handle such logic. You can do this the old school way, quite easy.
// Create .aspx page, to be our service.
public class ControlUpdateService
{
protected void Page_Load(object sender, EventArgs e)
{
// Use an approach to determine which control type, and model to build.
// You would build your object, then use Newtonsoft.Json, to serialize, then
// return the object, via Response.End(object).
}
}
Then your page would Ajax the data, hit the service, then build your control via the .success in the Ajax call. If you do this approach, you commit to saving your data via Ajax as well. Keep that in mind. As I was answering this question, I can't help but feel your problem actually stems from the control doing an AutoPostback. Which you can actually disable.
AutoPostBack = "false";
Telerik may be different, but the documentation should clearly indicate how to disable this feature. Which would eleminate your need for an UpdatePanel all together. Allowing you to save your data, on PostBack correctly.
Use telerik Ajaxloadingpanel except UpdatePanel this is good for your code try this Example
<telerik:RadAjaxLoadingPanel ID="rlp" runat="server" Skin="Metro">
</telerik:RadAjaxLoadingPanel>
<telerik:RadAjaxPanel runat="server" LoadingPanelID="rlp" skin="Metro">
<telerik:RadDatePicker ID="rdpDate1" runat="server">
</telerik:RadDatePicker>
<telerik:RadComboBox ID="ddlCountry" runat="server">
</telerik:RadComboBox>
</telerik:RadAjaxPanel>

Change Image Url at button click

In my asp.net page I have Image control , in which myimage.png will display at page load. Requirement as below,
Browse image using File upload control and on click of Upload button , immediate preview need to be displayed in Image control. When upload button is pressed after browsing image, the existing "myimage.png" will be deleted and new image will be saved into sever path with same name and preview need to be displayed in image control.
Issue is After saving image , image control is not displaying the new image immediately.
To view the image page need to be re-loaded. Code as below,
In aspx page,
<asp:Image ID="imgLogo" style="margin-left: -299px;" ImageUrl="~/images/myimage.png" runat="server" />
Code behind as below,
protected void btnUpload_Click(object sender, EventArgs e)
{
string filePath = FileUpload1.PostedFile.FileName;
File.Delete(Server.MapPath(#"~\images\myimage.png"));
FileUpload1.SaveAs(Server.MapPath(#"~\images\myimage.png"));
imgLogo.ImageUrl = Server.MapPath(#"~\images\myimage.png");
}
Regards
The reason your page must be reloaded is because ASP.NET code is executed on a server. So every time you, for example, click the button with a server-side code inside, the request is sent to the server, server executes your code and returns a proper response. Basically: something MUST be reloaded. It doesn't have to be the entire page, though. You can force the browser to reload only a certain piece of page using AJAX extensions such as Script Manager and Update Panel.
Example (aspx page):
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Click the button."></asp:Label>
<br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Hello World" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
OnClick event:
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "Hello world!";
}
Also, you can force the panel to update it's content using the Update() method of the UpdatePanel.
This looks like a browser caching issue.
The url is exactly the same as it was prior to changing the image file, so the cache will use the originally named file (in its cache) to display.
You can get over this hurdle by adding something extra (but not used) to the url:
protected void btnUpload_Click(object sender, EventArgs e)
{
// Do your upload stuff here...
imgLogo.ImageUrl = "~/images/myimage.png?" + DateTime.Now;
}

Having issue for rendering user control after async postback

I have script manager in master page:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnableScriptLocalization ="true" EnableScriptGlobalization ="true" EnablePartialRendering="true" >
</asp:ScriptManager>
MyPage.aspx (Placed in contentplaceholder of master page)
<asp:UpdatePanel ID="upMain" runat="server" UpdateMode="Conditional" EnableViewState="true">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnRefresh" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:PlaceHolder ID="placeHolder1" runat="server" EnableViewState="true"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
MyPage.aspx script:
$(document).ready(function () {
setInterval(myfun, 20000);
});
function myfun() {
var btn = document.getElementById('<%=btnRefresh.ClientID%>');
btn.click();
}
On the place holder I'm putting dynamically created table containing user controls.
On the page load, I can see the user controls on the page. But when Async postback is called after 20 seconds, I don't see the user controls. With firebug, I see that user controls are there. But they do not get rendered; even though I'm creating them again on async postback. They appears to be empty. Help.
Try this code. You need to create controls on every page postback.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GetData(); // get data from database
}
LoadUserControls(); // Create dynamic table containing user controls
}
I think you should read this. Loading UserControl Dynamically in UpdatePanel

How to hide/show a control using AJAX (AjaxControlToolkit) and C#

I know this must sound really basic but I'm really stumped here. What I'm trying to do is to show a Hyperlink once a process has completed. And this process is the AsyncFileUpload. In the ASPX page, I want to create an but have it hidden on the initial page load. If I set the Style="display: none;" seems to work but after the file upload, nothing I do, will make the control visible again. When the file is uploaded, it calls a function called FileUploadComplete. It's in here that no matter what I do, the Hyperlink won't display.
Any help is greatly appreciated :)
Thank you,
dave
Here is the ASPX Code (with recently added javascript)
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="OptionsPlaceHolder" runat="server">
<script language="javascript" type="text/javascript">
function ShowLink() {
$("#openFile").show();
}
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolderBody" runat="server">
<asp:UpdatePanel ID="updImportFile" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div class="pageHeader">
<asp:Literal runat="server" ID="pageTitle" Text="<%$ Resources:Resources, ImportFile %>" />
</div>
<ajaxToolkit:AsyncFileUpload ID="FileUpload1" runat="server" Width="600px"
UploaderStyle="Traditional" OnUploadedComplete="FileUploadComplete" ThrobberID="throbber"
CompleteBackColor="#E9F2FD" OnClientUploadComplete="ShowLink" />
<asp:Image runat="server" ID="throbber" ImageUrl="images/loading.gif" />
<br />
<asp:Hyperlink runat="server" ID="openFile" NavigateUrl="~/OpenFile.aspx" Text="Open"
style="display:none;"/>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
And here is the code behind:
protected void FileUploadComplete(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string importName = Server.MapPath(#"Uploads\") + FileUpload1.FileName;
FileUpload1.SaveAs(importName);
// Import the JSA
JSA jsa = new JSA();
jsa.Import(importName);
// Show the Hyperlink
ShowLink();
}
}
private void ShowLink()
{
openFile.Attributes["Style"] = string.Empty;
}
I didn't include the master page code. It has the ToolkitScriptManager in it.
Are you trying to show on client-side or server-side? Is the link a client-side, or server-side object? Javascript would be the standard way.
If the control is a client-side object:
document.getElementById("hyperlink_name").style.display = "block";
Or if it is a server-side object:
document.getElementById("<%= hyperlink_name.ClientID %>").style.display = "block";
I would recommend getting jQuery and using the following though:
$('#hyperlink_name').show();
Or you can use an ASP.Net Link Button and do it server-side:
linkButton.Visible = true;
It would be more helpful if you would post some of the code you have tried already so that we can get a better idea of where you are.
{first answer deleted}
[EDIT :I didn't catch that you are using AsyncFileUpload when I first read the question]
Using AsyncFileUpload inside an update panel the server is being accessed via a partial postback, as a result other controls (the hyperlink) cannot be affected on the server. This will require that you make use of javascript (or preferably jquery) to make the change on the client.
You can do it on OnClientUploadComplete function, but you have to reference the hyperlink like this: <%= hyperLink.ClientID %>.style.display = 'block';
Another more asp.net way is to use update panels. Put the hyperlink into an UpdatePanel and set a trigger on the UpdatePanel when the file is uploaded. then change the visibility on the server at UploadedComplete event.

Problem using UpdatePanel with Masterpage in C#

My code :
<%# Page Language="C#" %>
<script runat="server">
void button_Click(object sender, EventArgs e)
{
label.Text = "Refreshed by server side event handler at " + DateTime.Now + ".<br>Value provided:" + text.Text;
}
</script>
<html>
<head>
<title>How to update an UpdatePanel with JavaScript</title>
<script type="text/javascript">
function UpdPanelUpdate(id) {
var obj = document.getElementById("<%= text.ClientID %>");
obj.value = id;
__doPostBack("<%= button.ClientID %>", "");
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
Update the Panel
<asp:TextBox ID="text" runat="server" Style="display: none;"></asp:TextBox>
<asp:Button ID="button" runat="server" OnClick="button_Click" Style="display: none;" />
<asp:UpdatePanel runat="server" ID="UpdatePanel1" UpdateMode="Conditional" ChildrenAsTriggers="false">
<contenttemplate>
<asp:Label ID="label" runat="server"></asp:Label>
</contenttemplate>
<triggers>
<asp:AsyncPostBackTrigger ControlID="button" EventName="Click" />
</triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
That works great, but when I use it with a Masterpage, the link does´t seems to work... No error, but nothing happens...
Any idea?
Thanks!
In your JavaScript try using UniqueID instead of ClientID:
function UpdPanelUpdate(id) {
var obj = document.getElementById("<%= text.UniqueID%>");
obj.value = id;
__doPostBack("<%= button.UniqueID%>", "");
}
Let me know if that works.
I suspect what's happening is the textbox ID is no longer what you expect it to be. The ID is originally "text" however once you move that page to a Master Page things change. Since controls are now contained in the master page their IDs effectively change to show this relationship. So instead of the textbox's ID being "text" it is now going to be something like ctl00$cphBody$text - where "ctl100" is the Master Page's ID prefix and "cphBody" is the value you assigned to that page's ContentPlaceHolderID, respectively.
Sure, from the code behind you can do this.text.Text = "new value" and directly access it. That's fine. But try using FindControl and you'll notice things get confusing. The easiest way to really understand what I am describing is to do the following on your page with it using the master page:
Set a breakpoint on page load
Bring up your Immediate Window (CTRL + ALT + I)
Type this in: ?this.text.ID (you should see text)
Type in: ?this.text.ClientID (you should see ctl00_cphBody_text)
Type in: ?this.text.UniqueID (you should see ctl00$cphBody$text)
Now test the results you got for steps 3-5 using FindControl. Use ?this.FindControl("text") and ?this.FindControl("ctl00_cphBody_text") and ?this.FindControl("ctl00$cphBody$text") - all but the last one should return null.
To further understand this I suggest reading this article, specifically the section titled "FindControl, JavaScript, and Naming Containers."
EDIT: I'm actually unable to test the function at the moment, but I'm wondering if what I posted about FindControl applies to JavaScript accessing the control. Based on this article it seems ClientID is suggested over UniqueID. So this may not work.
Have you ensured the ScriptManager is included correctly on the master page? You might find this link useful; Using the ASP.NET UpdatePanel Control with Master Pages

Categories

Resources