Erik Lenaerts

Do, or do not. There is no try.

February 2006 - Posts

An Xml Web Control WITH ViewState

Hi,

Recently we stumbled upon something strange in one of the new .NET Controls of VS 2005. It appears that the Xml Control doesn't keep state for its DocumentSource & TransformSource properties. With these two properties, one can set the file names of both the Xml and XSL file.

So, I figured that this was a short comming and decided to write a derived version of the Xml Control that would keep this state information between postbacks.

I figured, let's keep the same names for these properties but since they aren't virtuals, I had to hide them using the New keyword. Additionaly I chose to store the respective values in the ViewState and not the new ASP.NET 2.0 ControlState, since I still wanted it to react on the EnableViewState property of the Control class.

download the code here (VS 2005)

- Erik

Using Popup window in ASP.NET 2.0

Hi,

As we started with our new intranet project, we wanted to use a popup window for lookup functionalities. I remember that this wasn't easy in ASP.NET 1.x and that one had to rely on javascript. Sadly enough ASP.NET 2.0 doesn't make things any better. 

So, after looking around, I found some implementations but to me, they looked ugly. So, I started building a few classes to manage popups and their results.

Basically when working with showModalDialog method of the window client side object you can get the result of the popup window via a return value of this method. When you need this result at the server side, you have a number of options but they all come down to one of these 2 concepts:

  1. On the web page that is displayed in the popup window, you get the user input from the page during a post back and (most likely) close the popup window.
  2. Collect the return value from the showModalDialog method call and pass it to the server via a form (Http Post) or via a parameters in an url (Http Get).

My approach here was to minimize the client side javascript code, so therefore my popup implementation is based on option 1.

PopupWindow Class

This class will produce the javascript code that will display the popup window (Modal Dialog box).

The following example will create a PopupWindow "Popup1" with a specified url which will be used by the Dialog Box.

PopupWindow popupWindow = new PopupWindow("Popup1", 
"child.aspx?target=First Input:"); btnValue1.Attributes.Add("onclick", popupWindow.RenderClientScriptCall());

The RenderClientScript method will produce the following code:

window.showModalDialog('child.aspx?target=First Input:&__PopupId=Popup1',
null,'status:yes;dialogWidth:300px;dialogHeight:200px; center:yes;
edge:Raised;help:yes;resizable:no;scroll:yes');

As you can see, most features of the showModalDialog method have default values. Notice the "__PopupId=Popup1" added to the querystring. This will allow the PopupManager later on to fetch the Id of the PopupWindow class.

PopupManager Class

This class is used both by the caller of the Popup (I call this one Parent) as the page displayed in the Popup (Child).

In the Child Page we use it for 2 purposes:

  • Close the Popup Window with the ClosePopup method
  • Set the result of the Popup Window with the SetPopupResult method

 In fact this class comes in 2 forms. One standard, which allows you to call the ClosePopup() method. Enough for situations where you only want to display a page in the Popup Window (like a help page)

The other version of the PopupManager has the following signature:

public class PopupManager : PopupManager
{
   //...
}

Where T is the type of the result object. The result object is something you want to create yourself. It is an object that can hold the necessary data which you want to return to the Parent Page. It could be as easy as a simple string or it can be a custom class with a high number of data properties.

In the Parent Page we use the same PopupManager class. But this time we use the GetPopupResult method, which will return us an object of type T. Additionally when working with multiple Popup windows called by the same parent (button from a datagrid for example) you want to know from which PopupWindow it was called. Therefore we can use the GetPopupId method.

PopupWindowBase Class

To make your life easier I created a base class PopupWindowBase and PopupWindowBase that you can use to derive your web pages from (both Parent and Child). These base classes are derived from System.Web.UI.Page, so you keep all the features you had before. Additionally these base classes provide you with a PopupManager property. This way you don't need to instantiate a PopupManager yourself and it also hides a bit the generic syntax. For example your code in the child class could look like:

public partial class child : PopupWindowBase
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ....
    }

    protected void btnOK_Click(object sender, EventArgs e)
    {
        PopupManager.SetPopupResult(new PopupResult("Hello", 
txtValue.Text)); PopupManager.ClosePopUp(); } protected void btnCancel_Click(object sender, EventArgs e) { PopupManager.ClosePopUp(); } }

So, the MyPopupResult is a class you should write yourself. Note how it is used as template type for the generic base class PopupWindowBase.

Simmilarly the code in the Parent class could look like:

public partial class Parent : PopupWindowBase
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            btnValue1.Attributes.Add("onclick", 
new PopupWindow("Popup1", "child.aspx").RenderClientScript()); btnValue2.Attributes.Add("onclick",
new PopupWindow("Popup2", "child.aspx").RenderClientScript()); } else { //Process the results of a popup window PopupResult popupResult = PopupManager.GetPopupResult(); if (popupResult != null) { string popupId = PopupManager.GetPopupId(); if (popupId == "Popup1") txtValue1.Text = popupResult.ToString(); else if (popupId == "Popup2") txtValue2.Text = popupResult.ToString(); } } } }

Internally the classes uses 2 session variables to operate. Since I work with the showModalDialog only one Dialog can exist at a time and we don't need any additional session storage.

download the code and a sample project here (.NET 2.0, VS 2005)