Using TreeView inside AJAX UpdatePanel

Microsoft does not support TreeView Control inside AJAX:UpdatePanel. So there are lots of issues if one need to do the same. One of my teams needed to use the TreeView inside the UpdatePanel. The core of the application is around some hierarchical documentation. As the user interaction with the system mostly through this hierarchical data, TreeView with check boxes is the most obvious selection. However, the pain began as the development progressed and changes in requirements started pouring in. One option was for clientside population of treeview. But some dynamic changes happening to the underlying hierarchical data (by concurrent users), we needed to repopulate the tree from the database. With growing data volume, clientside population had to be abandoned. But the TreeView started giving endless sitting with the code as it started behaving weirdly at most of the times.

Here are some of the key issues and resolutions of some of them. Some are yet to be resolved, however.

1. The SelectedNode property is lost in successive postbacks. The scenario is easy. Click any TreeNode. In the coddebehind, you get the TreeView.SelectedNode. But on any successive postback where the postback is caused by anything other than a TreeNode click, the SelectedNode property is NULL.

Resolution: Use your own ViewState to manage. Following is the code segment:

    #region ViewState handling for selected node
    //Added by Kangkan - on June 04 2009
    // As the selected Node is lost on second or more postback
    // if the treeview is inside the update panel.
    protected override object SaveViewState()
    {
        if (TViewDeviceHeirarchy.SelectedNode != null)
        {
            ViewState["SelectedNodePath"] = TViewDeviceHeirarchy.SelectedNode.ValuePath;
        }
        return base.SaveViewState();
    }

    protected void Page_PreLoad(object sender, EventArgs e)
    {
        GetSelectedNodeFromViewState();
    }

    private void GetSelectedNodeFromViewState()
    {
        if (ViewState["SelectedNodePath"] != null)
        {
            TreeNode node = TViewDeviceHeirarchy.FindNode(ViewState["SelectedNodePath"].ToString());
            if (node != null)
                node.Select();
            else
                ViewState["SelectedNodePath"] = null;
        }
    }

    public void ClearSelectedNodeViewState()
    {
        ViewState.Remove("SelectedNodePath");
        if (TViewDeviceHeirarchy.SelectedNode != null)
            TViewDeviceHeirarchy.SelectedNode.Selected = false;
    }
    #endregion ViewState handling for selected node

2. The CheckedNodes collection is null in successive postbacks. The scenario is easy. Check any checkbox associated with a TreeNode. In the coddebehind, you get the TreeView.CheckedNodes collection. But on any successive postback where there is no change in the checkedNodes, the CheckedNodes collection returns 0 count. And in this point of time, though the TreeNodes are checked at the client (browser), a FindNode at times fail to locate the node and if it locates, the TreeNode.Checked property is also at times false. It was a nightmare to continue with such a piece of code. Thought of using the same method as that used for persisting the SelectedNode. There are issues with that. So we relied upon Session variable. Here is the code segment for the same:

    #region CheckNodes handling
    //To handle loss of checked Nodes on repeatitive postbacks
    //  SetCheckedNodesToSession sets the nodes'ValuePath to session
    //  GetCheckedNodesFromSession gets the TreeNode Collection from the session
    //The session variable Session["CheckedNode"] is used.
    //The same need to be cleared (set to null) once the usage is over.
    //-----------------------------------------------------------------

    /// <summary>
    /// SetCheckedNodesToSession: Sets the CheckedNodes' ValuePath to a Session Object.
    /// ValuePath of each CheckedNode is concatenated to a string and the string is saved.
    /// Session["CheckedNode"] is used for saving the ValuePath string.
    /// </summary>
    private void SetCheckedNodesToSession()
    {
        if (TViewDeviceHeirarchy.CheckedNodes.Count > 0)
        {
            StringBuilder checks = new StringBuilder();
            for (int i = 0; i < TViewDeviceHeirarchy.CheckedNodes.Count; i++)
            {
                checks.Append(TViewDeviceHeirarchy.CheckedNodes[i].ValuePath + "|");
            }
            Session["CheckedNode"] = checks.ToString().Remove(checks.ToString().Length - 1, 1);
        }
    }

    /// <summary>
    /// Return TreeNodeCollection from the Session
    /// Session["CheckedNode"] is used for saving the ValuePath string.
    /// </summary>
    /// <returns>TreeNodeCollection as saved into the session.</returns>
    private TreeNodeCollection GetCheckedNodesFromSession()
    {
        TreeNodeCollection ColNodes = new TreeNodeCollection();
        if (Session["CheckedNode"] != null)
        {
            string checks = Session["CheckedNode"].ToString();
            string[] CheckArray = checks.Split(new char[] { '|' });
            TreeNode node;
            foreach (string s in CheckArray)
            {
                node = TViewDeviceHeirarchy.FindNode(s);
                if (node != null)
                {
                    ColNodes.Add(node);
                    //node.Checked = true;
                }
            }
        }
        return ColNodes;
    }

    #endregion CheckNodes handling
[/code]


3. SelectedNodeChanged event does not fire! The usage scenario include change of one node from one parent to another parent node. So what happens is that once we complete the task, we clear the nodes of the tree [TreeView.Nodes.clear()] and rebind the tree. We bind the tree to the first level only and set the nodes to PopulateOnDemand=true for the nodes that have child nodes. At this moment, if we again click on any tree node, at times it does not fire any postback. Rather the element just vanishes(?) from the treeview. If I reload the page, we can see the element at it works fine. To get rid of this issue, I use to reload the page at the end of certain usage scenario. But the pain is how to let the user know the satus of what happened at the end of the usage? Again the use of Session variable. What we have done is shown below:

At the end of any such usage scenario, put the message to the user in a session variable and reload the page:


[code:c#]


    public void SetReloadStatus(string message, bool IsError)
    {
        Session["ReloadMessage"] = message;
        Session["ReloadStatus"] = IsError.ToString();
    }

[/code]



At the load of the page, check for the existence of any session variable for pending tasks and complete accordingly:


    public void ShowReloadStatus()
    {
        if (Session["ReloadStatus"] != null)
        {
            bool boolVal = Convert.ToBoolean(Session["ReloadStatus"].ToString());
            if (boolVal)
                Infobar1.error = Session["ReloadMessage"].ToString();
            else
                Infobar1.info = Session["ReloadMessage"].ToString();
            Session["ReloadStatus"] = null;
            Session["CheckedNode"] = null;
        }
    }

[/code]


I am aware that the methods applied are not good, rather I shall say not at all meaningful from programming point of view. But till Microsoft does not provide better solutions or I migrate to some other wiser control that works properly, these are some work arounds that we are sticking to. I shall request you to provide your valuable feedback and further suggestions on this.

 

 

Posted: Jun 27 2009, 19:02 by Admin | Comments (4) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Category: ASP.NET | Learning
Social Bookmarks: E-mail | Kick it! | DZone it! | del.icio.us

schema.ini file to interpret column attributres while reading a CSV using MS Text Driver

Problem – While reading a CSV file using Microsoft Text Driver, It interprets CSV file columns in it’s own way like if one the column contains data specific to a date, then it only keep data which is in proper format otherwise it put null against that.



Solution – Create a schema.ini file which defines the structure of a CSV file in turn gets interpreted automatically by driver itself in a desired format.



Details -

Schema.ini files provide schema information about the records in a text file.



If you create a DSN, the schema.ini file gets created automatically in the folder where all your CSV files reside. But if you use connection string, you have to create schema.ini file on your own.



When the Text driver is used, the format of the text file is determined by using a schema information file. The schema information file, which is always named schema.ini and always kept in the same directory as the text data source, provides the IISAM with information about the general format of the file

Each Schema.ini entry specifies one of five characteristics of the table:

· The text file name

· The file format

· The field names, widths, and types

· The character set

· Special data type conversions

Example of a schema.ini file


Code:
[data.txt]
ColNameHeader=FALSE
Col1=Name Char Width 255
Col2=Company Char Width 255



Below are the links for detail information on this topic

http://msdn.microsoft.com/en-us/library/ms709353.aspx


http://www.codeproject.com/KB/database/FinalCSVReader.aspx

 

 

 

Code:
[data.txt]
ColNameHeader=FALSE
Col1=Name Char Width 255
Col2=Company Char Width 255





Below are the links for detail information on this topic

http://msdn.microsoft.com/en-us/library/ms709353.aspx


http://www.codeproject.com/KB/database/FinalCSVReader.aspx

Posted: Nov 05 2008, 14:45 by Admin | Comments (4) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Category: ASP.NET | Learning | ADO.NET
Social Bookmarks: E-mail | Kick it! | DZone it! | del.icio.us

ASP.NET webdomain recycle on subfolder changes

While working on a web application, one of my team presented some weird behaviour on ASP.NET

FIrst observation: Session times out randomly while working on the application.

So we started observing the application closely to see what might be causing this. We came out with some more observations:

Detailed observation: Session times out when any of the user participates in certain scenario. Also, not only the specific session expires, but all the use sessions are expired. Further study shown that actually the app domain itself recycles.

We studied the activities in these specific scenario. We found that a certain implementation use to create folder, put some temporrary files inside it and once done, the folder and the files were deleted. The application recycles whenever the folder is deleted.

The technical reason: ASP.NET runs a File Monitor (FCN) that observes any change to the structure of the Virtual Directory. In case of any change the application is recycled.

Some forums said that tghe app_data folder within the application folder is immune to the condition. But upon testing, we found it otherwise.

Analysis: Lots of analysis:

Also we were observing session expiration initially. All session expires on application recycle unless the state is not in-process. So moving state in-proc to out-proc is a solution.

We found some other approaches as well.

Resolution: There are multiple solutions that can be taken up for this:

Compiled Solutions / workarounds so for

Sol 1: Use out of process session state.

Sol 2: Use Directory Junction between seperate Web folder and content folders. A directory Junction is a pointer to an external folder (outside the application folder/sub folder.

See http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx for more details

Sol 3: Disable FCNotifications in ASP.NET2.0 by adding DWORD FCNMode =1 under HKLM\Software\Microsoft\ASP.NET key

Registry information

loadTOCNode(3, 'resolution'); To enable this hotfix, you must add the following DWORD value at the following registry key:
HKLM\Software\Microsoft\ASP.NET\FCNMode

The following table lists possible values for the FCNMode DWORD value and the behavior that is associated with each value.
Value                   Behavior
Does not exist     This is the default behavior. For each subdirectory, the application will create an object that will monitor the subdirectory.
0 or greater than 2     This is the default behavior. For each subdirectory, the application will create an object that will monitor the subdirectory.
1                   The application will disable File Change Notifications (FCNs). Smile
2                   The application will create one object to monitor the main directory. The application will use this object to monitor each subdirectory.

More info at: http://support.microsoft.com/kb/911272/en-us  


Sol 4: Do not delete any folder.

Most of the time solution 4 seems to be easy way out till MS releases fix for this problem. So we are following solution no 4 for the time being.


Further reading:
 
http://www.eggheadcafe.com/software/aspnet/32318159/modifying-application-fol.aspx

 
http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx

http://forums.asp.net/p/966593/1209642.aspx

http://weblogs.asp.net/owscott/archive/2006/02/21/438678.aspx

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=240686

http://connect.microsoft.com/VisualStudio/feedback/Workaround.aspx?FeedbackID=240686

Posted: Oct 14 2008, 16:44 by Admin | Comments (22) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Category: Learning | ASP.NET
Social Bookmarks: E-mail | Kick it! | DZone it! | del.icio.us

Handling onPropertyChange in Firefox

IE non-standard onPropertyChange is a huge problem in most of the places. I was working on a work of moving an application designed to work on IE to a cross-browser standard. For some of the forms, there is a pop up and on the close button of the pop up, it used to update some of the fields in the opener page as:

    function fnClose(rowid){
        var taxHTML = document.getElementById("taxvalues").innerHTML;
        window.opener.document.getElementById("taxvalues").innerHTML=taxHTML;
        window.opener.document.getElementById("hdnTax").value=rowid;
        //There is a event handler on this element in the opener using "onPropertyChange=fnPopClosed(this.value);"
        window.close();
    }

There is a hidden field in the opener and onPropertyChange event of the hidden field was handled to accomplish the final task. On the opener page there was a call to a javascript function triggered by the onPropertyChange event of the hidden field. Though IE gracefully handles the situation, Firefox and other browsers have never heard of such an event. So there is no activity.

I studied a lot of techniques to emulate the onPropertyChange event including adding a eventlistener. After around three hours of tweaking different ideas, I finally wired up the same in a different technique. I called the javascript method in the opener page directly from the pop up like this:

    function fnClose(rowid){
        var taxHTML = document.getElementById("taxvalues").innerHTML;
        window.opener.document.getElementById("taxvalues").innerHTML=taxHTML;
        window.opener.fnPopClosed(rowid);
        window.close();
    }


And I got what I wished to have.

Enjoy javascripting....

Posted: Oct 05 2008, 16:19 by Admin | Comments (6) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Category: Javascript
Social Bookmarks: E-mail | Kick it! | DZone it! | del.icio.us

Microsoft Patterns & Practices : Guidance Explorer

Wow! Just another goodie!!

Look at this. Now a guidance explorer is available from the Patterns & Practices team at codeplex.com for all the people who want to better their performance. Congratulations to the team for the good work.

The guidance explorer let you explore the guidances mentioned in various patterns and practices guidelines. No more browsing through numerous web pages to find out the guidances. A neat tool with an file explorer style tree to keep the points tidy.

Just loved it. I shall request you all to get it installed and most importantly READ.

Have it in the following URL:

[http://www.codeplex.com/guidanceExplorer/Release/ProjectReleases.aspx?ReleaseId=9763]
Posted: Apr 18 2008, 18:27 by Admin | Comments (5) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Category: Pattern | Learning
Social Bookmarks: E-mail | Kick it! | DZone it! | del.icio.us

The Architecture Journal Reader

Wow! See what I got!!

The Architecture Journal Reader from Microsoft. Thanks a Zillion to MS team.

First, the Architecture Journal has been one of the best things MS is doing. I am a regular CONSUMER of the journal. It carries so much of good things that it keeps you on the toe always.

Now coupled with the journal reader, it is going to touch the zenith of perfection. It presents the content of the journal in a very very comprehensive and readable format. MS is always pioneering the art of UX (User eXperience).

I will request all of you to go for it and have a nice learning ahead. You can download this from <http://www.microsoft.com/downloads/thankyou.aspx?familyId=dd466bbb-1b7d-438e-9f9a-954ce2058f15&displayLang=en> and start your daily dose of learning.

Happy learning ahead!!


 

Posted: Mar 31 2008, 16:56 by Admin | Comments (15) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Social Bookmarks: E-mail | Kick it! | DZone it! | del.icio.us