Category Archives: Programming

Regular expression for a line with only white spaces

I had this requirement to check whether the input string contains only white spaces. I am not a regular RegEx user, so it took me some time to achieve this.

^[ \t\r\n]*$

That’s it. The meaning of the above pattern is [Beginning of line] [0 or multiple white spaces] [End of line]. Note that this pattern matches an empty string also, since we have given * after white spaces. If you want to strictly look for white spaces and exclude empty strings, then change the * to +.

This is not such a big deal that it requires a blog post of its own, but I didn’t find this information when I looked for it. So putting this out there for anyone who comes looking for it.

Advertisements

Right click on TreeView: Get the node clicked at

Problem:

There is a TreeView control with n number of nodes. When the user right clicks on the TreeView control, get the node on which the right click was performed.

Background:

In TreeView control, SelectedNode property is set whenever left click occurs. This is not true for right clicks. So, we need to have some workaround for this.

Solution 1:

The most popular solution is to handle the MouseDown event. Check if the click was a right click and then use the TreeView control’s GetNodeAt API to get the node which was clicked at.

private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
TreeNode selectedNode = treeView1.GetNodeAt(e.X, e.Y);
MessageBox.Show("You clicked on node: " + selectedNode.Text);
}
}


Solution 2:

Handle the NodeMouseClick event. The TreeNodeMouseClickEventArgs has the node which was clicked at.

private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
MessageBox.Show("You clicked on node: " + e.Node.Text, "Solution 2");
}
}

SelectedNode property of a treeview is set whenever a left click occurs. Why can’t the same be applied for right click? Right click on a treeview is such a common UI event, that users will benefit from it.

Removing items in a list while iterating through it

See the following code:

List list = new List();

for (int i = 1; i < 10; i++) { list.Add(i); } foreach (int i in list) { list.Remove(i); } [/source] Do you see anything wrong in this piece of code? No? Okay. Execute this code and you will get a System.InvalidOperationException with the message “Collection was modified; enumeration operation may not execute.”

The first time foreach loop executes, it deletes the first item and in the second iteration, this nasty exception is thrown. Reason? You deleted the first item and the list has changed. If not for the InvalidOperationException , you could have got a IndexOutOfRange exception while traversing the list.

So, how does one delete some items in the list while iterating through the list? I faced this problem in my project today and I couldn’t come up with an elegant solution. I did come up with a hack. I identify all items that need to be deleted and mark them with a flag (I need one iteration here). In another iteration, I create a new list and copy all those items which are not marked.

Sorry, I couldn’t come up with something better. If you have a solution or a better fix, please do let me know. Please note that if I want to remove all items, I can use list.Clear(). I am talking about a scenario where I want to delete only a select few items.

Update:

I read somewhere that if you use for loop instead of foreach, this problem does not arise. True, you will not get an exception, but you might not delete the items that you actually want to delete. Let’s see what happens in our case.

List list = new List();

for (int i = 1; i < 10; i++) { list.Add(i); } for (int i = 0; i < list.Count; i++) { int remove = list[i]; list.Remove(remove); } [/source] You will delete items 1, 3, 5, 7 and 9. After the for loop exits, your list will still have 2, 4, 6 and 8. Surprised? Let's see why this is so. First iteration: i = 0, remove = 1. Deleted item = 1 Once you delete this item, the list has changed. So, the first element in the list is now 2.
Second iteration: i = 1, remove = 3. Deleted item = 3
Third iteration: i = 2, remove = 5. Deleted item = 5

and so on….

So, replacing foreach with a for is not a solution.

C#: List of struct

Talking about discoveries, I discovered something about C# today.

Let’s say I have a struct ‘MyStruct’ with an integer as its data member. and I create a list of this type.

List list = new List();

I add a few elements to this list.

list.Add(new MyStruct(10));
list.Add(new MyStruct(20));

If I try to modify any element in this list, that is when things become interesting.

list[0].m_age = 30;

The compiler starts its blaring sirens. Error: Cannot modify the return value of System.Collections.Generic.List<MyStruct>.this[int]’ because it is not a variable

This problem does not arise if you have a list of class instead of a structure. i.e, if I change MyStruct to a class (and call it MyClass to avoid confusion), this error message goes away. Why should it matter for structs and not for classes? I knew the basic difference between these two, one being a value type and the other being a reference type. This knowledge wasn’t enough to crack this puzzle.

A quick googling gave me the answer. The operator [] is actually a function call. When you index a list and get the individual element, you are actually making a function call. You get the individual element as the return value of the function. This return value is placed on the stack and when you try to use the dot operator on this, you are actually trying to modify the return value of the function. i.e. you are modifying a copy of the element and your modifications will not affect the element in the list. The compiler, smart it is, catches this and informs you of the pitfall.

This does not affect a list of class items because class is a reference type. When you use [] operator on a list of class, the [] function is actually returning a reference to the original object and hence your modification on this reference object will cause the original element to change.

Phew! One discovery that was. Next time you are creating a list of structs, remember this little piece of information.

Update:

Beware! If you save the return value of the function in a variable, modify that variable and expect the actual list element to change, that’s not going to happen.

MyStruct s = list[0];
s.m_age = 40; // This will not change the element list[0]

Modifying the variable s is not going to modify list[0].

This poses an interesting question. Once you create a list of structs and initialize it, there is no way you can modify it? I need to find this out. Look out for more updates on this.

.NET Remoting, Marshalling, yada yada

A search for basics on .NET remoting threw up these really useful articles. Bookmark them, you never know when you might need it.

Introduction to .NET Remoting

Copying, Cloning, and Marshalling in .NET

Coding and writing short stories

Having tried my hand at the creative side of life (read “writing stories”), I have often heard from the veterans that one needs to read a lot to be a good writer. I couldn’t agree more. You see how writers play with words and you are tempted to do it yourself. You read a good piece and say “I wish I had written that” or “I wish I could write like that”.

I felt the same when I saw a piece of code today. It’s written by one of our senior most programmers who I am in awe of. It’s around 15 lines of Perl code. It’s neat, compact, efficient and awesome! It took me 20 minutes to figure out all the constructs that piece of code used. I admit I am not all that familiar with Perl.

This led me to this thought: Do you need to read others’ code to become a good coder? Certainly. If I hadn’t looked at the Perl code, I would have never imagined one could write code like that! Sadly, I don’t even remember when I read somebody’s code because I wanted to read it. Code review, code digging, debugging – I have done all this. But, reading code for the heck of reading it: No.

Lesson learnt: Read more code from this senior programmer.