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 :)