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.
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
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
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....
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]
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!!