Dilettante attempt @MustacheJS with ASP.NET

Dear Reader,

For some reason i stumbled upon the javascript templating topic and found out about MustacheJS and its simplicity, though i am not an expert at this topic, but i felt the ease of learning this is quite nice.

It took me for a while to understand and proceed in getting started with Mustache. My skills with JS is also needs a lot of sharpening, yet its slow and steady. In attempt to learning this engine, i made a sample application which is easy enough to understand myself in future as well as any others.

With that in mind, i came up with a small application of getting some messages data based on the options/choices chosen by a user i.e Admin vs Guest. Its tiny and simple but i hope its very easy to understand. It might look like re-inventing a wheel, but i wanted to try in my own way.

Default.aspx:

Untitled

As you can see, i have only 2 radio buttons on the default page: Admin and User. The rest is all self-explanatory.

Admin.html:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<div id="AdminTemplate">
    <h2>Welcome aboard {{UserName}}</h2>

    <h3>select type of action:</h3><input id="Manage" name="SettingsType" onclick=
    "OnSettingsTypeRadioButtonClicked(this)" type="radio" value="Manage">Manage <input id="News"
    name="SettingsType" onclick="OnSettingsTypeRadioButtonClicked(this)" type="radio" value=
    "News">News <input id="Tasks" name="SettingsType" onclick=
    "OnSettingsTypeRadioButtonClicked(this)" type="radio" value="Tasks">Tasks List <input id=
    "Messages" name="SettingsType" onclick="OnSettingsTypeRadioButtonClicked(this)" type="radio"
    value="Messages">Messages

    <div id="TemplateHolder"></div>
</div>

As you can see from the above html page, i have added a place holder for a dynamic text from server at line 2; the place holder for mustache to recognize is placed between {{xxxx}} braces. Then there are few radio buttons provided to choose.

User.html:

 1
 2
 3
 4
 5
 6
 7
<div id="UserTemplate">
   <h2>Welcome aboard {{UserName}}</h2>

    <h3>Below listed messages. Have fun</h3>
    <div id="TemplateHolder"></div>

</div>

The template or the data for the user is kept very simple without any option to make it very distinguishable.

The div element with id= “TemplateHolder” is the tag which will hold a message board for both Admin and Guest user based on their choice; if any.

In this example, i wanted to list down the messages in a bulletin format or list wise, hence i chose below message board template:

MessagesBoardTemplate.html:

 1
 2
 3
 4
 5
 6
 7
 8
<div id="MessagesBoardTemplate">
    <h4>{{ChoiceMessage}}</h4>
    <ul>
        {{#ChoiceInfo}}
        <li>{{.}}</li>
        {{/ChoiceInfo}}
    </ul>
</div>

In Mustache, one can print an array items in the form of a list as shown above. The array start is done on-line 4 and the line 5 i.e {{.}} iterates (internally to MustacheJS) over each item of the array and substitutes it.

Now comes the part where we need to fetch the data and then prepare the template info to be displayed.

Template.js:
Snippet 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function OnRadioButtonClick(element) {
    if ($(element).attr("id") == "Admin") {        
        
        getHTML(function (html) {
            processTemplateHTML(html, "Admin");
        }, "/Templates/Admin.html");       
    }
    else if ($(element).attr("id") == "Regular") {
        getHTML(function (html) {
            processTemplateHTML(html, "Guest");
            requestMessageData("Messages");
        }, "/Templates/User.html");
    }
}

As you can see from the above code, this function/event gets executed when the user selects an option on Default.aspx page.

getHTML is a callback variable (delegate in .net terms) at line 4 and 9, used here to invoke/load the template/html data from the server. Since every thing in Javascript is an asynchronous operation, the code flow here is a continuous styled. Making it a synchronous operation kills the usability/operational style of the browser, hence the delegate/callback approach is used here.

Snippet 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var getHTML = function (onResult, url) {
    $.get(url, function (htmlContent) {
        onResult(htmlContent);
    });
}

function processTemplateHTML(templatehtml, userName) {
    var uName = { UserName: userName };
    var htmlContent = Mustache.to_html(templatehtml, uName);
     $("#UserTypeDataHolder").html(htmlContent);
}

From the above code, the getHTML callback variable is declared at line 1 here which holds a reference to a function taking 2 parameters. The first argument is another callback function being passed in the previous snippet 1 at line 4 and 9. Here, i am using Jquery.get() method to get the html content from the server. I am not using .load() method here because, i need the html content in a in memory variable than being appended to an DOM tree element; which may or may not be made hidden. The .load method does not load the content to a variable in memory nor to a dummy div tag created by the jquery, hence the next best is chosen.

OnResult argument is another delegate (remember the continuous code flow layout of javascript due to its asynchronous modus operandi?) being passed which is; processTemplateHTML() at line 7. This method, takes the template (html from server) and then creates an associative array (line 8), this is then passed to the MustacheJS at line 9. The musatcheJS thus parsing the html content will place the values being supplied in the second argument onto the place holders in the first argument at suitable matching places.

In above snippet, at line 10, the template data holder is assigned the final html content for further operation using jquery.

Snippet 3:

 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
function OnSettingsTypeRadioButtonClicked(element) {    
    requestMessageData($(element).attr("id"));
}

function requestMessageData(elementId)
{
    getHTML(function (html) {
        $.ajax({
            type: "POST",
            url: "Default.aspx/GetSettingsActionData",
            data: JSON.stringify({ "choice": elementId }),
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            success: function (data) {
                setTemplateData(data, html);
            },
            error: function (request, status, error) {
                alert(request.responseText + " ===== " + status + "---------" + error);
            }
        });
    }, "/Templates/MessageBoardTemplate.html");
}

function setTemplateData(jsonData, actionTemplateData) {
    var html = Mustache.to_html(actionTemplateData, JSON.parse(jsonData.d));
    $("#TemplateHolder").html(html);
}

On line 1 above, the method/event OnSettingsTypeRadioButtonClicked() is invoked by the multi choice radio button provided by the Admin.html template.

requestMessageData() function invokes a server AJAX request to the ASP.NET code behind (c#) method to fetch the dynamically populated data based on the choices made. Line 10 is a better choice to make things obvious of the data conversion being done, some times the ajax request fails if this is not used i.e explicit JSON string conversion. The line 12, is also a must, if data is passed to the server via “POST” method in AJAX request: this helps the code behind and the browser to decipher the data better.

On success request, setTemplateData() callback is invoked, wherein the json data fetched from the server is applied to the MessageBoardTemplate html. Please note that the json data received must be parsed back to JSON at line 26 else the Mustache fails to parse the string.

C# Code behind:

Default.aspx.cs:

 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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
public class SettingsData
    {
 
        public string ChoiceMessage {get;set;}

         public List<string> ChoiceInfo { get; set; }
    }

    public partial class Default : System.Web.UI.Page
    {
        [System.Web.Services.WebMethod]
        public static string GetSettingsActionData(string choice)
        {
            SettingsData data;
            switch (choice)
            {
                case "Manage":
                    data = GetConfigData();
                    break;
                case "News":
                    data = GetNewsData();
                    break;
                case "Tasks":
                    data = GetTasksData();
                    break;
                case "Messages":
                    data = GetMessagesData();
                    break;
                default: data = null;
                    break;
            }

            string json = new JavaScriptSerializer().Serialize(data);
            return json;
        }

        public static SettingsData GetConfigData()
        {
            SettingsData d = new SettingsData();

            d.ChoiceMessage = "Choices";
            d.ChoiceInfo = new List<string>()
            {
                "User Configuration",
                "WebPages Configuation",
                "DateTime Congfiguration",
                "Performance Tests",
                "Server logs Configuration"
            };

            return d;
        }

        public static SettingsData GetNewsData()
        {
            SettingsData d = new SettingsData();

            d.ChoiceMessage = "Important events:";
            d.ChoiceInfo = new List<string>()
            {
                "10 Users at server x.x.x.10 blocked",
                "2 Users at server x.x.1.20 granted additional rights",
                "Servers at 10.3.3.5 went offline for 4 hours",
                "Users at 2.3.101.222, 9.89.32.22, 2,3.51.55 were logged in for more than 36 hours",
                "System detected users at 10.0.0.1, 0.2.3.4, 21.1.2.3, 33.2.12.4 for suspecious activity"
            };
            return d;
        }

        public static SettingsData GetMessagesData()
        {
            SettingsData d = new SettingsData();

            d.ChoiceMessage = "Messages";
            d.ChoiceInfo = new List<string>()
            {
                "Your password about to expire in 10 days",
                "Your last login was 2 days"                
            };
            return d;
        }

        public static SettingsData GetTasksData()
        {
            SettingsData d = new SettingsData();
            d.ChoiceInfo = new List<string>()
            {
                "Server 2.1.3.200 needs restarts",
                "Server 20.4.65.22 updates pending",
                "Database upgrade done, restart required for server oxc.edm.com"
            };
            return d;
        }
    }

The above code is mostly self-explanatory. Based on the selection choices,i am filling up the DataObject and at line 33, its recommended to use System.Web.Script.Serialization.JavaScriptSerializer API for serializing the managed type objects than the API’s from System.RunTime.Serialization assembly.

I hope i have made things simple and clear. If any mistakes/suggestion, kindly please leave a detailed comment, if possible.

Thanks,
Zen :)

Sample: https://drive.google.com/open?id=0B5DC25Y3gdgrR3BzRk1CQzNobEE&authuser=0

References:

Generic method to avoid long IF clauses

Dear Reader,

Recently at work, i was working with a library which had lot of properties wherein they must be verified for its Truth value before exporting or importing respective attributes to file or back to UI respectively.

Basically, the raw code initially looked roughly like below:

void ExampleMethod() {
SomeType type = new SomeType();

if (type.HasValue1)
  //Export Value1
if (type.HasValue2)
  //Export Value2
if (type.HasValue3)
  //Export Value3
if (type.HasValue4)
  //Export Value4
if (type.HasValue5)
  //Export Value5
if (type.HasValue6)
  //Export Value6
if (type.HasValue7)
  //Export Value7
if (type.HasValue8)
  //Export Value8
if (type.HasValue9)
  //Export Value9
if (type.HasValue10)
  //Export Value10
if (type.HasValue11)
  //Export Value11
if (type.HasValue12)
  //Export Value12

if (type.HasValue25)
  //Export Value25
}

The above case got repetitive at many places for other types in the same library based on level of their appearance in the UI viz. tree level node. The body of the if-clause all over the place remained same i.e 1 – Check for Truth, 2 – if success, Add to some final list for exporting/importing if not already present.

The method complexity in some cases went over 20 which was getting really gruesome to me. Finally, i decided to refactor the code to reduce not just the complexity but also find a unified solution for other basic types if need be.

Struck to me are 2 possible yet simple solutions yet satisfying the required criteria.

Solution 1: To use the Dictionary<Func< T >, SomeType>, but the body of all those if clauses required another 3rd parameter which hindered me to not opt the dictionary since Dictionary can’t have more than Key : Value pair thus making me to add dictionary inside dictionary which is not only complex in readability aspects but also Value dictionary may not be unique as well. So i had to discard this solution.

Solution 2: To make use of Generic Methods with delegates via lambda expression. This proved to be a working solution in this case yet very simple and effective.

void CheckAndDoSomething < T > (Func< T > property, object Value,
object otherValue) where T: struct
{
  Type t = typeof(T);
  if (t is bool && property())
  {
     //Do some thing with Value and OtherValue
  }
}

void ExampleMethod()
{
  SomeType type = new SomeType();
CheckAndDoSomething(() => type.HasValue1,value0, otherValue0);
CheckAndDoSomething(() => type.HasValue2,value1, otherValue1);
CheckAndDoSomething(() => type.HasValue3,value2, otherValue2);

}

Hope it helps,
Thanks,
Zen :)

ASP.NET Treeview Node Expand-Collapse with Node click: Client Side Javascript

Dear Reader,

I had to implement a custom client side node click along with Tree expand and collapse feature working. There was no straight solution to implement ASP.NET Treeview expand and collapse in pure Javascript or JQuery directly.

With googling for almost half of the day, it turned out noting. So i began to look at the html which gets rendered by Treeview and noticed that it uses TreeView’s own client side script called TreeView_ToggleNode(…).

Method 1:

But hooking onclick for the treeview shall override this JS call when user clicks on the expander node, because the browser shall invoke custom JS script which is hooked. To over come this problem, i had to write below JS code with some validation logic to invoke TreeView’s JS script for toggling treenode (Expand/Collapse).

MyTree.js:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
function OnNodeClicked(event) {
	if (event.target.id == "" && event.target.tagName == "IMG") {
		var parentId = event.target.parentElement.id;

		if (parentId.charAt(parentId.length - 1) == 'i')
			alert("node image is clicked");
		else {
			var nodeIndex = parentId.charAt(parentId.length - 1);
			var childNodesArg = parentId + "Nodes";

			//var func = window["TreeView_ToggleNode"];
			TreeView_ToggleNode(TreeView1_Data, nodeIndex, document.getElementById(parentId), ' ', document.getElementById(childNodesArg));
		}
	} else alert(event.target.id + " is clicked with name = " + $(event.target.id).text());


	return false;
}

MyTreeView.aspx:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<body>
    <form id="form1" runat="server">
    <div>
    <asp:TreeView runat="server" ID="TreeView1" SelectedNodeStyle="Blue" EnableClientScript="True"></asp:TreeView>
    
    </div>
    </form>
</body>
</html>

<script src="MyTree.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
        $("#TreeView1").on('click', this, OnNodeClicked);
</script>

As you can see from the above JS code, i am invoking the TreeView’s JS function for enabling toggling feature at line 12. This script is supplied by Microsoft TreeView control along with HTML on page load if EnableClientScript is enabled.

The code is self-explanatory i spose.

EDIT:
Method 2:

There are numerous ways in JS one can solve this problem, one way is above mentioned. However, thanks to my dear colleague who came up with this idea, which actually is simple yet nice solution.

Rather than using Jquery and attaching click event for the whole tree purely on the client side as done above, we could override the default href of treenodes from server side itself.

TreeView.aspx.cs:

TreeNode t = new TreeNode(“Parent1”);
t.NavigateUrl = “javascript:OnTreeNodeClicked(“Parent1”);

TreeView.js:

function OnTreeNodeClicked(treenode){
//Do what ever you want with the string being passed;
}

Pros:

Method 1:

  • This style gives more control at the client side.
  • Server side code can just purely concentrate on getting the data and not control how client should behave with the tree data.

Method 2:

  • The Server gets more control on how client should behave with the actions on tree.
  • Less JS validation code needed.
  • No need to care about toggling functionality. Its automatically taken care off.

Cons:

Method 1:

  • The JS code gets a lil bit more messy to validate as seen above.
  • Explicitly need to invoke toggling API of ASP.NET TreeView JS script to make expand-collapse work.

Method 2:

  • The Client side JS code does not get which treenode is clicked by the user.
  • Client JS file has to sync with the data format sent by the server, any changes done at server about the way data is being sent, then JS script needs to be updated accordingly. Thus a bit of tight binding.

Thanks,
Zen :)

ASP.NET TreeView tree node icon change JavaScript/JQuery

Dear Reader,

This is my start up work on the web technologies after along standing work on windows platform. Its very much exciting to work on JS and JQuery, although still alot looks gloomy and mysterious to me and ofcourse confusing and sometimes head banging ;)

Anyways, lately i took up a small work on ASP.NET TreeView which currently the whole implementation was done at the server side. So any action on the treeview (treenode) a postback was happening which resulted in complete TreeView being built and sent back via XML from server, thus traffic is huge and so is loading times.

At the moment i have managed to do action click on any tree node without any postback as well as icon reset at the client end itself rather than complete postback from the server.

Treeview.aspx

<%@ Page Language=”C#” AutoEventWireup=”true” CodeBehind=”TreeView.aspx.cs” Inherits=”WebApplication1.TreeView” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;

<script src=”//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js” type=”text/javascript”></script>

<html>
<head>
</head>
<body>
<form id=”form1″ runat=”server”>
<asp:TreeView runat=”server” ID=”TreeView1″ EnableViewState=”false” EnableClientScript=”True”
Target=”form1″>
</asp:TreeView>
<div>
</div>
</form>
</body>
</html>

<script src=”TreeView.js” type=”text/javascript”></script>
<script type=”text/javascript” language=”javascript”>
$(“#TreeView1”).on(‘click’, this, OnTreeNodeClick);
</script>

As you can see i just have added a server control asp:TreeView onto the aspx page. And after that using JQuery i have attached click event for every node of the tree with node object is being passed as an argument to the delegate OnTreeNodeClick method.

Treeview.aspx.cs

public partial class TreeView : System.Web.UI.Page
{
static IDictionary<string, string> _IconimageDictionary = new Dictionary<string, string>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (_IconimageDictionary.Count < 1)
{
_IconimageDictionary.Add(“1”, “./Resources/Image1.png”);
_IconimageDictionary.Add(“2”, “./Resources/Image2.png”);
_IconimageDictionary.Add(“3”, “./Resources/Image3.png”);
_IconimageDictionary.Add(“4”, “./Resources/Image4.png”);
}

TreeNode t = new TreeNode();
t = new TreeNode(“Parent2”);
t.ImageUrl = _IconimageDictionary[“1”];
t.ChildNodes.Add(new TreeNode(@”Parent2\Child10″){ ImageUrl = _IconimageDictionary[“1”]});
t.ChildNodes.Add(new TreeNode(@”Parent2\Child20″) { ImageUrl = _IconimageDictionary[“1”] });
t.ChildNodes.Add(new TreeNode(@”Parent2Child30″) { ImageUrl = _IconimageDictionary[“1”] });
TreeView1.Nodes.Add(t);
}
}

I am filling the dummy information from server onto the tree node for the first time only. In real life scenario, this dummy data would be fetched from DB or filesystem.

Once the server construct the HTML data of this tree and sends back to the browser, its whole different ballgame to identify the tree nodes and access them or to even modify the DOM tree. This is because .NET<4, there is no way one can set client ID for any HTML elements, since i am using 3.5 framework, the server takes privileges in setting its own Client ID for the tree node elements.

HTML Source from Browser of TreeView:

<table cellpadding=”0″ cellspacing=”0″ style=”border-width: 0;”>
<tr>
<td>
<a id=”TreeView1n0″ href=”javascript:TreeView_ToggleNode(TreeView1_Data,0,TreeView1n0,’ ‘,TreeView1n0Nodes)”>
<img src=”/WebResource.axd?d=cZ5kMITeSm_Rn7tikwjob9p_LS9v3TCcc3ApPfN2ItF2ekZYXvhU3yEijLo8a3AAWHN2L0l2O32tJJ79rAu9e4UXdJuLimPPMUSMFc54G6IwB09f0&amp;t=635199992887188881″ alt=”Collapse Parent2″ style=”border-width: 0;” />
</a>
</td>
<td>
<a href=”javascript:__doPostBack(‘TreeView1′,’sParent2′)” onclick=”TreeView_SelectNode(TreeView1_Data, this,’TreeView1t0’);” id=”TreeView1t0i” tabindex=”-1″>
<img src=”./Resources/Image1.png” alt=”” style=”border-width: 0;” />
</a>
</td>
<td style=”white-space: nowrap;”>
<a href=”javascript:__doPostBack(‘TreeView1′,’sParent2′)” onclick=”TreeView_SelectNode(TreeView1_Data, this,’TreeView1t0’);” id=”TreeView1t0″ style=”text-decoration: none;”>Parent2</a>
</td>
</tr>
</table>
<div id=”TreeView1n0Nodes” style=”display: block;”>
<table cellpadding=”0″ cellspacing=”0″ style=”border-width: 0;”>
<tr>
<td>
<div style=”width: 20px; height: 1px”>
</div>
</td>
<td>
<img src=”/WebResource.axd?d=D6-CBDozPvT6cSNuEIYsRXO5GdTG2ybgi40r8UfRPOR_FwCtOjk_rm_jbNDblYlDLwgKA-ihR41amS8iiChAic99j1mJhhEaU0jqBXw4JSA3lDt70&amp;t=635199992887188881″ alt=”” />
</td>
<td>
<a href=”javascript:__doPostBack(‘TreeView1′,’sParent2\\Parent2*|*Child10′)” onclick=”TreeView_SelectNode(TreeView1_Data, this,’TreeView1t1’);” id=”TreeView1t1i” tabindex=”-1″>
<img src=”./Resources/Image1.png” alt=”” style=”border-width: 0;” />
</a>
</td>
<td style=”white-space: nowrap;”>
<a href=”javascript:__doPostBack(‘TreeView1′,’sParent2\\Parent2*|*Child10′)” onclick=”TreeView_SelectNode(TreeView1_Data, this,’TreeView1t1’);” id=”TreeView1t1″ style=”text-decoration: none;”>Parent2\Child10</a>
</td>
</tr>
</table>

As you can see, the treeview is translated into bunch of <tr> <td> tags. So now, i need to change the image icon of each tree node to something else apart from what the server has set already.

Here comes the JQuery|JavaScript to the rescue. Since its all new and beginning to me, it took a while for me to understand the whole javascript jquery API and its working style. So based on the basic understanding, i could come up with the below code:

Treeview.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function OnTreeNodeClick(sender) {
    var id =sender.target.id;
    if (id) {
        var doc = document.getElementById(id);
        var innerhtml = document.getElementById(doc.id + 'i').innerHTML;
        innerhtml = innerhtml.replace("Image1.png", "Image2.png");
        document.getElementById(doc.id + 'i').innerHTML = innerhtml;
    }
    return false;
}

As per the above code, i am passing the ‘this’ as an second argument from aspx ‘on’ method call of JQuery. So the sender argument will be the treenode on which the user has clicked on. Once i get the sender, i need to find the server generated client ID for this node. Once i get the id, i get the DOM element via getElementById() API in line 4.

If you refer the server generated HTML document for browser pasted above, you can see that for each tree node there are 3 <td> tags per <tr>. So looking a bit deeper, we noticed that one <td> is for icon and other for the text element of the particular tree node. Thankfully ASP.NET consistently appends “i”  to the end of the clientID for identifying it as icon element in the treenode.

So in the line 5, i get the innerHTML  of that icon tag for that particular treenode by appending “i” to the id of the sender tree node. In line 6, i replace the png name to the required name. Then in line 7, i assign it back to the innerhtml for the DOM tree to refresh itself. Line 9 is important to avoid any postback happening.

Theres still more to learn and more validation, requirements to be added and the source code needs alot of beatification to improve it.

Please feel free to submit any suggestions.

Thanks,
Zen :)

Decision matrix implementation in C#

Dear Reader,

Yesterday i faced a problem where the combinations possibilities were many and i had to implement code for this problem. Obvious solution is to implement If – else ladder. But i absolute hate this solution because the combination were around 5C3. The combination data was about behavior aspect of a scenario. Next solution is to use Switch block. But this solution involves inner switch combinations. So down the line it gets more complicated.

Next solution was to go for dictionary. But the problem with dictionary is the key uniqueness. In my case, most of the keys were not unique. So either i had to customize the dictionary behavior (List of KeyValuePair) or go for some thing else. The earlier will lead to writing alot of code for small problem and involves more cost factor in terms of development time and testing effort.  Idea rejected.

Then i suddenly remembered to make use of Decision table. So googling a bit to learn more about decision matrix, this is what i could implement which is not just extensible but also easy to understand and easy to add/modify later on. No need to change in the actual code (finding the combo) unless the way to look up methodology changes.

Sample code:

Untitled

At line 27, i am here searching for a combination key of “Condition3” AND “ASC”, then get the result from the matrix. Line 31, have used FirstOrDefault() than First() to avoid exception when result is not found.

Hope it helps,
Thanks,.
Zen :)

Progress Modal Dialog Launch from another Thread

Dear,

Today i encountered a problem to fit one of the use case, so i went ahead to develop a prototype. Because of rest of the layering architecture i had to take a bad design decision. I had to launch a progress dialog as modal dialog on top of the main window but do not block the main window thread from further data processing. So i had to launch this progress dialog in a different child thread and make the main window as its parent. The main thread shall do alot of processing and notifies the progress dialog about the updates. Basically the below layers in the main thread calculates some data and informs it to the UI  for displaying. To accommodate this i tried couple of ways and reached dead-end. Referring to couple of stackover flow threads also did not give me complete answer, but they indeed gave me some insights. Thanks to those guys.

So i came up with a prototype with a simple winform main app having a button which again creates a progress dialog as modal in a separate thread then update progress bar values from the main thread. Below is rough diagram of how it should be:

progress Dlg

So after exhaustive effort for a day, i came up with below code which seem to work out well as per the stated requirement above. Below is the code:

public class MainForm1 : Form
    {      
        int counter = 0;
        Thread progressDialogUIThread;
        bool stopProcessing = false;
        ManualResetEvent resetEvent = new ManualResetEvent(false);
       
        ProgressDialogForm2 progressDlg;

        private void button1_Click(object sender, EventArgs e)
        {           
            progressDialogUIThread = new Thread(new ThreadStart(InitializeDialog));
            this.Enabled = false;
            progressDialogUIThread.Start();
           //Wait till child thread creates and initialize the dialog instance
            resetEvent.WaitOne();
            UpdateProgressData();
        }

        private void InitializeDialog()
        {
            progressDlg = new ProgressDialogForm2();           

            progressDlg.cancelButtonEvent = new EventHandler((s, e1) =>
            {
                switch (progressDlg.DialogResult)
                {
                     case DialogResult.Cancel: 
                        stopProcessing = true;
                        progressDlg.Close();
                        break;
                }
            });

            resetEvent.Set();
            //Cant pass owner here, since child thread so throws cross thread excep.
            progressDlg.ShowDialog();
        }

        private void UpdateProgressData()
        {
            for (int i = 0; i < 100; i++)//Range of Progress bar is 0-100
            {
               //Closing dialog window on cancel button click, hence flag check. 
                if (!stopProcessing)
                  //If not checked, then window is closed and below invoke throws exception.
                {
                    progressDlg.Invoke(new Action<int>(progressDlg.SetProgressValue),
                           new object[] { i });
                    //Just to put some delay in updating progress bar for visiblity purpose
                    Thread.Sleep(500);
                }
                else this.Enabled = true;
            }
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
           if (progressDlg != null)
            {
                if (!stopProcessing)//When dialog is closed, nothing to update.
                    this.Invoke(new Action(progressDlg.BringToFront));
            }
        }
}

public partial class ProgressDialogForm2: Form
    {
        public EventHandler cancelButtonEvent;

         public void SetProgressValue(int value)
        {
            this.progressBar1.PerformStep();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            if(cancelButtonEvent != null)
                cancelButtonEvent(sender,e);
        }
    }

Hope it was helpful.

Happy Coding :)
Zen :)

Windows cannot find devenv error – Win 7

Dear Reader,

Today on my Win 7 (VM install guest on Zenwalk Linux) VS 2012 RC expired. Hence i had to uninstall it. Unfortunately after it uninstalled, it did not clean up all the paths and links and corrected the changed paths of some too, in this case devenv command path (Beta build yea!). Though i restarted the VM twice, still the problem persisted. Hence i could not launch VS 2010 from Start -> Run or even from command prompt.

After googling for a while, i did end up with nothing apparently. So searching to fix this issue had to fiddle with the stupid windows registry.

So if you also face the same issue, here is the path for it:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\devenv.exe\

Short and Hope it helps.

Happy Coding,
Zen :)