Working with Frames in .NET

WEBINAR: On-demand webcast

How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >

By Scott Rosa

Any developer who has had the dubious task of developing a Web site utilizing frames knows it can be an uphill battle. Many argue that frames should be avoided at all costs, while others realize how they can benefit a Web site's user interface. When my team had to develop a Web site that displayed pdf's in a management dashboard, we knew frames were the way to go. Unfortunately, we were not sure how to best work with frames in ASP.NET. When I used my list of normal search engines/newsgroups, I could not find much in the way of useful information. Here is one reply I got when asking how to best work with frames in .NET:

Ok, My list of suggestion for Frames.
1. Frames are Evil
2. The Devil created Frames
3. If you are having a problem related to the Target, refer to item 1
4. If you are trying to refresh data in a particular frame, refer to 1

I think you get the idea. The fact of the matter is frames can provide an aesthetically pleasing site, which in many situations is more user-friendly. This of course is only the case if you avoid the pitfalls of frames, such as multiple scroll bars and too many frame windows. I will not address these pitfalls in this article because there is certainly an over-abundance of information/opinions on that subject. In my opinion frames have gotten a bad reputation from users because so many developers misused them. On the other hand they have a well deserved reputation from the developer side because in the past they were very difficult to work with. The purpose of this article is to show you that this is no longer the case. I will also present one alternative to using frames, called Smart Navigation.

In the end we solved the problem of working with frames by utilizing a mix of JavaScript code and the Attributes property of .NET Web Forms. This is essentially the key behind working with frames in .NET.

System Requirements
Netscape 4.0 or later or IE 5.0 or later Visual Studio.NET Windows 2000 with IIS5

Web Site Set-Up
A pdf_files directory must be created under the Web site root with write access

Frames and Frame Alternatives

Although this article will be used to address the usage of frames in .NET, it is important to talk about the use of frames and some alternatives. My team has developed the majority of our sites without frames because they did not fit into a model in which they were required. We use frames when we need to present the users with a control or set of controls that maintain a certain state, while another part of the page needs to load a file in or some other type of control(s). The MSDN site illustrates a good use of frames in its library section: http://msdn.microsoft.com/library/default.asp In the past we have also used frames to control screen refresh. On an ASP 2.0 or 3.0 page, the entire page would refresh any time you needed to perform a server side event. One alternative to solving the screen refresh issue in ASP.NET is Smart Navigation. This tag can be set at page level through page properties, or at site level through web.config. With this turned on, only the controls within the form tag will be refreshed. So if you have other images, headers, etc., the users will not get screen flicker. It is important to note that behind the scenes ASP.NET is using Iframes, so this will only work on IE5.0 and greater browsers. The use of inline frames allows for this targeted refresh because each frame is treated independently. The following link will provide you with more information on Iframes and some issues related to them: http://www.cs.tut.fi/~jkorpela/html/iframe.html

To see how Smart Navigation can be used, let's take a look at an example.


<%@ Page Language="vb" AutoEventWireup="false" 
Codebehind="smart_tag.aspx.vb" Inherits="asptoday_frames.smart_tag" 
smartNavigation="True"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
	<HEAD>
		<title>smart_tag</title>

		<meta content="Microsoft Visual Studio.NET 7.0" 
name="GENERATOR">
		<meta content="Visual Basic 7.0" name="CODE_LANGUAGE">
		<meta content="JavaScript" name="vs_defaultClientScript">
		<meta content="http://schemas.microsoft.com/intellisense/ie5"    
name="vs_targetSchema">
	</HEAD>
	<body MS_POSITIONING="GridLayout">

		<form id="frmImage" style="Z-INDEX: 101; LEFT: 6px; POSITION: 
absolute; TOP: 18px" runat="server">
<asp:button id="btnRefresh" style="Z-INDEX: 104; LEFT: 19px; POSITION: 
absolute; TOP: 13px" runat="server" Text="Refresh"></asp:button><asp:label id="lblRefresh" 
style="Z-INDEX: 105; LEFT: 96px; POSITION: absolute; TOP: 18px" 
runat="server"></asp:label></form>
		<IMG style="Z-INDEX: 103; LEFT: 27px; WIDTH: 507px; POSITION: 
absolute; TOP: 87px; HEIGHT: 259px" height="259" alt="" src="test.GIF" 
width="507">
		<IMG style="Z-INDEX: 102; LEFT: 16px; WIDTH: 507px; POSITION: 
absolute; TOP: 78px; HEIGHT: 259px" height="259" alt="" src="test.GIF" 
width="507">
	</body>

</HTML>

Code Behind

Public Class smart_tag
    Inherits System.Web.UI.Page
    Protected WithEvents btnRefresh As System.Web.UI.WebControls.Button
    Protected WithEvents lblRefresh As System.Web.UI.WebControls.Label

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles  MyBase.Load
        Me.lblRefresh.Text = ""
    End Sub

Private Sub btnRefresh_Click(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles btnRefresh.Click
        Me.lblRefresh.Text = "Page Refreshed"
    End Sub
End Class

At the top of the page we are setting smartNavigation="True" so that the only the lblRefresh and btnRefresh make a roundtrip to the server. I have added two images at the bottom of the page to illustrate the difference that smart navigation makes. If you set smartNavigation = False, you will notice some flashing of the images, even when running local to the Web server.

IFrames can be useful in forcing refresh of only part of the screen, but it cannot fully replace the functionality that comes with working with regular frames. The biggest drawback with Iframes is that you cannot implement two separate form tags in the same page, which may be required for some sites.

Questions Regarding Frames

The main problem that most people have when working with frames is cross-frame communication. There are several consistent questions I see on frames including:

  • How do I pass data to another frame?
  • How do I refresh a specific frame?
    This issue is compounded when you start dealing with pop-up windows.

The Solution

Solving the above described problems has become much easier with some basic knowledge of the windows and frames properties in javascript and the ASP.NET Attributes property. In this article I am going to break my code up into several sections, starting with a very easy to follow hello world style example. After that I will address working with pop-ups, adding a very useful HTML control into the mix.

The Code

Goal #1: Pass data between left and right frames

UI Design
Before I get into the code, it is important that you receive the visual of the two frames that we will be working with:


Figure 1

CODE
For the purpose of brevity, I will exclude code automatically generated by Web forms.

To start we have the simple default.htm page that will contain our two aspx pages.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>

	<head>
		<title>How to Work with frames in .Net</title>
		<meta name="vs_defaultClientScript" content="JavaScript">
		<meta name="vs_targetSchema" 
content="http://schemas.microsoft.com/intellisense/ie5">
		<meta name="GENERATOR" content="Microsoft Visual Studio.NET 
7.0">

		<meta name="ProgId" content="VisualStudio.HTML">
		<meta name="Originator" content="Microsoft Visual Studio.NET 
7.0">
	</head>
	<frameset border="1" frameborder="1" framespacing="0" 
cols="30%,70%">

<frame name="left frame" src="leftframe.aspx"/>
<frame name="right frame" src="rightframe.aspx"/>

</frameset>
</html>

Next is the left frame page, which will contain a mix of javascript and VB.NET code. The mix of this code will enable us to pass a text string from a textbox on the left frame to a textbox in the right frame.

Public Class leftframe
    Inherits System.Web.UI.Page
    Protected WithEvents btnTright As System.Web.UI.WebControls.Button
    Protected WithEvents btnPop As System.Web.UI.WebControls.Button
    Protected WithEvents txtTright As System.Web.UI.WebControls.TextBox

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles MyBase.Load
'enclose the add attributes in the not is post back block, so they
        	' are called to be added only once.
        If Not IsPostBack Then
            btnTright.Attributes.Add("onclick", 
"javascript:tranRight(txtTransferRight.value)")
            btnPop.Attributes.Add("onclick", "javascript:openWindow()")
            'remove file name from session
            Session.Remove("fileName")
        End If

    End Sub

End Class

The key to working with frames is the Attributes property along with its Add method, which allows us to dynamically insert calls to javascript functions, passing in our server side control's data. The Attributes property allows you to declare any event handler that is associated with a specific Web control. Any of the attributes that you add to the controls collection will be rendered at run time. For a text box you could add a call to the textchanged event. Note, if you do make reference to an unsupported event, it will be ignored by the browser. For now you can ignore the session remove, which will be needed for a later part of this article.

Here is the HTML code that exists for the left frame page.


<%@ Page Language="vb" AutoEventWireup="false" 
Codebehind="leftframe.aspx.vb" Inherits="asptoday_frames.leftframe"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
	<HEAD>
		<title>leftframe</title>
		<meta content="Microsoft Visual Studio.NET 7.0" 
name="GENERATOR">

		<meta content="Visual Basic 7.0" name="CODE_LANGUAGE">
		<meta content="JavaScript" name="vs_defaultClientScript">
		<meta content="http://schemas.microsoft.com/intellisense/ie5" 
name="vs_targetSchema">
	</HEAD>
	<body MS_POSITIONING="GridLayout">
<form id="frmTransterRight" method="post" runat="server">

<asp:button id="btnTransferRight" style="Z-INDEX: 101; LEFT: 23px; 
POSITION: absolute; TOP: 100px" runat="server" Text="Send to right frame" 
Width="131px"></asp:button><asp:textbox 
id="txtTransferRight" style="Z-INDEX: 102; LEFT: 26px; POSITION: absolute; TOP: 
64px" runat="server" Width="170px" Height="24px">Text to go to right 
frame</asp:textbox><asp:button id="btnPop" style="Z-INDEX: 103; 
LEFT: 24px; POSITION: absolute; TOP: 136px" runat="server" Text="Open Pop-Up" 
Width="129px"></asp:button></form>
<script language="javascript">		

//this function takes a value (ltext) and transmits that to the left hand frame

function tranRight(ltext)

{
	parent.frames(1).document.forms("frmReceive").item("txtReceive").value = 
ltext;
	
}
		</script>
	</body>


Notice the tranRight javascript function, which will enable us to transfer the text in the left frame to the right frame. The tranRight function is called from the click event of the btnTransferRight button Parent.Frames(1) indicates we are targeting the right frame, while Parent.Frames(0) is the current page that the code is getting initialized from. When the btnTransferRight button is clicked, only the left frame will be re-rendered because the button's event is set to run client side.

With that simple code, we have established basic interaction between our frames.

Goal #2: Pass text between pop-up and right frame

In this section we will pass text from a pop-up screen launched from the left frame to a textbox in the right frame. UI Design

The "Send Via QS" button will trigger the event that will transmit the text. The lower section of this UI will be addressed in Goal#3


Figure 2

UI Code
The first key is the code which allows this pop-up to be launched from the left frame. This is a line in the original left frame codebehind listed as part of example #1:

 
btnPop.Attributes.Add("onclick", "javascript:openWindow()")

This is the JavaScript which launches this pop-up:

function openWindow() 
{ msgWindow=window.open("popup.aspx","", 
"fullscreen=no,toolbar=no,status=yes,menubar=yes,scrollbars=no,resizable=no,
directories=no,location=no,width=500,height=400"); 
if (msgWindow.opener == null) msgWindow.opener = self; }

Now that we have established the launch of the popup, we can look at the pageload event of the popup Web form.


Public Class popup
    Inherits System.Web.UI.Page
    Protected WithEvents btnLfile As System.Web.UI.HtmlControls.HtmlInputButton
    Protected WithEvents btnWFrame As System.Web.UI.WebControls.Button
    Protected WithEvents btnHframe As System.Web.UI.WebControls.Button
    Protected WithEvents txtPop As System.Web.UI.WebControls.TextBox
    Protected WithEvents myFile As System.Web.UI.HtmlControls.HtmlInputFile

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles MyBase.Load
'enclose the add attributes in the not is post back block, so they
' are called to be added only once.
        If Not IsPostBack Then
            btnSendQS.Attributes.Add("onclick", 
"javascript:openpdf(txtPop.value)")
            btnSendSession.Attributes.Add("onclick", 
"javascript:openviacache()")        
        End If
    End Sub
End Class

Once again we are adding attributes to two of the buttons which call javascript functions. The first button is the one we will concentrate on for the time being. As you can see we are passing in the value of the txtPop textbox.

Here is the javascript which transmits the text.


function transferText(strTxtTransfer) { 
window.opener.parent.frames[1].location.href 
= "rightframe.aspx?strText="+ strTxtTransfer; window.close(); }

By using window.opener.parent we are able to reference the original frame, so we then in turn can reference the right frame to transmit the data to (by inserting and index of 1). The text itself is encased within a query string. This query string is then read by the right frame on load of the page and presented within that page's textbox.

Goal #3 Use HTML input control in pop-up to load user file to server and then launch pdf in right fr

In this section we will be using the HTML input control to load a pdf file to the Web server and then subsequently call for the load of that pdf into the right frame. The HTML input control, which is provided with .NET, makes file uploading far more simple by presenting users with the standard Windows file browsing window.

UI Design


Figure 2

UI Code


<form id="Form1" method="post" encType="multipart/form-data" 
runat="server">


The first section of code to review is the HTML in the pop-up.aspx page. In the form you must add the Tag encType="multipart/form-data". This will allow the HTML input control to work.

  Private Sub btnLoadFile_ServerClick(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles btnLfile.ServerClick, btnLoadFile.ServerClick
    
    'Grab the file name from its fully qualified path at client 
        Dim strFileName As String = myFile.PostedFile.FileName
        ' only the attched file name not its path
        Dim strShortFile As String = System.IO.Path.GetFileName(strFileName)
        'Save uploaded file to server @ rootweb\pdf_files and add to session
 myFile.PostedFile.SaveAs(Server.MapPath(".") & "\pdf_files\" & strShortFile)
Session.Add("fileName", Server.MapPath(".") & "\pdf_files\" & strShortFile)
    End Sub

This codebehind for the loadfile button saves the file up to the server and stores the name and location in session. This was the reason for the clearing of session that was seen in the codebehind of the left frame page. The browse button is what presents the user with the standard Windows Explorer file selection box and fills in the lower text box. This functionality is all encapsulated in the HTML input control.

Below is the HTML and JavaScript that exists behind the pop-up aspx page.



<%@ Page Language="vb" AutoEventWireup="false" Codebehind="popup.aspx.vb" 
Inherits="asptoday_frames.popup"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
	<HEAD>
		<title>popup</title>
		<meta content="Microsoft Visual Studio.NET 7.0" 
name="GENERATOR">

		<meta content="Visual Basic 7.0" name="CODE_LANGUAGE">
		<meta content="JavaScript" name="vs_defaultClientScript">
		<meta content="http://schemas.microsoft.com/intellisense/ie5" 
name="vs_targetSchema">
	</HEAD>
	<body MS_POSITIONING="GridLayout">
		<form id="frmPopUp" method="post" encType="multipart/form-data" 
runat="server">

			<asp:label id="Label1" style="Z-INDEX: 106; LEFT: 26px; 
POSITION: absolute; TOP: 90px" runat="server" Height="20px" ForeColor="Red" 
Font-Bold="True" Width="280px">Session 
Example</asp:label><asp:label id="lblSession" style="Z-INDEX: 
107; LEFT: 26px; POSITION: absolute; TOP: 117px" runat="server" Height="20px" 
ForeColor="DimGray" Font-Bold="True" Width="459px" Font-
Size="Smaller">Click Browse, Find PDF file, click load file and then the 
send via session button</asp:label> 
			<INPUT id="btnLoadFile" style="Z-INDEX: 100; LEFT: 334px; 
WIDTH: 79px; POSITION: absolute; TOP: 148px; HEIGHT: 23px" type="button" 
value="LoadFile " runat="server">
			<asp:button id="btnSendSession" style="Z-INDEX: 101; 
LEFT: 18px; POSITION: absolute; TOP: 179px" runat="server" Width="112px" 
Text="Send Via Session"></asp:button><asp:button 
id="btnSendQS" style="Z-INDEX: 102; LEFT: 266px; POSITION: absolute; TOP: 41px" 
runat="server" Width="113px" Text="Send Via 
QS"></asp:button><INPUT id="myFile" style="Z-INDEX: 103; 
LEFT: 18px; WIDTH: 311px; POSITION: absolute; TOP: 148px; HEIGHT: 22px" 
type="file" size="32" name="myFile" runat="server">

			<asp:textbox id="txtPop" style="Z-INDEX: 104; LEFT: 25px; 
POSITION: absolute; TOP: 43px" runat="server" Width="225px">Transmit to 
right frame</asp:textbox><asp:label id="lblQS" style="Z-INDEX: 
105; LEFT: 32px; POSITION: absolute; TOP: 13px" runat="server" ForeColor="Red" 
Font-Bold="True" Width="251px">Query String 
Example</asp:label></form>
		<script language="javascript">			

function transferText(strTxtTransfer)
{
window.opener.parent.frames[1].location.href = "rightframe.aspx?strText="+ strTxtTransfer;
window.close();
}


function openviacache()
{
window.opener.parent.frames[1].location.href = "rightframe.aspx";
window.close();
}
		</script>
	</body>

</HTML>

A refresh of the right frame is called from the "Send Via Cache" button, which has an onclick event call to the openviacache JavaScript function. This function calls for the re-load of the right frame page. We want the page to reload so the code in the page load event of the right hand frame page will execute.

The code behind of the right frame page looks for the fname session key and loads a pdf in the page based on that filename. In this block of code, I first test to make sure the file passed from session is a pdf. This is because I am using Response.contentType so that the browser can interpret the file as a pdf and display it properly in the browser.


Public Class rightframe
    Inherits System.Web.UI.Page
    Protected WithEvents txtFleft As System.Web.UI.WebControls.TextBox

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here

        Dim strTxtTransfer As String = Request.QueryString.Get("strText")
        'first find out if this page is getting called from the send via qs 
button by looking for a query string
        If strTxtTransfer <> "" Then
            Me.txtReceive.Text = strTxtTransfer
            ' if session fname is populated and the file is a pdf load the pdf
        ElseIf (Session.Item("filename")) <> "" And 
Right((Session.Item("filename")), 3) = "pdf" Then
            Response.Expires = 0
            Response.Buffer = True
            Response.Clear()
            Response.ContentType = "application/pdf"
            Response.WriteFile(Session.Item("filename"))
            Response.End()
            'if session has a value and it is not a pdf send an error message
        ElseIf (Session.Item("filename")) <> "" And 
Right((Session.Item("filename")), 3) <> "pdf" Then
            With Me.txtReceive
                .ForeColor = Color.Red
                .Text = "sorry you must choose a pdf file to display"
            End With
        End If
End Sub


The final result looks like this:


Figure 3

Conclusion

My goal for this article was to illustrate that working with frames in ASP.NET is a far more efficient endeavor than it once was in the old ASP world. I also wanted to illustrate some benefits of using frames, which are not covered by ASP.NET's Smart Navigation feature. My goal was not to convince you that frames are appropriate for most Web sites. When they are you can use this article as a guide so that you may avoid some of the struggles my team initially encountered.

Links

More info on Smart Navigation:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWebUIPageClassSmartNavigationTopic.asp

About the Author

Scott Rosa is an applications development manager for Analog Devices and has an MBA in Computer Information Systems.

Scott has experience working with ASP.NET, VB.NET, VB 6.0, SQL Server, ADO.NET, Essbase, XML, and UML.

Download source code below and rename the file to "15Seconds_frames" before unzipping.



Downloads

Comments

  • Web Page

    Posted by gajendra bisht on 12/29/2015 08:39am

    Hello Sir, Is their any way to open a web Page (like gmail or facebook Page) in our same aspx page in asp.Net by using frameset or any other way.Please help me out.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date