Pages

Thursday, 17 November 2011

Slide Show In asp.net


I had been looking for the source of a web-based slide show. The features I wanted in my slide show pages were that it should dynamically select a picture in the server to display, it should display some transition effects, and it should not cause page refreshing. But I couldn’t find one of this kind. So I decided to code it myself.There is a lot of source code to make the transition effect using JavaScript. But to address the dynamic selection of the picture to display and to avoid the page from refreshing, I used AJAX. There are a lot of AJAX frameworks and tools out there to choose from. But for this simple task, I just used the ASP.NET2’s built-in AJAX supported class system.Web.UI.ICallbackEventHandler.

The included source code will demonstrate the use of this class, and also how to use JavaScript to make the request to get the next image file and apply the transition effects. One thing I need to mention is when applying transition effects, the next image has to be completely loaded before playing the effect, otherwise, the picture display will not be smooth and will be flickering. I also address this in my JavaScript code.


//.aspx page
<img id="photo" src="" runat="server" border="0" style="height: 150px; width: 400px;" />

//javascript function
<script type="text/javascript">
 //A timer will be fired in 5 seconds to call getNextImage()
 var c_interval = 5000;
window.setTimeout("getNextImage()", c_interval);
function getNextImage() {
 //Send the request to server with the current image url as the argument
CallServer(document.getElementById("photo").src, "")
}
function ReceiveServerData(rValue) {
 //Receive server's response of a string rValue, which is prepared in the server's function
//GetCallbackResult()
 var wds = rValue.split(";");
 //Assign the transition effect
 document.getElementById("photo").style.filter = wds[1];
 //Preload the image file from server. When finishing download, imageLoaded function will be called
 //with the img object as the argument
 var img = new Image();
 img.onload = function () { imageLoaded(this); }
img.onerror = function () { imageError(this); }
 img.onabort = function () { imageError(this); }
 img.src = wds[0];
}
function imageError(img) {
 //If image download errors occur, this function will be called.
 window.setTimeout("getNextImage()", 1000);
}
function imageLoaded(img) {
var photo = document.getElementById("photo"); //Find the image control object
photo.filters[0].apply(); //Apply the transition effect
photo.filters[0].play(); //Play the effect and display the new image
photo.src = img.src; //Assign the image to the image control
window.setTimeout("getNextImage()", c_interval); //Initiate the next request
 }
</script>


//.cs file
string m_lastFileName = "none";
protected void Page_Load(object sender, EventArgs e)
 {if (IsPostBack)
     return;
  photo.Src = GetNextImageUrl();
//Register Ajax client script to client's browsers. This has to be hard coded.
 string cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
 string callbackScript = "function CallServer(arg, context)" + "{ " + cbReference + "} ;";
 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
}
public void RaiseCallbackEvent(string eventArgument)
 {
//This is first place to receive the callback from client's browser. The parameter 'eventArgument'
 //is the parameter passed from the Javascript's call 'CallServer()'. In this example, it is the
 //last image url.
 m_lastFileName = Path.GetFileName(eventArgument);
 }
public string GetCallbackResult()
{
//This is the second call triggled by the 'CallServer()' and it is the place to prepare and return a string
 //to the client. Here the returned string is the image url and the transition effect.
 return GetNextImageUrl() + ";" + GetNextTransition();
 }
private string GetNextImageUrl()
 {
//Randomly pick a image file in the server.
 string[] files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "Images", "*.jpg");
if (files.Length == 0)
    return string.Empty;
while (true)
 {
int n = (int)((files.Length - 1) * (new Random()).NextDouble());
 //Do not want to repeat the last image
 if (files[n].IndexOf(m_lastFileName) < 0)
 {
return files[n].Replace(AppDomain.CurrentDomain.BaseDirectory, string.Empty);
 }
}
}
private string GetNextTransition()
 {
//Randomly pick a transition effect. Note some of the effects only work in IE.
 int n = (int)((new Random().NextDouble()) * 5);
 switch (n)
 {
case 0:
 case 1:
 n = (int)((new Random().NextDouble()) * 22);
 return "revealTrans(duration=2,transition=" + n.ToString() + ")";
 case 2:
 case 3:
 if (Request.Browser.Browser == "IE")
{
n = (
int)((new Random().NextDouble()) * 8);
 switch (n)
 {
case 0:
 return "progid:DXImageTransform.Microsoft.RandomDissolve()";
 case 1:
 return "progid:DXImageTransform.Microsoft.Pixelate(MaxSquare=20, Duration=2, Enabled=false)";
 case 2:
 return "progid:DXImageTransform.Microsoft.RadialWipe(wipeStyle='clock')";
 case 3:
 return "progid:DXImageTransform.Microsoft.Wheel(spokes=4)";
 case 4:
return "progid:DXImageTransform.Microsoft.Stretch(stretchStyle='spin')";
 default:
 return "progid:DXImageTransform.Microsoft.Stretch(stretchStyle='push')";
 }
}
else
 return "blendTrans(duration=2)";
 default:
 return "blendTrans(duration=2)";
 }
}


 

Wednesday, 2 November 2011

Calling javascript function from silverlight


Introduction

When working with Silverlight, we are working with managed code (C#, VB). Sometimes, we need to callback to HTML page from managed code.
In this article, we walkthrough how to call managed code from JavaScript and call JavaScript function from managed code.

Background

To call JavaScript function from Silverlight, HtmlPage class of System.Windows.Browser namespace is used to allow the user to access and manipulate browser DOM (Document Object Model).
ScriptableMemberAtrribute class indicates that method or property is accessible for JavaScript caller.
To permit user to access method of Silverlight from JavaScript, you have to set [ScriptableMember] attribute to that method.

Using the Code

Let's start step by step including source to demonstrate how to communication between JavaScript and Silverlight.

First we start with Calling JavaScript function from Silverlight

Step 1: First, create one class in a Silverlight project, which describes method to call from JavaScript.

Step 2: Switch to Web project and open HTML page.

Step 3: Create Method in HTML page called from Silverlight

//.js file

function alertText(text) {

alert(text);

}
function sendText() {

return "Hi from Javascript!";

}

Step 4: In User Control, create Button to call JavaScript function.

//page.xmal


<Grid x:Name="LayoutRoot" Background="Transparent">

<Grid.RowDefinitions>

<RowDefinition Height="50"></RowDefinition>

<RowDefinition Height="50"></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="200"></ColumnDefinition>

<ColumnDefinition Width="200"></ColumnDefinition>

</Grid.ColumnDefinitions>

<Button x:Name="btnFireJavascript" Grid.Column="0" Click="btnFireJavascript_Click" Width="100" Height="30" Content="Send Data!"></Button>

<Button x:Name="btnReceiveJavascript" Click="btnReceiveJavascript_Click" Grid.Column="1" Width="100" Height="30" Content="Receive Data!"></Button>

<TextBox x:Name="txtReturnData" Height="30" Width="150" Grid.Row="1" Grid.ColumnSpan="2"></TextBox>

</Grid>

//page.xaml.cs

private void btnFireJavascript_Click(object sender, RoutedEventArgs e)
{
HtmlPage.Window.Invoke("alertText", new string[] { "Hi!" });
}
private void btnReceiveJavascript_Click(object sender, RoutedEventArgs e)
{
string obj = HtmlPage.Window.Invoke("sendText", null) as string;
txtReturnData.Text = obj;
}

By clicking on button, we need to invoke JavaScript function by using System.Windows.Browser.HtmlPage.Window.Invoke method. This method will call JavaScript "sendText" method will return the entered text disyplay the "alertText" method with "From Silverlight" as alert messagebox.In the next step, write method in HTML page of Web project has XAP file as a Object parameter.
 Step 5: Drag the reference of the js file to Web project

//silverlighttestpage.aspx drag reference

<script type="text/javascript" src="MyFunctions.js" ></script>

This is just a simple demo example, you can also use Silverlight property from JavaScript as well as JavaScript member from Silverlight.

Please put he comments.......





Thursday, 13 October 2011

showmodaldialog example in asp.net

 

Introduction

This article presents how to open a modal dialog window on a browser (IE only) which contains a web form. Submitting the form on the modal dialog window will refresh the main window content.

Background

I was working on a project to convert a Windows application into a Web-based application. The Windows application's main form displays a DataGrid. Clicking on a row of the DataGrid opens a modal dialog window which holds detailed information about that DataGrid row record. The user can edit the data on the modal dialog window, and clicking on an Update button closes the dialog and refreshes the DataGrid on the main form. The client wanted the same effect in the web application. After much R & D, I came with a solution which I want to share with you.

How to open a modal dialog window and how to get a return value from it?

Since I have no time, my source project contains all the code in one file (sorry! no separate business logic or data access logic classes given).
First of all, let's look at the JavaScript code for opening a modal window (the OpenModalDialog function in the Default.aspx page):
vReturnValue = window.showModalDialog(url,"#1","dialogHeight: 300px; dialogWidth: 600px;" +  
"dialogTop: 190px; dialogLeft: 220px; edge: Raised; center: Yes;" +
"help: No; resizable: No; status: No;");
 
The vReturnValue variable will contain the return value of the modal dialog window (when closed), which we can set in the ModalWindow form (in the detail.aspx page).

window.returnValue = true;
//(I am returning true to refresh Main page and false for no action)
 
 
You can give any value to be returned.

Postback from JavaScript

The most important thing for me is to refresh the grid when I get 'true' as the return value from the modal window. For that, I use (look in JavaScript's OpenModalDialog function):

__doPostBack(btnName,''); //(this will trigger 'btnName' butoon's Click event)
 
In the default.aspx page, I have used btnAddNew to add new data. Using the above JavaScript, I can fire the Click event of this button.

Note :To make this work, you have to set the default.aspx page's EnableEventValidation attribute to False. Setting this attribute to false enables us to fire a postback (server side events) using JavaScript.

 //Another example in details
 
//in parent page
//parent.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ParentForm.aspx.cs" Inherits="ParentForm" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Parent Page</title>
    <script type="text/javascript">
        function OpenChildWindow()
        {
            //open a new dialog window
            var sFeatures="dialogHeight: 200px;";
            sFeatures += "dialogWidth: 400px;";
            sFeatures += "center: yes;";
            sFeatures += "edge: sunken;";
            sFeatures += "scroll: no;";
            sFeatures += "status: yes;";
            sFeatures += "resizeable: no;";
            var url = 'ChildForm.aspx?SomeValue=12345';
           
            entryWindow=window.showModalDialog(url, 'ChildForm', sFeatures);           
            if(entryWindow ==true)
            {
                alert("Watch for CurrTime & ChildWin labels, its going to update since the new child window saved something");
                //this would trigger the update panels update as the button is part of the UP
                window.document.getElementById('btnHiddenForUpdate').click();
            }
            else
            {
                //No change will happen to the parent page as child page did nothing
                alert("Nothing on the page will change as the new child window was cancelled");
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="smParent" runat="server" />
        <div id="divUpdatePanel">           
            <asp:UpdatePanel ID="upParent" runat="server">
                <ContentTemplate>
                    <asp:Label ID="lblCurrTime" runat="server" Text="CurrTime:"></asp:Label> <br />
                    <asp:Label ID="lblChildWinValue" runat="server" Text="ChildWin Value:"></asp:Label><br /><br />
                    <a href="javascript:OpenChildWindow();">Click to open the Child Window</a>         <br />
                    <input type="button" id="btnHiddenForUpdate" runat="server" style="display:none" onserverclick="btnHiddenForUpdate_ServerClick" />     <br />     
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
        <div id="divNormalUpdatePanel">
            <asp:Panel ID="pnlFullPostback" runat="server">
                <asp:Label ID="lblPageLoadTime" runat="server" Text="PageLoadTime:"></asp:Label>
            </asp:Panel>
        </div>
    </form>
</body>
</html>
//parent.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;
public partial class ParentForm : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
   
    {
        if (!IsPostBack)
        {
            //Set default values to the control on PageLoad for first time.
            lblChildWinValue.Text = "ChildWin Value: " + "NONE";
            lblCurrTime.Text = "CurrTime: " + DateTime.Now.ToString();
            lblPageLoadTime.Text = "PageLoadTime: " + DateTime.Now.ToString();
        }       
    }
    protected void btnHiddenForUpdate_ServerClick(object sender, EventArgs e)
    {       
        //Update Panels update - repopulate the controls the way needed.
        lblChildWinValue.Text = "ChildWin Value: " + "SOME VALUE";
        lblCurrTime.Text = "CurrTime: " + DateTime.Now.ToString();
        lblChildWinValue.BackColor = Color.Yellow;
        lblCurrTime.BackColor = Color.Yellow;
        //Just to show that this label wont update as outside the update panel
        lblPageLoadTime.Text = "PageLoadTime: " + DateTime.Now.ToString();
        lblPageLoadTime.BackColor = Color.Yellow;
    }
}
//child.aspx page
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ChildForm.aspx.cs" Inherits="ChildForm" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Child Page</title>
    <script type="text/javascript">
        function WindowClose() {
            //return some value from here based on which Parent will decide the partial update
            window.returnValue = true;
            window.close();
        }
        function WindowCancel() {
            //return some value from here based on which Parent will decide the partial update
            //            window.returnValue = false;
            window.close();
        }
    </script>
    <base target="_self" />
</head>
<body>
    <form id="form1" runat="server">
    <div align="center">
        <br />
        <asp:Label ID="lblParentPageValue" runat="server" Text="Value from parent page: "></asp:Label><br />
        <br />
        <br />
        <asp:Button ID="btnOK" runat="server" Text="Save & Close" OnClientClick="WindowClose();" />
        <asp:Button ID="btnCancel" runat="server" Text="Cancel" OnClientClick="WindowCancel();" /><br />
    </div>
    </form>
</body>
</html>
//child.aspx.cs file
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class ChildForm : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.Request.QueryString["SomeValue"] != null)
        {
            lblParentPageValue.Text = lblParentPageValue.Text + Page.Request.QueryString["SomeValue"].ToString();
        }
    }
}

//and one more thing if u use this functionality postback issue is there so we need to add 3 more details
Response.Expires = 0;
            Response.Cache.SetNoStore();
            Response.AppendHeader("Pragma", "no-cache");
//chk it