The Treeview Sort method applies a simple character sort to the node text. For sophisticated business applications this is often too simple and a custom sort is required in order to sort the nodes based upon the content and not just the character representation.
For example, consider this simple scenario with the following nodes:
Sorting these nodes using a character sort will place them in alphabetical order; First, Fourth, Second, Third.
A custom sort is easy to implement and link to a Treeview control. In this example the Tag property of the Node control is used to store data for sorting the nodes. The NodeSort class is assigned to the TreeViewNodeSorter property before sorting the nodes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | Public Class Form1 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load Dim nodParent As TreeNode Dim nodChild As TreeNode ' Add four nodes and assign the sequence number to the Tag property For intNode As Integer = 1 To 4 nodParent = TreeView1.Nodes.Add(Choose(intNode, "First Node", "Second Node", "Third Node", "Fourth Node")) nodParent.Tag = intNode Next ' Add a series of dates to the 4th node For intAdjust As Integer = 1 To 49 Step 7 Dim dteNode As Date = DateAdd(DateInterval.Day, intAdjust, Date.Now) nodChild = nodParent.Nodes.Add(String.Format("{0:dd MMM yy}", dteNode)) nodChild.Tag = dteNode Next ' Assign the custom sort class and sort the TreeView With TreeView1 .TreeViewNodeSorter = New NodeSorter .Sort() End With End Sub End Class Public Class NodeSorter Implements IComparer Public Function Compare(ByVal x As Object, ByVal y As Object) _ As Integer Implements IComparer.Compare Dim tx As TreeNode = CType(x, TreeNode) Dim ty As TreeNode = CType(y, TreeNode) If TypeOf tx.Tag Is Integer And TypeOf ty.Tag Is Integer Then ' Sort numbers in ascending sequence Return String.Compare(tx.Tag.ToString, ty.Tag.ToString) ElseIf TypeOf tx.Tag Is Date And TypeOf ty.Tag Is Date Then ' Sort dates in descending sequence Return String.Compare(String.Format("{0:yyyymmdd}", CDate(ty.Tag)), String.Format("{0:yyyymmdd}", CDate(tx.Tag))) Else ' Sort everything else alphabetically in ascending sequence Return String.Compare(tx.Text, ty.Text) End If End Function End Class |
Note that the dates are sorted in descending sequence simply by swapping the X and Y nodes and comparing Y with X instead of X with Y.
The Microsoft AJAX Toolkit seems have been overtaken by jQuery these days, so I thought that it was about time I investigated what it could do and how it worked. For one of the projects that I’ve got on the go the AutoComplete widget that is part of the jQuery UI looked useful, especially as it can be linked to a remote datasource. The data for this project is stored in a SQL Server database, so I needed to prove that the AutoCompete widget would work with this.
After digging around it looked to me as though I would need to implement a generic handler that jQuery could call from the client and return some JSON data. The DataContractJsonSerializer class appeared to provide the mechanism for returning the data.
Step 1 was to create the generic handler. In my VS2010 project I added a folder called Soap and within that I created a new generic handler that I called SoapTest.ashx. The code that I wrote to begin with always returns 6 items, with the text entered by the user followed by a counter. All I wanted to achieve at this point was to make sure that I could return some data to the client.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | Imports System.Web Imports System.Web.Services Imports System.Runtime.Serialization Public Class SoapTest Implements System.Web.IHttpHandler Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest context.Response.ContentType = "application/json" Dim Term As String = String.Empty If Not context.Request.QueryString("term") = String.Empty Then Model = context.Request.QueryString("term") Dim DataList As List(Of AutoCompleteData) = New List(Of AutoCompleteData) For ItemCount As Integer = 1 To 6 Dim DataItem As New AutoCompleteData DataItem.label = String.Format("{0} - {1}", Term, ItemCount) DataItem.value = String.Format("{0} - {1}", Term, ItemCount) DataList.Add(DataItem) Next Dim Serialiser As Json.DataContractJsonSerializer = New Json.DataContractJsonSerializer(DataList.GetType()) Serialiser.WriteObject(context.Response.OutputStream, DataList) End Sub ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class ''' <summary> ''' AutoCompleteData class for serialising Json data ''' </summary> ''' <remarks> ''' The properties must be lowercase otherwise the jQuery code does not handle them correctly. ''' </remarks> <DataContract()> Public Class AutoCompleteData <DataMember()> Public Property label As String <DataMember()> Public Property value As String End Class |
Testing this code is simple. Run the project and change the URL to http://localhost:51727/Soap/SoapTest.ashx. Note that the port number when you run the project might not be 51727. If everything is working the function will return some JSON data that looks like this:
[{“label”:” – 1″,”value”:” – 1″},{“label”:” – 2″,”value”:” – 2″},{“label”:” – 3″,”value”:” – 3″},{“label”:” – 4″,”value”:” – 4″},{“label”:” – 5″,”value”:” – 5″},{“label”:” – 6″,”value”:” – 6″}]
Of course, the code is expecting to receive the data that the user has typed into the AutoComplete field, passed in via the QueryString ‘term’ item. Changing the URL to http://localhost:51727/Soap/SoapTest.ashx?term=abc will result in JSON data like so:
[{“label”:”abc – 1″,”value”:”abc – 1″},{“label”:”abc – 2″,”value”:”abc – 2″},{“label”:”abc – 3″,”value”:”abc – 3″},{“label”:”abc – 4″,”value”:”abc – 4″},{“label”:”abc – 5″,”value”:”abc – 5″},{“label”:”abc – 6″,”value”:”abc – 6″}]
Having established that the handler is working I then needed to hook this up to a control on the client with jQuery. A input field is required for this, and with ASP.Net 4.0 it is now very easy to link ASP controls into the Java script by making use of the new ClientIDMode property. Setting ClientIDMode=”Static” generates an HTML input field with the same ID as the ASP control which can therefore be used to hook the control into jQuery.
The server side control therefore looks like this:
Enter Text: <asp:TextBox ID=”TBAutoComplete” runat=”server” ClientIDMode=”Static”></asp:TextBox>
And the associated jQuery call like this:
1 2 3 4 5 6 7 8 9 10 | <script type="text/javascript"> $(function () { $("#TBAutoComplete").autocomplete({ source: "/Soap/SoapTest.ashx", minLength: 2, dataType: "json" }); }); </script> |
This all seemed to work quite nicely. Next I need to extend this to link the AutoComplete field to a drop-down list and pass an additional parameter to the Soap handler. Finally I’ll need to hook up the Soap handler to my database but that should be the easy bit.
Recent Comments